From: Tim Northover Date: Wed, 9 Dec 2015 15:54:50 +0000 (+0000) Subject: ARM: don't use a deleted node as the BaseReg in complex pattern. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6d8e50b6e2c07d1502dc899dd1741af14111b480;p=oota-llvm.git ARM: don't use a deleted node as the BaseReg in complex pattern. We mutated the DAG, which invalidated the node we were trying to use as a base register. Sometimes we got away with it, but other times the node really did get deleted before it was finished with. Should fix PR25733 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255120 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index cd73021dfc6..024244092a3 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -548,8 +548,11 @@ bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N, unsigned PowerOfTwo = 0; SDValue NewMulConst; if (canExtractShiftFromMul(N, 31, PowerOfTwo, NewMulConst)) { + BaseReg = SDValue(Select(CurDAG->getNode(ISD::MUL, SDLoc(N), MVT::i32, + N.getOperand(0), NewMulConst) + .getNode()), + 0); replaceDAGValue(N.getOperand(1), NewMulConst); - BaseReg = N; Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ARM_AM::lsl, PowerOfTwo), SDLoc(N), MVT::i32); diff --git a/test/CodeGen/ARM/shifter_operand.ll b/test/CodeGen/ARM/shifter_operand.ll index 11a8ee6ef7d..5d44eb0f11d 100644 --- a/test/CodeGen/ARM/shifter_operand.ll +++ b/test/CodeGen/ARM/shifter_operand.ll @@ -224,3 +224,18 @@ entry: %conv = zext i8 %0 to i32 ret i32 %conv } + + +define void @test_well_formed_dag(i32 %in1, i32 %in2, i32* %addr) { +; CHECK-LABEL: test_well_formed_dag: +; CHECK-ARM: movw [[SMALL_CONST:r[0-9]+]], #675 +; CHECK-ARM: mul [[SMALL_PROD:r[0-9]+]], r0, [[SMALL_CONST]] +; CHECK-ARM: add {{r[0-9]+}}, r1, [[SMALL_PROD]], lsl #7 + + %mul.small = mul i32 %in1, 675 + store i32 %mul.small, i32* %addr + %mul.big = mul i32 %in1, 86400 + %add = add i32 %in2, %mul.big + store i32 %add, i32* %addr + ret void +}