From dde85de90f79218e0ab89c951282cf52a860c32a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 16 Jan 2011 08:48:11 +0000 Subject: [PATCH] fix PR8514, a bug where the "heroic" transformation of shift/and into and/shift would cause nodes to move around and a dangling pointer to happen. The code tried to avoid this with a HandleSDNode, but got the details wrong. llvm-svn: 123578 --- lib/Target/X86/X86ISelDAGToDAG.cpp | 22 ++++++++---------- test/CodeGen/X86/crash.ll | 36 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index d9e8980d965..70f025704df 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -933,24 +933,18 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, // Add an artificial use to this node so that we can keep track of // it if it gets CSE'd with a different node. HandleSDNode Handle(N); - SDValue LHS = Handle.getValue().getNode()->getOperand(0); - SDValue RHS = Handle.getValue().getNode()->getOperand(1); X86ISelAddressMode Backup = AM; - if (!MatchAddressRecursively(LHS, AM, Depth+1) && - !MatchAddressRecursively(RHS, AM, Depth+1)) + if (!MatchAddressRecursively(N.getOperand(0), AM, Depth+1) && + !MatchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth+1)) return false; AM = Backup; - LHS = Handle.getValue().getNode()->getOperand(0); - RHS = Handle.getValue().getNode()->getOperand(1); - + // Try again after commuting the operands. - if (!MatchAddressRecursively(RHS, AM, Depth+1) && - !MatchAddressRecursively(LHS, AM, Depth+1)) + if (!MatchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth+1)&& + !MatchAddressRecursively(Handle.getValue().getOperand(0), AM, Depth+1)) return false; AM = Backup; - LHS = Handle.getValue().getNode()->getOperand(0); - RHS = Handle.getValue().getNode()->getOperand(1); // If we couldn't fold both operands into the address at the same time, // see if we can just put each operand into a register and fold at least @@ -958,11 +952,13 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, if (AM.BaseType == X86ISelAddressMode::RegBase && !AM.Base_Reg.getNode() && !AM.IndexReg.getNode()) { - AM.Base_Reg = LHS; - AM.IndexReg = RHS; + N = Handle.getValue(); + AM.Base_Reg = N.getOperand(0); + AM.IndexReg = N.getOperand(1); AM.Scale = 1; return false; } + N = Handle.getValue(); break; } diff --git a/test/CodeGen/X86/crash.ll b/test/CodeGen/X86/crash.ll index 49ca04b14aa..93277764963 100644 --- a/test/CodeGen/X86/crash.ll +++ b/test/CodeGen/X86/crash.ll @@ -151,3 +151,39 @@ entry: ret i32 %cond } + +; PR8514 - Crash in match address do to "heroics" turning and-of-shift into +; shift of and. +%struct.S0 = type { i8, [2 x i8], i8 } + +define void @func_59(i32 %p_63) noreturn nounwind { +entry: + br label %for.body + +for.body: ; preds = %for.inc44, %entry + %p_63.addr.1 = phi i32 [ %p_63, %entry ], [ 0, %for.inc44 ] + %l_74.0 = phi i32 [ 0, %entry ], [ %add46, %for.inc44 ] + br i1 undef, label %for.inc44, label %bb.nph81 + +bb.nph81: ; preds = %for.body + %tmp98 = add i32 %p_63.addr.1, 0 + br label %for.body22 + +for.body22: ; preds = %for.body22, %bb.nph81 + %l_75.077 = phi i64 [ %ins, %for.body22 ], [ undef, %bb.nph81 ] + %tmp110 = trunc i64 %l_75.077 to i32 + %tmp111 = and i32 %tmp110, 65535 + %arrayidx32.0 = getelementptr [9 x [5 x [2 x %struct.S0]]]* undef, i32 0, i32 %l_74.0, i32 %tmp98, i32 %tmp111, i32 0 + store i8 1, i8* %arrayidx32.0, align 4 + %tmp106 = shl i32 %tmp110, 2 + %tmp107 = and i32 %tmp106, 262140 + %scevgep99.sum114 = or i32 %tmp107, 1 + %arrayidx32.1.1 = getelementptr [9 x [5 x [2 x %struct.S0]]]* undef, i32 0, i32 %l_74.0, i32 %tmp98, i32 0, i32 1, i32 %scevgep99.sum114 + store i8 0, i8* %arrayidx32.1.1, align 1 + %ins = or i64 undef, undef + br label %for.body22 + +for.inc44: ; preds = %for.body + %add46 = add i32 %l_74.0, 1 + br label %for.body +}