diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2013-07-24 09:47:28 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2013-07-24 09:47:28 +0000 |
commit | 9b3b2862478e5baec967d479a2d00731758e1bb8 (patch) | |
tree | 9a340c11fd6fb4ca03f48bce8c37e059e112dc57 /test/Transforms | |
parent | ef540b194f8ae1ff994ccdcb10dcc36f60e419c2 (diff) | |
download | llvm-9b3b2862478e5baec967d479a2d00731758e1bb8.tar.gz llvm-9b3b2862478e5baec967d479a2d00731758e1bb8.tar.bz2 llvm-9b3b2862478e5baec967d479a2d00731758e1bb8.tar.xz |
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
Diffstat (limited to 'test/Transforms')
-rw-r--r-- | test/Transforms/SROA/phi-and-select.ll | 37 |
1 files changed, 37 insertions, 0 deletions
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]] +} |