[llvm] [RISCV] Prevent RISCVMergeBaseOffsetOpt from calling getVRegDef on a physical register. (PR #78762)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 19 12:05:22 PST 2024


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/78762

>From a8a6eb7d2c5284b4812b520672d84854269d87f0 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 19 Jan 2024 11:06:10 -0800
Subject: [PATCH 1/3] [RISCV] Prevent RISCVMergeBaseOffsetOpt from calling
 getVRegDef on a physical register.

Fixes #78679.
---
 .../lib/Target/RISCV/RISCVMergeBaseOffset.cpp |  6 +-
 .../test/CodeGen/RISCV/fold-addi-loadstore.ll | 66 +++++++++++++++++++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index ae46d5554d3505d..71702ba655aeac0 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -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 ||
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
index 7c2f775bca14e6d..124431eb5b6201e 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 caling 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
+}

>From 615c1c46e0d45a15bec40b2e5a90726409b0881a Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 19 Jan 2024 11:31:59 -0800
Subject: [PATCH 2/3] fixup! Qualify other getVRegDef calls too.

---
 llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index 71702ba655aeac0..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);
@@ -248,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);

>From 82b7bd71d834aa5d11c5540b8d44cc998a9fd16a Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 19 Jan 2024 12:05:11 -0800
Subject: [PATCH 3/3] fixup! fix typos in comment.

---
 llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
index 124431eb5b6201e..74652cbc73b601f 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
@@ -967,7 +967,7 @@ declare void @f(ptr)
 
 @g = external dso_local global [100 x [100 x i8]]
 
-; This Test used to crash due to caling getVRegDef on X0.
+; This test used to crash due to calling getVRegDef on X0.
 define i32 @crash() {
 ; RV32I-LABEL: crash:
 ; RV32I:       # %bb.0: # %entry



More information about the llvm-commits mailing list