From 7b92d4ef0c6972ed4f45324025bb90ff4bf1602e Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 8 Dec 2014 08:53:47 +0000 Subject: [PATCH] Merging r216891: ------------------------------------------------------------------------ r216891 | majnemer | 2014-09-01 14:20:14 -0700 (Mon, 01 Sep 2014) | 12 lines 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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223639 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SROA.cpp | 5 +- test/Transforms/SROA/phi-and-select.ll | 99 ++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 8c7f253290b..f902eb23cbc 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2697,7 +2697,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/test/Transforms/SROA/phi-and-select.ll b/test/Transforms/SROA/phi-and-select.ll index 8d82964dcbd..f2870127352 100644 --- a/test/Transforms/SROA/phi-and-select.ll +++ b/test/Transforms/SROA/phi-and-select.ll @@ -501,3 +501,102 @@ end: ; CHECK-NOT: load ; CHECK: ret float %[[phi]] } + +; Verifies we fixed PR20425. We should be able to promote all alloca's to +; registers in this test. +; +; %0 = slice +; %1 = slice +; %2 = phi(%0, %1) // == slice +define float @simplify_phi_nodes_that_equal_slice(i1 %cond, float* %temp) { +; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice( +entry: + %arr = alloca [4 x float], align 4 +; CHECK-NOT: alloca + br i1 %cond, label %then, label %else + +then: + %0 = getelementptr inbounds [4 x float]* %arr, i64 0, i64 3 + store float 1.000000e+00, float* %0, align 4 + br label %merge + +else: + %1 = getelementptr inbounds [4 x float]* %arr, i64 0, i64 3 + store float 2.000000e+00, float* %1, align 4 + br label %merge + +merge: + %2 = phi float* [ %0, %then ], [ %1, %else ] + store float 0.000000e+00, float* %temp, align 4 + %3 = load float* %2, align 4 + ret float %3 +} + +; A slightly complicated example for PR20425. +; +; %0 = slice +; %1 = phi(%0) // == slice +; %2 = slice +; %3 = phi(%1, %2) // == slice +define float @simplify_phi_nodes_that_equal_slice_2(i1 %cond, float* %temp) { +; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice_2( +entry: + %arr = alloca [4 x float], align 4 +; CHECK-NOT: alloca + br i1 %cond, label %then, label %else + +then: + %0 = getelementptr inbounds [4 x float]* %arr, i64 0, i64 3 + store float 1.000000e+00, float* %0, align 4 + br label %then2 + +then2: + %1 = phi float* [ %0, %then ] + store float 2.000000e+00, float* %1, align 4 + br label %merge + +else: + %2 = getelementptr inbounds [4 x float]* %arr, i64 0, i64 3 + store float 3.000000e+00, float* %2, align 4 + br label %merge + +merge: + %3 = phi float* [ %1, %then2 ], [ %2, %else ] + store float 0.000000e+00, float* %temp, align 4 + %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 +}