-
Notifications
You must be signed in to change notification settings - Fork 12.2k
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
[RISCV] Don't crash in RISCVMergeBaseOffset if INLINE_ASM uses address register in a non-memory constraint. #100790
Conversation
…s register in a non-memory constraint. If the register is used by a non-memory constraint we should disable the fold. Otherwise, we may leave CommonOffset unassigned. Fixes llvm#100779.
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesIf the register is used by a non-memory constraint we should disable the fold. Otherwise, we may leave CommonOffset unassigned. Fixes #100779. Full diff: https://github.com/llvm/llvm-project/pull/100790.diff 2 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index fecc83a821f42..b6ac3384e7d3e 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -429,8 +429,16 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi,
NumOps = Flags.getNumOperandRegisters();
// Memory constraints have two operands.
- if (NumOps != 2 || !Flags.isMemKind())
+ if (NumOps != 2 || !Flags.isMemKind()) {
+ // If the register is used by something other than a memory contraint,
+ // we should not fold.
+ for (unsigned J = 0; J < NumOps; ++J) {
+ const MachineOperand &MO = UseMI.getOperand(I + 1 + J);
+ if (MO.isReg() && MO.getReg() == DestReg)
+ return false;
+ }
continue;
+ }
// We can't do this for constraint A because AMO instructions don't have
// an immediate offset field.
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
index 52d0dabf18839..6666d92feaac2 100644
--- a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
+++ b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
@@ -2252,3 +2252,53 @@ label:
call void asm "lw zero, $0", "*A"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_A_with_local_3, %label), i32 2000))
ret void
}
+
+@_ZN5repro9MY_BUFFER17hb0f674501d5980a6E = external global <{ [16 x i8] }>
+
+; Address is not used by a memory constraint.
+define void @should_not_fold() {
+; RV32I-LABEL: should_not_fold:
+; RV32I: # %bb.0: # %start
+; RV32I-NEXT: .cfi_def_cfa_offset 0
+; RV32I-NEXT: lui a0, %hi(_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+; RV32I-NEXT: addi a0, a0, %lo(_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+; RV32I-NEXT: #APP
+; RV32I-NEXT: ecall
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: should_not_fold:
+; RV64I: # %bb.0: # %start
+; RV64I-NEXT: .cfi_def_cfa_offset 0
+; RV64I-NEXT: lui a0, %hi(_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+; RV64I-NEXT: addi a0, a0, %lo(_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+; RV64I-NEXT: #APP
+; RV64I-NEXT: ecall
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+;
+; RV32I-MEDIUM-LABEL: should_not_fold:
+; RV32I-MEDIUM: # %bb.0: # %start
+; RV32I-MEDIUM-NEXT: .cfi_def_cfa_offset 0
+; RV32I-MEDIUM-NEXT: .Lpcrel_hi39:
+; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi39)
+; RV32I-MEDIUM-NEXT: #APP
+; RV32I-MEDIUM-NEXT: ecall
+; RV32I-MEDIUM-NEXT: #NO_APP
+; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: should_not_fold:
+; RV64I-MEDIUM: # %bb.0: # %start
+; RV64I-MEDIUM-NEXT: .cfi_def_cfa_offset 0
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi39:
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi39)
+; RV64I-MEDIUM-NEXT: #APP
+; RV64I-MEDIUM-NEXT: ecall
+; RV64I-MEDIUM-NEXT: #NO_APP
+; RV64I-MEDIUM-NEXT: ret
+start:
+ %0 = tail call ptr asm sideeffect alignstack "ecall", "=&{x10},0,~{vtype},~{vl},~{vxsat},~{vxrm},~{memory}"(ptr @_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
+ ret void
+}
|
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 for fixing this!
(This bug was introduced by me🥺)
…s register in a non-memory constraint. (llvm#100790) If the register is used by a non-memory constraint we should disable the fold. Otherwise, we may leave CommonOffset unassigned. Fixes llvm#100779. (cherry picked from commit c901b73)
…s register in a non-memory constraint. (llvm#100790) If the register is used by a non-memory constraint we should disable the fold. Otherwise, we may leave CommonOffset unassigned. Fixes llvm#100779. (cherry picked from commit c901b73)
If the register is used by a non-memory constraint we should disable the fold. Otherwise, we may leave CommonOffset unassigned.
Fixes #100779.