diff options
Diffstat (limited to 'test/Transforms/EarlyCSE/const-speculation.ll')
-rw-r--r-- | test/Transforms/EarlyCSE/const-speculation.ll | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/test/Transforms/EarlyCSE/const-speculation.ll b/test/Transforms/EarlyCSE/const-speculation.ll new file mode 100644 index 000000000000..5b7f2f5b6982 --- /dev/null +++ b/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 +} |