diff options
| author | Tim Northover <tnorthover@apple.com> | 2017-05-22 21:28:08 +0000 |
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2017-05-22 21:28:08 +0000 |
| commit | 997f5f10c6de8f0327225ff4e03582272094811a (patch) | |
| tree | 269bb12909c545959c8fbe668d8c5d487a21f727 /llvm/test/Transforms/EarlyCSE | |
| parent | f12ac5b77612c9dbdbbf7f34cfda4a96d5cdc732 (diff) | |
| download | bcm5719-llvm-997f5f10c6de8f0327225ff4e03582272094811a.tar.gz bcm5719-llvm-997f5f10c6de8f0327225ff4e03582272094811a.zip | |
InstructionSimplify: don't speculate about Constants changing.
When presented with an icmp/select pair, we can end up asking what would happen
if we replaced one constant with another in an instruction. This is a mistake,
while non-constant Values could become a constant, constants cannot change and
trying to do so can lead to completely invalid IR (a GEP referencing a
non-existant field in the original case).
llvm-svn: 303580
Diffstat (limited to 'llvm/test/Transforms/EarlyCSE')
| -rw-r--r-- | llvm/test/Transforms/EarlyCSE/const-speculation.ll | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/test/Transforms/EarlyCSE/const-speculation.ll b/llvm/test/Transforms/EarlyCSE/const-speculation.ll new file mode 100644 index 00000000000..5b7f2f5b698 --- /dev/null +++ b/llvm/test/Transforms/EarlyCSE/const-speculation.ll @@ -0,0 +1,39 @@ +; RUN: opt -early-cse -S %s | FileCheck %s + +%mystruct = type { i32 } + +; @var is global so that *every* GEP argument is Constant. +@var = external global %mystruct + +; Control flow is to make the dominance tree consider the final icmp before it +; gets to simplify the purely constant one (%tst). Since that icmp uses the +; select that gets considered next. Finally the select simplification looks at +; the %tst icmp and we don't want it to speculate about what happens if "i32 0" +; is actually "i32 1", broken universes are automatic UB. +; +; In this case doing the speculation would create an invalid GEP(@var, 0, 1) and +; crash. + +define i1 @test_constant_speculation() { +; CHECK-LABEL: define i1 @test_constant_speculation +entry: + br i1 undef, label %end, label %select + +select: +; CHECK: select: +; CHECK-NOT: icmp +; CHECK-NOT: getelementptr +; CHECK-NOT: select + + %tst = icmp eq i32 1, 0 + %elt = getelementptr %mystruct, %mystruct* @var, i64 0, i32 0 + %sel = select i1 %tst, i32* null, i32* %elt + br label %end + +end: +; CHECK: end: +; CHECK: %tmp = phi i32* [ null, %entry ], [ getelementptr inbounds (%mystruct, %mystruct* @var, i64 0, i32 0), %select ] + %tmp = phi i32* [null, %entry], [%sel, %select] + %res = icmp eq i32* %tmp, null + ret i1 %res +} |

