-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[RISCV] Mark symbols used in inline asm for relocations as referenced #104925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Anton Sidorenko (asi-sc) ChangesCommit 5cd8d53 taught RISCVMergeBaseOffset to handle inline asm, however In the example below compiler generates pcrel relocation (mcmodel=medany)
And fails with the folliwng error
After transformations MachineFunction contains inline asm instructions with
So, when AsmParser processes 'fld', it has to create a new symbol as
This change adds symbols used in memory operands to the list of referenced ones. Godbolt link: https://godbolt.org/z/aqrrsWKoK -- on the left you can find incorrect labels for the integrated-as and on the right an error when compiling to the binary object. Note that I change tests in the first commit and the second commit shows the real difference after the fix. Patch is 90.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/104925.diff 3 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 93677433c04405..476dde2be39e57 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -396,6 +396,15 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
OS << MCO.getImm();
else if (Offset.isGlobal() || Offset.isBlockAddress() || Offset.isMCSymbol())
OS << *MCO.getExpr();
+
+ if (Offset.isMCSymbol())
+ MMI->getContext().registerInlineAsmLabel(Offset.getMCSymbol());
+ if (Offset.isBlockAddress()) {
+ const BlockAddress *BA = Offset.getBlockAddress();
+ MCSymbol *Sym = GetBlockAddressSymbol(BA);
+ MMI->getContext().registerInlineAsmLabel(Sym);
+ }
+
OS << "(" << RISCVInstPrinter::getRegisterName(AddrReg.getReg()) << ")";
return false;
}
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint-2.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint-2.ll
new file mode 100644
index 00000000000000..f0bad08bd44388
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint-2.ll
@@ -0,0 +1,95 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; integrated-as fails with error: unexpected token
+; sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
+; ^
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -no-integrated-as < %s \
+; RUN: | FileCheck -check-prefixes=RV32I %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs -no-integrated-as < %s \
+; RUN: | FileCheck -check-prefixes=RV64I %s
+; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
+; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM %s
+; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
+; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM %s
+
+@eg = external global [4000 x i32], align 4
+@ewg = extern_weak global [4000 x i32], align 4
+
+define void @constraint_o_with_multi_operands() nounwind {
+; RV32I-LABEL: constraint_o_with_multi_operands:
+; RV32I: # %bb.0:
+; RV32I-NEXT: lui a0, %hi(eg)
+; RV32I-NEXT: #APP
+; RV32I-NEXT: sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: constraint_o_with_multi_operands:
+; RV64I: # %bb.0:
+; RV64I-NEXT: lui a0, %hi(eg)
+; RV64I-NEXT: #APP
+; RV64I-NEXT: sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+;
+; RV32I-MEDIUM-LABEL: constraint_o_with_multi_operands:
+; RV32I-MEDIUM: # %bb.0:
+; RV32I-MEDIUM-NEXT: .Lpcrel_hi0:
+; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg)
+; RV32I-MEDIUM-NEXT: #APP
+; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi0)(a0) \n sw zero, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV32I-MEDIUM-NEXT: #NO_APP
+; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: constraint_o_with_multi_operands:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi0:
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg)
+; RV64I-MEDIUM-NEXT: #APP
+; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi0)(a0) \n sw zero, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64I-MEDIUM-NEXT: #NO_APP
+; RV64I-MEDIUM-NEXT: ret
+ call void asm "sw zero, $0 \n sw zero, $1", "=*o,=*o"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
+ ret void
+}
+
+define void @constraint_A_with_multi_operands() nounwind {
+; RV32I-LABEL: constraint_A_with_multi_operands:
+; RV32I: # %bb.0:
+; RV32I-NEXT: lui a0, %hi(eg)
+; RV32I-NEXT: addi a0, a0, %lo(eg)
+; RV32I-NEXT: #APP
+; RV32I-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: constraint_A_with_multi_operands:
+; RV64I: # %bb.0:
+; RV64I-NEXT: lui a0, %hi(eg)
+; RV64I-NEXT: addi a0, a0, %lo(eg)
+; RV64I-NEXT: #APP
+; RV64I-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+;
+; RV32I-MEDIUM-LABEL: constraint_A_with_multi_operands:
+; RV32I-MEDIUM: # %bb.0:
+; RV32I-MEDIUM-NEXT: .Lpcrel_hi1:
+; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg)
+; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1)
+; RV32I-MEDIUM-NEXT: #APP
+; RV32I-MEDIUM-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
+; RV32I-MEDIUM-NEXT: #NO_APP
+; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: constraint_A_with_multi_operands:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi1:
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg)
+; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1)
+; RV64I-MEDIUM-NEXT: #APP
+; RV64I-MEDIUM-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
+; RV64I-MEDIUM-NEXT: #NO_APP
+; RV64I-MEDIUM-NEXT: ret
+ call void asm "sw zero, $0 \n sw zero, $1", "=*A,=*A"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
+ ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
index 6666d92feaac2e..82798a22014ec6 100644
--- a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
+++ b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
@@ -1,12 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs -no-integrated-as < %s \
-; RUN: | FileCheck -check-prefixes=RV32I %s
+; RUN: | FileCheck -check-prefixes=RV32I,RV32I-NO-INTEGRATED %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs -no-integrated-as < %s \
-; RUN: | FileCheck -check-prefixes=RV64I %s
+; RUN: | FileCheck -check-prefixes=RV64I,RV64I-NO-INTEGRATED %s
; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
-; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM %s
+; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM,RV32I-MEDIUM-NO-INTEGRATED %s
; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
-; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM %s
+; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM,RV64I-MEDIUM-NO-INTEGRATED %s
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32I,RV32I-INTEGRATED %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV64I,RV64I-INTEGRATED %s
+; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM,RV32I-MEDIUM-INTEGRATED %s
+; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM,RV64I-MEDIUM-INTEGRATED %s
@eg = external global [4000 x i32], align 4
@ewg = extern_weak global [4000 x i32], align 4
@@ -495,39 +503,77 @@ label:
}
define void @constraint_m_with_multi_operands() nounwind {
-; RV32I-LABEL: constraint_m_with_multi_operands:
-; RV32I: # %bb.0:
-; RV32I-NEXT: lui a0, %hi(eg)
-; RV32I-NEXT: #APP
-; RV32I-NEXT: sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
-; RV32I-NEXT: #NO_APP
-; RV32I-NEXT: ret
-;
-; RV64I-LABEL: constraint_m_with_multi_operands:
-; RV64I: # %bb.0:
-; RV64I-NEXT: lui a0, %hi(eg)
-; RV64I-NEXT: #APP
-; RV64I-NEXT: sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
-; RV64I-NEXT: #NO_APP
-; RV64I-NEXT: ret
-;
-; RV32I-MEDIUM-LABEL: constraint_m_with_multi_operands:
-; RV32I-MEDIUM: # %bb.0:
-; RV32I-MEDIUM-NEXT: .Lpcrel_hi9:
-; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg)
-; RV32I-MEDIUM-NEXT: #APP
-; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
-; RV32I-MEDIUM-NEXT: #NO_APP
-; RV32I-MEDIUM-NEXT: ret
-;
-; RV64I-MEDIUM-LABEL: constraint_m_with_multi_operands:
-; RV64I-MEDIUM: # %bb.0:
-; RV64I-MEDIUM-NEXT: .Lpcrel_hi9:
-; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg)
-; RV64I-MEDIUM-NEXT: #APP
-; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
-; RV64I-MEDIUM-NEXT: #NO_APP
-; RV64I-MEDIUM-NEXT: ret
+; RV32I-NO-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV32I-NO-INTEGRATED: # %bb.0:
+; RV32I-NO-INTEGRATED-NEXT: lui a0, %hi(eg)
+; RV32I-NO-INTEGRATED-NEXT: #APP
+; RV32I-NO-INTEGRATED-NEXT: sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
+; RV32I-NO-INTEGRATED-NEXT: #NO_APP
+; RV32I-NO-INTEGRATED-NEXT: ret
+;
+; RV64I-NO-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV64I-NO-INTEGRATED: # %bb.0:
+; RV64I-NO-INTEGRATED-NEXT: lui a0, %hi(eg)
+; RV64I-NO-INTEGRATED-NEXT: #APP
+; RV64I-NO-INTEGRATED-NEXT: sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
+; RV64I-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-NO-INTEGRATED-NEXT: ret
+;
+; RV32I-MEDIUM-NO-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV32I-MEDIUM-NO-INTEGRATED: # %bb.0:
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: .Lpcrel_hi9:
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: auipc a0, %pcrel_hi(eg)
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: #APP
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: #NO_APP
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: ret
+;
+; RV64I-MEDIUM-NO-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV64I-MEDIUM-NO-INTEGRATED: # %bb.0:
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: .Lpcrel_hi9:
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: auipc a0, %pcrel_hi(eg)
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: #APP
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
+;
+; RV32I-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV32I-INTEGRATED: # %bb.0:
+; RV32I-INTEGRATED-NEXT: lui a0, %hi(eg)
+; RV32I-INTEGRATED-NEXT: #APP
+; RV32I-INTEGRATED-NEXT: sw zero, %lo(eg)(a0)
+; RV32I-INTEGRATED-NEXT: sw zero, %lo(eg)(a0)
+; RV32I-INTEGRATED-NEXT: #NO_APP
+; RV32I-INTEGRATED-NEXT: ret
+;
+; RV64I-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV64I-INTEGRATED: # %bb.0:
+; RV64I-INTEGRATED-NEXT: lui a0, %hi(eg)
+; RV64I-INTEGRATED-NEXT: #APP
+; RV64I-INTEGRATED-NEXT: sw zero, %lo(eg)(a0)
+; RV64I-INTEGRATED-NEXT: sw zero, %lo(eg)(a0)
+; RV64I-INTEGRATED-NEXT: #NO_APP
+; RV64I-INTEGRATED-NEXT: ret
+;
+; RV32I-MEDIUM-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV32I-MEDIUM-INTEGRATED: # %bb.0:
+; RV32I-MEDIUM-INTEGRATED-NEXT: .Lpcrel_hi9:
+; RV32I-MEDIUM-INTEGRATED-NEXT: auipc a0, %pcrel_hi(eg)
+; RV32I-MEDIUM-INTEGRATED-NEXT: #APP
+; RV32I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV32I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV32I-MEDIUM-INTEGRATED-NEXT: #NO_APP
+; RV32I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-MEDIUM-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV64I-MEDIUM-INTEGRATED: # %bb.0:
+; RV64I-MEDIUM-INTEGRATED-NEXT: .Lpcrel_hi9:
+; RV64I-MEDIUM-INTEGRATED-NEXT: auipc a0, %pcrel_hi(eg)
+; RV64I-MEDIUM-INTEGRATED-NEXT: #APP
+; RV64I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-MEDIUM-INTEGRATED-NEXT: #NO_APP
+; RV64I-MEDIUM-INTEGRATED-NEXT: ret
call void asm "sw zero, $0; sw zero, $1", "=*m,=*m"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
ret void
}
@@ -584,67 +630,137 @@ define void @constraint_m_with_multi_asm() nounwind {
}
define i32 @constraint_m_with_callbr_multi_operands(i32 %a) {
-; RV32I-LABEL: constraint_m_with_callbr_multi_operands:
-; RV32I: # %bb.0: # %entry
-; RV32I-NEXT: lui a1, %hi(eg)
-; RV32I-NEXT: #APP
-; RV32I-NEXT: sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB14_2
-; RV32I-NEXT: #NO_APP
-; RV32I-NEXT: # %bb.1: # %normal
-; RV32I-NEXT: li a0, 0
-; RV32I-NEXT: ret
-; RV32I-NEXT: .LBB14_2: # Block address taken
-; RV32I-NEXT: # %fail
-; RV32I-NEXT: # Label of block must be emitted
-; RV32I-NEXT: li a0, 1
-; RV32I-NEXT: ret
-;
-; RV64I-LABEL: constraint_m_with_callbr_multi_operands:
-; RV64I: # %bb.0: # %entry
-; RV64I-NEXT: lui a1, %hi(eg)
-; RV64I-NEXT: #APP
-; RV64I-NEXT: sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB14_2
-; RV64I-NEXT: #NO_APP
-; RV64I-NEXT: # %bb.1: # %normal
-; RV64I-NEXT: li a0, 0
-; RV64I-NEXT: ret
-; RV64I-NEXT: .LBB14_2: # Block address taken
-; RV64I-NEXT: # %fail
-; RV64I-NEXT: # Label of block must be emitted
-; RV64I-NEXT: li a0, 1
-; RV64I-NEXT: ret
-;
-; RV32I-MEDIUM-LABEL: constraint_m_with_callbr_multi_operands:
-; RV32I-MEDIUM: # %bb.0: # %entry
-; RV32I-MEDIUM-NEXT: .Lpcrel_hi11:
-; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg)
-; RV32I-MEDIUM-NEXT: #APP
-; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); beqz a0, .LBB14_2
-; RV32I-MEDIUM-NEXT: #NO_APP
-; RV32I-MEDIUM-NEXT: # %bb.1: # %normal
-; RV32I-MEDIUM-NEXT: li a0, 0
-; RV32I-MEDIUM-NEXT: ret
-; RV32I-MEDIUM-NEXT: .LBB14_2: # Block address taken
-; RV32I-MEDIUM-NEXT: # %fail
-; RV32I-MEDIUM-NEXT: # Label of block must be emitted
-; RV32I-MEDIUM-NEXT: li a0, 1
-; RV32I-MEDIUM-NEXT: ret
-;
-; RV64I-MEDIUM-LABEL: constraint_m_with_callbr_multi_operands:
-; RV64I-MEDIUM: # %bb.0: # %entry
-; RV64I-MEDIUM-NEXT: .Lpcrel_hi11:
-; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg)
-; RV64I-MEDIUM-NEXT: #APP
-; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); beqz a0, .LBB14_2
-; RV64I-MEDIUM-NEXT: #NO_APP
-; RV64I-MEDIUM-NEXT: # %bb.1: # %normal
-; RV64I-MEDIUM-NEXT: li a0, 0
-; RV64I-MEDIUM-NEXT: ret
-; RV64I-MEDIUM-NEXT: .LBB14_2: # Block address taken
-; RV64I-MEDIUM-NEXT: # %fail
-; RV64I-MEDIUM-NEXT: # Label of block must be emitted
-; RV64I-MEDIUM-NEXT: li a0, 1
-; RV64I-MEDIUM-NEXT: ret
+; RV32I-NO-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV32I-NO-INTEGRATED: # %bb.0: # %entry
+; RV32I-NO-INTEGRATED-NEXT: lui a1, %hi(eg)
+; RV32I-NO-INTEGRATED-NEXT: #APP
+; RV32I-NO-INTEGRATED-NEXT: sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB14_2
+; RV32I-NO-INTEGRATED-NEXT: #NO_APP
+; RV32I-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV32I-NO-INTEGRATED-NEXT: li a0, 0
+; RV32I-NO-INTEGRATED-NEXT: ret
+; RV32I-NO-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV32I-NO-INTEGRATED-NEXT: # %fail
+; RV32I-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV32I-NO-INTEGRATED-NEXT: li a0, 1
+; RV32I-NO-INTEGRATED-NEXT: ret
+;
+; RV64I-NO-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-NO-INTEGRATED-NEXT: lui a1, %hi(eg)
+; RV64I-NO-INTEGRATED-NEXT: #APP
+; RV64I-NO-INTEGRATED-NEXT: sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB14_2
+; RV64I-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-NO-INTEGRATED-NEXT: ret
+; RV64I-NO-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV64I-NO-INTEGRATED-NEXT: # %fail
+; RV64I-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-NO-INTEGRATED-NEXT: ret
+;
+; RV32I-MEDIUM-NO-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV32I-MEDIUM-NO-INTEGRATED: # %bb.0: # %entry
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: .Lpcrel_hi11:
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(eg)
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: #APP
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); beqz a0, .LBB14_2
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: #NO_APP
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 0
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: ret
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: # %fail
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
+; RV32I-MEDIUM-NO-INTEGRATED-NEXT: ret
+;
+; RV64I-MEDIUM-NO-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-MEDIUM-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: .Lpcrel_hi11:
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(eg)
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: #APP
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); beqz a0, .LBB14_2
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: # %fail
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
+;
+; RV32I-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV32I-INTEGRATED: # %bb.0: # %entry
+; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
+; RV32I-INTEGRATED-NEXT: #APP
+; RV32I-INTEGRATED-NEXT: sw zero, %lo(eg)(a1)
+; RV32I-INTEGRATED-NEXT: sw zero, %lo(eg)(a1)
+; RV32I-INTEGRATED-NEXT: beqz a0, .LBB14_2
+; RV32I-INTEGRATED-NEXT: #NO_APP
+; RV32I-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV32I-INTEGRATED-NEXT: li a0, 0
+; RV32I-INTEGRATED-NEXT: ret
+; RV32I-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV32I-INTEGRATED-NEXT: # %fail
+; RV32I-INTEGRATED-NEXT: # Label of block must be emitted
+; RV32I-INTEGRATED-NEXT: li a0, 1
+; RV32I-INTEGRATED-NEXT: ret
+;
+; RV64I-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-INTEGRATED: # %bb.0: # %entry
+; RV64I-INTEGRATED-NEXT: lui a1, %hi(eg)
+; RV64I-INTEGRATED-NEXT: #APP
+; RV64I-INTEGRATED-NEXT: sw zero, %lo(eg)(a1)
+; RV64I-INTEGRATED-NEXT: sw zero, %lo(eg)(a1)
+; RV64I-INTEGRATED-NEXT: beqz a0, .LBB14_2
+; RV64I-INTEGRATED-NEXT: #NO_APP
+; RV64I-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-INTEGRATED-NEXT: li a0, 0
+; RV64I-INTEGRATED-NEXT: ret
+; RV64I-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV64I-INTEGRATED-NEXT: # %fail
+; RV64I-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-INTEGRATED-NEXT: li a0, 1
+; RV64I-INTEGRATED-NEXT: ret
+;
+; RV32I-MEDIUM-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV32I-MEDIUM-INTEGRATED: # %bb.0: # %entry
+; RV32I-MEDIUM-INTEGRATED-NEXT: .Lpcrel_hi11:
+; RV32I-MEDIUM-INTEGRATED-NEXT: auipc a1, %pcrel_hi(eg)
+; RV32I-MEDIUM-INTEGRATED-NEXT: #APP
+; RV32I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV32I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV32I-MEDIUM-INTEGRATED-NEXT: beqz a0, .LBB14_2
+; RV32I-MEDIUM-INTEGRATED-NEXT: #NO_APP
+; RV32I-MEDIUM-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV32I-MEDIUM-INTEGRATED-NEXT: li a0, 0
+; RV32I-MEDIUM-INTEGRATED-NEXT: ret
+; RV32I-MEDIUM-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV32I-MEDIUM-INTEGRATED-NEXT: # %fail
+; RV32I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
+; RV32I-MEDIUM-INTEGRATED-NEXT: li a0, 1
+; RV32I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-MEDIUM-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-MEDIUM-INTEGRATED: # %bb.0: # %entry
+; RV64I-MEDIUM-INTEGRATED-NEXT: .Lpcrel_hi11:
+; RV64I-MEDIUM-INTEGRATED-NEXT: auipc a1, %pcrel_hi(eg)
+; RV64I-MEDIUM-INTEGRATED-NEXT: #APP
+; RV64I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV64I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV64I-MEDIUM-INTEGRATED-NEXT: beqz a0, .LBB14_2
+; RV64I-MEDIUM-INTEGRATED-NEXT: #NO_APP
+; RV64I-MEDIUM-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 0
+; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+; RV64I-MEDIUM-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV64I-MEDIUM-INTEGRATED-NEXT: # %fail
+; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of...
[truncated]
|
@@ -0,0 +1,95 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | |||
; integrated-as fails with error: unexpected token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this comment below the RUN lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed
; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM %s | ||
; | ||
; integrated-as fails with error: unexpected token | ||
; sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use \0A instead of \n?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was in the test before my chagne. I just split inline-asm-mem-contriant.ll into two tests: the one that fails with intergrated-as and the second one that works correctly.
I mean I can change it, not a problem. But originally it was added with '\n'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok we can leave them split then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
(Actually, this is a problem I have already found when I was implementing it, but I didn't put it in mind).
Commit 5cd8d53 taught RISCVMergeBaseOffset to handle inline asm, however there is at least one case uncovered for integrated as. In the example below compiler generates pcrel relocation (mcmodel=medany) volatile double double_val = 1.0; void foo() { asm volatile("fld f0, %0 \n\t" : : "m"(double_val) : "memory"); } And fails with the folliwng error error: could not find corresponding %pcrel_hi | "fld f0, %0 \n\t" <inline asm>:1:2: note: instantiated into assembly here | fld f0, %pcrel_lo(.Lpcrel_hi0)(a0) After transformations MachineFunction contains inline asm instructions with '.Lpcrel_hi0' symbol that is not defined in inline asm, but referenced. ... = AUIPC ...(riscv-pcrel-hi) @double_val, pre-instr-symbol <mcsymbol .Lpcrel_hi0> INLINEASM &"fld f0, $0 \0A\09" ... target-flags(riscv-pcrel-lo) <mcsymbol .Lpcrel_hi0> So, when AsmParser processes 'fld', it has to create a new symbol as '.Lpcrel_hi0' already exists but not known to be referenced in inline asm. AsmParser avoids conflicts by renaming referenced by 'fld' symbol with '.Lpcrel_hi00' name which does not exist. Resulting erroneous asm .Lpcrel_hi0: auipc a0, %pcrel_hi(double_val) #APP fld ft0, %pcrel_lo(.Lpcrel_hi00)(a0) This change adds symbols used in memory operands to the list of referenced ones.
Rebased on top of precommitted test. |
…d5842fd7a Local branch amd-gfx 58ed584 Merged main:4549a8d251cfa91cc6230139595f0b7efdf199d9 into amd-gfx:757aa7b5f1a5 Remote branch main 2f91e98 [RISCV] Mark symbols used in inline asm for relocations as referenced (llvm#104925)
Commit 5cd8d53 taught RISCVMergeBaseOffset to handle inline asm, however
there is at least one case uncovered for integrated as.
In the example below compiler generates pcrel relocation (mcmodel=medany)
And fails with the folliwng error
After transformations MachineFunction contains inline asm instructions with
'.Lpcrel_hi0' symbol that is not defined in inline asm, but referenced.
So, when AsmParser processes 'fld', it has to create a new symbol as
'.Lpcrel_hi0' already exists but not known to be referenced in inline asm.
AsmParser avoids conflicts by renaming referenced by 'fld' symbol with
'.Lpcrel_hi00' name which does not exist. Resulting erroneous asm
This change adds symbols used in memory operands to the list of referenced ones.
Godbolt link: https://godbolt.org/z/aqrrsWKoK -- on the left you can find incorrect labels for the integrated-as and on the right an error when compiling to the binary object.
Note that I change tests in the first commit and the second commit shows the real difference after the fix.