diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -73,6 +73,7 @@ int JT; unsigned Align; // CP alignment. unsigned char SymbolFlags; // X86II::MO_* + bool NegateIndex = false; X86ISelAddressMode() : BaseType(RegBase), Base_FrameIndex(0), Scale(1), IndexReg(), Disp(0), @@ -115,6 +116,8 @@ dbgs() << " Base.FrameIndex " << Base_FrameIndex << '\n'; dbgs() << " Scale " << Scale << '\n' << "IndexReg "; + if (NegateIndex) + dbgs() << "negate "; if (IndexReg.getNode()) IndexReg.getNode()->dump(DAG); else @@ -271,6 +274,14 @@ Scale = getI8Imm(AM.Scale, DL); + // Negate the index if needed. + if (AM.NegateIndex) { + unsigned NegOpc = VT == MVT::i64 ? X86::NEG64r : X86::NEG32r; + SDValue Neg = SDValue(CurDAG->getMachineNode(NegOpc, DL, VT, MVT::i32, + AM.IndexReg), 0); + AM.IndexReg = Neg; + } + if (AM.IndexReg.getNode()) Index = AM.IndexReg; else @@ -1863,14 +1874,11 @@ } // Ok, the transformation is legal and appears profitable. Go for it. - SDValue Zero = CurDAG->getConstant(0, dl, N.getValueType()); - SDValue Neg = CurDAG->getNode(ISD::SUB, dl, N.getValueType(), Zero, RHS); - AM.IndexReg = Neg; + // Negation will be emitted later to avoid creating dangling nodes if this + // was an unprofitable LEA. + AM.IndexReg = RHS; + AM.NegateIndex = true; AM.Scale = 1; - - // Insert the new nodes into the topological ordering. - insertDAGNode(*CurDAG, N, Zero); - insertDAGNode(*CurDAG, N, Neg); return false; } diff --git a/llvm/test/CodeGen/X86/imul.ll b/llvm/test/CodeGen/X86/imul.ll --- a/llvm/test/CodeGen/X86/imul.ll +++ b/llvm/test/CodeGen/X86/imul.ll @@ -2,6 +2,8 @@ ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s --check-prefix=X64 ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefix=X86 +; At least one of the test cases in here crashed when linearizing the DAG. +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -pre-RA-sched=linearize define i32 @mul4_32(i32 %A) { ; X64-LABEL: mul4_32: