[llvm] 9ae28fb - [RISCV] Prevent RISCVMergeBaseOffsetOpt from calling getVRegDef on a physical register. (#78762)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 19 12:15:13 PST 2024
Author: Craig Topper
Date: 2024-01-19T12:15:08-08:00
New Revision: 9ae28fb9d3b8d8f3db7cc55c164aa1ceb4df300c
URL: https://github.com/llvm/llvm-project/commit/9ae28fb9d3b8d8f3db7cc55c164aa1ceb4df300c
DIFF: https://github.com/llvm/llvm-project/commit/9ae28fb9d3b8d8f3db7cc55c164aa1ceb4df300c.diff
LOG: [RISCV] Prevent RISCVMergeBaseOffsetOpt from calling getVRegDef on a physical register. (#78762)
Fixes #78679.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index ae46d5554d3505d..866b2453579cc37 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -181,7 +181,7 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
Register Reg = Rs == GAReg ? Rt : Rs;
// Can't fold if the register has more than one use.
- if (!MRI->hasOneUse(Reg))
+ if (!Reg.isVirtual() || !MRI->hasOneUse(Reg))
return false;
// This can point to an ADDI(W) or a LUI:
MachineInstr &OffsetTail = *MRI->getVRegDef(Reg);
@@ -192,9 +192,11 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
MachineOperand &AddiImmOp = OffsetTail.getOperand(2);
if (AddiImmOp.getTargetFlags() != RISCVII::MO_None)
return false;
+ Register AddiReg = OffsetTail.getOperand(1).getReg();
+ if (!AddiReg.isVirtual())
+ return false;
int64_t OffLo = AddiImmOp.getImm();
- MachineInstr &OffsetLui =
- *MRI->getVRegDef(OffsetTail.getOperand(1).getReg());
+ MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg);
MachineOperand &LuiImmOp = OffsetLui.getOperand(1);
if (OffsetLui.getOpcode() != RISCV::LUI ||
LuiImmOp.getTargetFlags() != RISCVII::MO_None ||
@@ -246,14 +248,14 @@ bool RISCVMergeBaseOffsetOpt::foldShiftedOffset(MachineInstr &Hi,
TailShXAdd.getOpcode() == RISCV::SH3ADD) &&
"Expected SHXADD instruction!");
- // The first source is the shifted operand.
- Register Rs1 = TailShXAdd.getOperand(1).getReg();
-
if (GAReg != TailShXAdd.getOperand(2).getReg())
return false;
+ // The first source is the shifted operand.
+ Register Rs1 = TailShXAdd.getOperand(1).getReg();
+
// Can't fold if the register has more than one use.
- if (!MRI->hasOneUse(Rs1))
+ if (!Rs1.isVirtual() || !MRI->hasOneUse(Rs1))
return false;
// This can point to an ADDI X0, C.
MachineInstr &OffsetTail = *MRI->getVRegDef(Rs1);
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
index 7c2f775bca14e6d..74652cbc73b601f 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
@@ -964,3 +964,69 @@ for.body: ; preds = %for.body.lr.ph, %fo
}
declare void @f(ptr)
+
+ at g = external dso_local global [100 x [100 x i8]]
+
+; This test used to crash due to calling getVRegDef on X0.
+define i32 @crash() {
+; RV32I-LABEL: crash:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a0, 1
+; RV32I-NEXT: lui a1, %hi(g)
+; RV32I-NEXT: addi a1, a1, %lo(g)
+; RV32I-NEXT: add a0, a1, a0
+; RV32I-NEXT: lbu a0, 400(a0)
+; RV32I-NEXT: seqz a0, a0
+; RV32I-NEXT: sw a0, 0(zero)
+; RV32I-NEXT: li a0, 0
+; RV32I-NEXT: ret
+;
+; RV32I-MEDIUM-LABEL: crash:
+; RV32I-MEDIUM: # %bb.0: # %entry
+; RV32I-MEDIUM-NEXT: li a0, 1
+; RV32I-MEDIUM-NEXT: .Lpcrel_hi14:
+; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(g)
+; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi14)
+; RV32I-MEDIUM-NEXT: add a0, a1, a0
+; RV32I-MEDIUM-NEXT: lbu a0, 400(a0)
+; RV32I-MEDIUM-NEXT: seqz a0, a0
+; RV32I-MEDIUM-NEXT: sw a0, 0(zero)
+; RV32I-MEDIUM-NEXT: li a0, 0
+; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-LABEL: crash:
+; RV64I: # %bb.0: # %entry
+; RV64I-NEXT: li a0, 1
+; RV64I-NEXT: lui a1, %hi(g)
+; RV64I-NEXT: addi a1, a1, %lo(g)
+; RV64I-NEXT: add a0, a1, a0
+; RV64I-NEXT: lbu a0, 400(a0)
+; RV64I-NEXT: seqz a0, a0
+; RV64I-NEXT: sw a0, 0(zero)
+; RV64I-NEXT: li a0, 0
+; RV64I-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: crash:
+; RV64I-MEDIUM: # %bb.0: # %entry
+; RV64I-MEDIUM-NEXT: li a0, 1
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi14:
+; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(g)
+; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi14)
+; RV64I-MEDIUM-NEXT: add a0, a1, a0
+; RV64I-MEDIUM-NEXT: lbu a0, 400(a0)
+; RV64I-MEDIUM-NEXT: seqz a0, a0
+; RV64I-MEDIUM-NEXT: sw a0, 0(zero)
+; RV64I-MEDIUM-NEXT: li a0, 0
+; RV64I-MEDIUM-NEXT: ret
+entry:
+ %idxprom7.peel = sext i32 1 to i64
+ br label %for.inc.peel
+
+for.inc.peel: ; preds = %entry
+ %arrayidx8.3.peel = getelementptr [100 x [100 x i8]], ptr @g, i64 0, i64 4, i64 %idxprom7.peel
+ %0 = load i8, ptr %arrayidx8.3.peel, align 1
+ %tobool.not.3.peel = icmp eq i8 %0, 0
+ %spec.select = select i1 %tobool.not.3.peel, i32 1, i32 0
+ store i32 %spec.select, ptr null, align 4
+ ret i32 0
+}
More information about the llvm-commits
mailing list