]> granicus.if.org Git - llvm/commitdiff
ARM: avoid handing a deleted node back to TableGen during ISel.
authorTim Northover <tnorthover@apple.com>
Tue, 2 May 2017 22:45:19 +0000 (22:45 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 2 May 2017 22:45:19 +0000 (22:45 +0000)
When we replaced the multiplicand the destination node might already exist.
When that happens the original gets CSEd and deleted. However, it's actually
used as the offset so nonsense is produced.

Should fix PR32726.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301983 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelDAGToDAG.cpp
test/CodeGen/ARM/load-arm.ll [new file with mode: 0644]

index e9df9449103c106cd01bdd59408bb39bacf64235..7f9fe55a5c38b54c26d7cf984e6bf2115a1c1887 100644 (file)
@@ -740,7 +740,9 @@ bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset,
     unsigned PowerOfTwo = 0;
     SDValue NewMulConst;
     if (canExtractShiftFromMul(Offset, 31, PowerOfTwo, NewMulConst)) {
+      HandleSDNode Handle(Offset);
       replaceDAGValue(Offset.getOperand(1), NewMulConst);
+      Offset = Handle.getValue();
       ShAmt = PowerOfTwo;
       ShOpcVal = ARM_AM::lsl;
     }
@@ -1420,7 +1422,9 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N,
     unsigned PowerOfTwo = 0;
     SDValue NewMulConst;
     if (canExtractShiftFromMul(OffReg, 3, PowerOfTwo, NewMulConst)) {
+      HandleSDNode Handle(OffReg);
       replaceDAGValue(OffReg.getOperand(1), NewMulConst);
+      OffReg = Handle.getValue();
       ShAmt = PowerOfTwo;
     }
   }
diff --git a/test/CodeGen/ARM/load-arm.ll b/test/CodeGen/ARM/load-arm.ll
new file mode 100644 (file)
index 0000000..94ade49
--- /dev/null
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=arm %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumbv7 %s -o - | FileCheck %s
+
+; We ended up feeding a deleted node back to TableGen when we converted "Off *
+; 410" into "(Off * 205) << 1", where the multiplication already existed in the
+; DAG.
+
+; CHECK-LABEL: addrmode_cse_mutation:
+; CHECK: {{mul|muls}}    [[OFFSET:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}
+; CHECK: {{ldrb|ldrb.w}} {{r[0-9]+}}, [r0, [[OFFSET]], lsl #3]
+define i32 @addrmode_cse_mutation(i8* %base, i32 %count) {
+  %offset = mul i32 %count, 277288
+  %ptr = getelementptr i8, i8* %base, i32 %offset
+  %val = load volatile i8, i8* %ptr
+  %res = mul i32 %count, 34661
+  ret i32 %res
+}