Skip to content

Commit 9ae28fb

Browse files
authored
[RISCV] Prevent RISCVMergeBaseOffsetOpt from calling getVRegDef on a physical register. (#78762)
Fixes #78679.
1 parent 9247013 commit 9ae28fb

File tree

2 files changed

+75
-7
lines changed

2 files changed

+75
-7
lines changed

llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
181181
Register Reg = Rs == GAReg ? Rt : Rs;
182182

183183
// Can't fold if the register has more than one use.
184-
if (!MRI->hasOneUse(Reg))
184+
if (!Reg.isVirtual() || !MRI->hasOneUse(Reg))
185185
return false;
186186
// This can point to an ADDI(W) or a LUI:
187187
MachineInstr &OffsetTail = *MRI->getVRegDef(Reg);
@@ -192,9 +192,11 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
192192
MachineOperand &AddiImmOp = OffsetTail.getOperand(2);
193193
if (AddiImmOp.getTargetFlags() != RISCVII::MO_None)
194194
return false;
195+
Register AddiReg = OffsetTail.getOperand(1).getReg();
196+
if (!AddiReg.isVirtual())
197+
return false;
195198
int64_t OffLo = AddiImmOp.getImm();
196-
MachineInstr &OffsetLui =
197-
*MRI->getVRegDef(OffsetTail.getOperand(1).getReg());
199+
MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg);
198200
MachineOperand &LuiImmOp = OffsetLui.getOperand(1);
199201
if (OffsetLui.getOpcode() != RISCV::LUI ||
200202
LuiImmOp.getTargetFlags() != RISCVII::MO_None ||
@@ -246,14 +248,14 @@ bool RISCVMergeBaseOffsetOpt::foldShiftedOffset(MachineInstr &Hi,
246248
TailShXAdd.getOpcode() == RISCV::SH3ADD) &&
247249
"Expected SHXADD instruction!");
248250

249-
// The first source is the shifted operand.
250-
Register Rs1 = TailShXAdd.getOperand(1).getReg();
251-
252251
if (GAReg != TailShXAdd.getOperand(2).getReg())
253252
return false;
254253

254+
// The first source is the shifted operand.
255+
Register Rs1 = TailShXAdd.getOperand(1).getReg();
256+
255257
// Can't fold if the register has more than one use.
256-
if (!MRI->hasOneUse(Rs1))
258+
if (!Rs1.isVirtual() || !MRI->hasOneUse(Rs1))
257259
return false;
258260
// This can point to an ADDI X0, C.
259261
MachineInstr &OffsetTail = *MRI->getVRegDef(Rs1);

llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,3 +964,69 @@ for.body: ; preds = %for.body.lr.ph, %fo
964964
}
965965

966966
declare void @f(ptr)
967+
968+
@g = external dso_local global [100 x [100 x i8]]
969+
970+
; This test used to crash due to calling getVRegDef on X0.
971+
define i32 @crash() {
972+
; RV32I-LABEL: crash:
973+
; RV32I: # %bb.0: # %entry
974+
; RV32I-NEXT: li a0, 1
975+
; RV32I-NEXT: lui a1, %hi(g)
976+
; RV32I-NEXT: addi a1, a1, %lo(g)
977+
; RV32I-NEXT: add a0, a1, a0
978+
; RV32I-NEXT: lbu a0, 400(a0)
979+
; RV32I-NEXT: seqz a0, a0
980+
; RV32I-NEXT: sw a0, 0(zero)
981+
; RV32I-NEXT: li a0, 0
982+
; RV32I-NEXT: ret
983+
;
984+
; RV32I-MEDIUM-LABEL: crash:
985+
; RV32I-MEDIUM: # %bb.0: # %entry
986+
; RV32I-MEDIUM-NEXT: li a0, 1
987+
; RV32I-MEDIUM-NEXT: .Lpcrel_hi14:
988+
; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(g)
989+
; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi14)
990+
; RV32I-MEDIUM-NEXT: add a0, a1, a0
991+
; RV32I-MEDIUM-NEXT: lbu a0, 400(a0)
992+
; RV32I-MEDIUM-NEXT: seqz a0, a0
993+
; RV32I-MEDIUM-NEXT: sw a0, 0(zero)
994+
; RV32I-MEDIUM-NEXT: li a0, 0
995+
; RV32I-MEDIUM-NEXT: ret
996+
;
997+
; RV64I-LABEL: crash:
998+
; RV64I: # %bb.0: # %entry
999+
; RV64I-NEXT: li a0, 1
1000+
; RV64I-NEXT: lui a1, %hi(g)
1001+
; RV64I-NEXT: addi a1, a1, %lo(g)
1002+
; RV64I-NEXT: add a0, a1, a0
1003+
; RV64I-NEXT: lbu a0, 400(a0)
1004+
; RV64I-NEXT: seqz a0, a0
1005+
; RV64I-NEXT: sw a0, 0(zero)
1006+
; RV64I-NEXT: li a0, 0
1007+
; RV64I-NEXT: ret
1008+
;
1009+
; RV64I-MEDIUM-LABEL: crash:
1010+
; RV64I-MEDIUM: # %bb.0: # %entry
1011+
; RV64I-MEDIUM-NEXT: li a0, 1
1012+
; RV64I-MEDIUM-NEXT: .Lpcrel_hi14:
1013+
; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(g)
1014+
; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi14)
1015+
; RV64I-MEDIUM-NEXT: add a0, a1, a0
1016+
; RV64I-MEDIUM-NEXT: lbu a0, 400(a0)
1017+
; RV64I-MEDIUM-NEXT: seqz a0, a0
1018+
; RV64I-MEDIUM-NEXT: sw a0, 0(zero)
1019+
; RV64I-MEDIUM-NEXT: li a0, 0
1020+
; RV64I-MEDIUM-NEXT: ret
1021+
entry:
1022+
%idxprom7.peel = sext i32 1 to i64
1023+
br label %for.inc.peel
1024+
1025+
for.inc.peel: ; preds = %entry
1026+
%arrayidx8.3.peel = getelementptr [100 x [100 x i8]], ptr @g, i64 0, i64 4, i64 %idxprom7.peel
1027+
%0 = load i8, ptr %arrayidx8.3.peel, align 1
1028+
%tobool.not.3.peel = icmp eq i8 %0, 0
1029+
%spec.select = select i1 %tobool.not.3.peel, i32 1, i32 0
1030+
store i32 %spec.select, ptr null, align 4
1031+
ret i32 0
1032+
}

0 commit comments

Comments
 (0)