[llvm] f91690f - [RISCV] Don't merge addi into load/store address if addi has a FrameIndex operand.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 29 18:23:48 PDT 2022


Author: Craig Topper
Date: 2022-04-29T18:22:20-07:00
New Revision: f91690f7db96aae16425241a17fe6649f5d156b4

URL: https://github.com/llvm/llvm-project/commit/f91690f7db96aae16425241a17fe6649f5d156b4
DIFF: https://github.com/llvm/llvm-project/commit/f91690f7db96aae16425241a17fe6649f5d156b4.diff

LOG: [RISCV] Don't merge addi into load/store address if addi has a FrameIndex operand.

This fixes a crash from D124231.

We can't fold
  (load (add base, (addi src, off1)), off2)
     -> (load (add base, src), off1+off2)
if the src is a FrameIndex. FrameIndex cannot be the operand of an
add.

There was an immediate==0 check that I think was trying to catch
the common case of FrameIndex addis where the immediate is 0, but
they can also appear in non-zero form. Instead explicitly check
for a FrameIndex operand.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
    llvm/test/CodeGen/RISCV/mem.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 87c3d6d3a19e..de9c15122177 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -2099,7 +2099,8 @@ bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) {
   if (!Base.isMachineOpcode())
     return false;
 
-  // There is a ADD between ADDI and load/store.
+  // There is a ADD between ADDI and load/store. We can only fold ADDI that
+  // do not have a FrameIndex operand.
   SDValue Add;
   int AddBaseIdx;
   if (Base.getMachineOpcode() == RISCV::ADD) {
@@ -2109,13 +2110,13 @@ bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) {
     SDValue Op0 = Base.getOperand(0);
     SDValue Op1 = Base.getOperand(1);
     if (Op0.isMachineOpcode() && Op0.getMachineOpcode() == RISCV::ADDI &&
-        isa<ConstantSDNode>(Op0.getOperand(1)) &&
-        cast<ConstantSDNode>(Op0.getOperand(1))->getSExtValue() != 0) {
+        !isa<FrameIndexSDNode>(Op0.getOperand(0)) &&
+        isa<ConstantSDNode>(Op0.getOperand(1))) {
       AddBaseIdx = 1;
       Base = Op0;
     } else if (Op1.isMachineOpcode() && Op1.getMachineOpcode() == RISCV::ADDI &&
-               isa<ConstantSDNode>(Op1.getOperand(1)) &&
-               cast<ConstantSDNode>(Op1.getOperand(1))->getSExtValue() != 0) {
+               !isa<FrameIndexSDNode>(Op1.getOperand(0)) &&
+               isa<ConstantSDNode>(Op1.getOperand(1))) {
       AddBaseIdx = 0;
       Base = Op1;
     } else

diff  --git a/llvm/test/CodeGen/RISCV/mem.ll b/llvm/test/CodeGen/RISCV/mem.ll
index 180074386ba8..c6c3ce8f649b 100644
--- a/llvm/test/CodeGen/RISCV/mem.ll
+++ b/llvm/test/CodeGen/RISCV/mem.ll
@@ -237,3 +237,34 @@ define i32 @lw_sw_far_local(i32* %a, i32 %b)  {
   store i32 %b, i32* %1
   ret i32 %2
 }
+
+%struct.quux = type { i32, [0 x i8] }
+
+; Make sure we don't remove the addi and fold the C from
+; (add (addi FrameIndex, C), X) into the store address.
+; FrameIndex cannot be the operand of an ADD. We must keep the ADDI.
+define void @addi_fold_crash(i32 %arg) {
+; RV32I-LABEL: addi_fold_crash:
+; RV32I:       # %bb.0: # %bb
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    .cfi_offset ra, -4
+; RV32I-NEXT:    addi a1, sp, 12
+; RV32I-NEXT:    add a0, a1, a0
+; RV32I-NEXT:    sb zero, 0(a0)
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:    call snork at plt
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+bb:
+  %tmp = alloca %struct.quux, align 4
+  %tmp1 = getelementptr inbounds %struct.quux, %struct.quux* %tmp, i32 0, i32 1
+  %tmp2 = getelementptr inbounds %struct.quux, %struct.quux* %tmp, i32 0, i32 1, i32 %arg
+  store i8 0, i8* %tmp2, align 1
+  call void @snork([0 x i8]* %tmp1)
+  ret void
+}
+
+declare void @snork([0 x i8]*)


        


More information about the llvm-commits mailing list