From 9b3b2862478e5baec967d479a2d00731758e1bb8 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 24 Jul 2013 09:47:28 +0000 Subject: Fix PR16687 where we were incorrectly promoting an alloca that had pending speculation for a phi node. The problem here is that we were using growth of the specluation set as an indicator of whether speculation would occur, and if the phi node is already in the set we don't see it grow. This is a symptom of the fact that this signal is a total hack. Unfortunately, I couldn't really come up with a non-hacky way of signaling that promotion remains valid *after* speculation occurs, such that we only speculate when all else looks good for promotion. In the end, I went with at least a much more explicit approach of doing the work of queuing inside the phi and select processing and setting a preposterously named flag to convey that we're in the special state of requiring speculating before promotion. Thanks to Richard Trieu and Nick Lewycky for the excellent work reducing a testcase for this from a pretty giant, nasty assert in a big application. =] The testcase was excellent. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187029 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Transforms/SROA/phi-and-select.ll | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'test/Transforms') diff --git a/test/Transforms/SROA/phi-and-select.ll b/test/Transforms/SROA/phi-and-select.ll index 86375780b6..9f2b191778 100644 --- a/test/Transforms/SROA/phi-and-select.ll +++ b/test/Transforms/SROA/phi-and-select.ll @@ -427,3 +427,40 @@ if.end: ret i64 %result ; CHECK-NEXT: ret i64 %[[result]] } + +define float @PR16687(i64 %x, i1 %flag) { +; CHECK-LABEL: @PR16687( +; Check that even when we try to speculate the same phi twice (in two slices) +; on an otherwise promotable construct, we don't get ahead of ourselves and try +; to promote one of the slices prior to speculating it. + +entry: + %a = alloca i64, align 8 + store i64 %x, i64* %a + br i1 %flag, label %then, label %else +; CHECK-NOT: alloca +; CHECK-NOT: store +; CHECK: %[[lo:.*]] = trunc i64 %x to i32 +; CHECK: %[[shift:.*]] = lshr i64 %x, 32 +; CHECK: %[[hi:.*]] = trunc i64 %[[shift]] to i32 + +then: + %a.f = bitcast i64* %a to float* + br label %end +; CHECK: %[[lo_cast:.*]] = bitcast i32 %[[lo]] to float + +else: + %a.raw = bitcast i64* %a to i8* + %a.raw.4 = getelementptr i8* %a.raw, i64 4 + %a.raw.4.f = bitcast i8* %a.raw.4 to float* + br label %end +; CHECK: %[[hi_cast:.*]] = bitcast i32 %[[hi]] to float + +end: + %a.phi.f = phi float* [ %a.f, %then ], [ %a.raw.4.f, %else ] + %f = load float* %a.phi.f + ret float %f +; CHECK: %[[phi:.*]] = phi float [ %[[lo_cast]], %then ], [ %[[hi_cast]], %else ] +; CHECK-NOT: load +; CHECK: ret float %[[phi]] +} -- cgit v1.2.3