summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-05-02 22:45:19 +0000
committerTim Northover <tnorthover@apple.com>2017-05-02 22:45:19 +0000
commit4a01ffbd6aca4a26f4a7b6f9112e920a56ff6e07 (patch)
tree12488b10098b01dc35949673a950b333c3020c77
parent9decbfee32cd1ff8538cbb97e1ec4d7ee7cb577e (diff)
downloadbcm5719-llvm-4a01ffbd6aca4a26f4a7b6f9112e920a56ff6e07.tar.gz
bcm5719-llvm-4a01ffbd6aca4a26f4a7b6f9112e920a56ff6e07.zip
ARM: avoid handing a deleted node back to TableGen during ISel.
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. llvm-svn: 301983
-rw-r--r--llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp4
-rw-r--r--llvm/test/CodeGen/ARM/load-arm.ll17
2 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index e9df9449103..7f9fe55a5c3 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -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/llvm/test/CodeGen/ARM/load-arm.ll b/llvm/test/CodeGen/ARM/load-arm.ll
new file mode 100644
index 00000000000..94ade49a121
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/load-arm.ll
@@ -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
+}
OpenPOWER on IntegriCloud