From d4cffcf07385bc92dd5b836646cad9204f1d043d Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 1 Sep 2014 21:20:14 +0000 Subject: [PATCH] SROA: Don't insert instructions before a PHI SROA may decide that it needs to insert a bitcast and would set it's insertion point before a PHI. This will create an invalid module right quick. Instead, choose the first insertion point in the basic block that holds our PHI. This fixes PR20822. Differential Revision: http://reviews.llvm.org/D5141 llvm-svn: 216891 --- llvm/lib/Transforms/Scalar/SROA.cpp | 5 ++- llvm/test/Transforms/SROA/phi-and-select.ll | 34 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index da5f14a7888a..32a61a0b9f27 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -2708,7 +2708,10 @@ private: // the old pointer, which necessarily must be in the right position to // dominate the PHI. IRBuilderTy PtrBuilder(IRB); - PtrBuilder.SetInsertPoint(OldPtr); + if (isa(OldPtr)) + PtrBuilder.SetInsertPoint(OldPtr->getParent()->getFirstInsertionPt()); + else + PtrBuilder.SetInsertPoint(OldPtr); PtrBuilder.SetCurrentDebugLocation(OldPtr->getDebugLoc()); Value *NewPtr = getNewAllocaSlicePtr(PtrBuilder, OldPtr->getType()); diff --git a/llvm/test/Transforms/SROA/phi-and-select.ll b/llvm/test/Transforms/SROA/phi-and-select.ll index 9948bb351072..f2870127352c 100644 --- a/llvm/test/Transforms/SROA/phi-and-select.ll +++ b/llvm/test/Transforms/SROA/phi-and-select.ll @@ -566,3 +566,37 @@ merge: %4 = load float* %3, align 4 ret float %4 } + +%struct.S = type { i32 } + +; Verifies we fixed PR20822. We have a foldable PHI feeding a speculatable PHI +; which requires the rewriting of the speculated PHI to handle insertion +; when the incoming pointer is itself from a PHI node. We would previously +; insert a bitcast instruction *before* a PHI, producing an invalid module; +; make sure we insert *after* the first non-PHI instruction. +define void @PR20822() { +; CHECK-LABEL: @PR20822( +entry: + %f = alloca %struct.S, align 4 +; CHECK: %[[alloca:.*]] = alloca + br i1 undef, label %if.end, label %for.cond + +for.cond: ; preds = %for.cond, %entry + br label %if.end + +if.end: ; preds = %for.cond, %entry + %f2 = phi %struct.S* [ %f, %entry ], [ %f, %for.cond ] +; CHECK: phi i32 +; CHECK: %[[cast:.*]] = bitcast i32* %[[alloca]] to %struct.S* + phi i32 [ undef, %entry ], [ undef, %for.cond ] + br i1 undef, label %if.then5, label %if.then2 + +if.then2: ; preds = %if.end + br label %if.then5 + +if.then5: ; preds = %if.then2, %if.end + %f1 = phi %struct.S* [ undef, %if.then2 ], [ %f2, %if.end ] +; CHECK: phi {{.*}} %[[cast]] + store %struct.S undef, %struct.S* %f1, align 4 + ret void +}