diff options
| author | Max Kazantsev <max.kazantsev@azul.com> | 2017-04-28 06:25:39 +0000 |
|---|---|---|
| committer | Max Kazantsev <max.kazantsev@azul.com> | 2017-04-28 06:25:39 +0000 |
| commit | 531db9a5046a6bd06c2f0dfadcc933ad070068fb (patch) | |
| tree | ab7cc857a15cca86d160736ddc91d0b8b6ca2527 /llvm/test/Transforms/EarlyCSE | |
| parent | 287942ae8278f81ee81ca248c88f5bf5f70f5147 (diff) | |
| download | bcm5719-llvm-531db9a5046a6bd06c2f0dfadcc933ad070068fb.tar.gz bcm5719-llvm-531db9a5046a6bd06c2f0dfadcc933ad070068fb.zip | |
[EarlyCSE] Mark the condition of assume intrinsic as true
EarlyCSE should not just ignore assumes. It should use the fact that its condition is true for all dominated instructions.
Reviewers: sanjoy, reames, apilipenko, anna, skatkov
Reviewed By: reames, sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D32482
llvm-svn: 301625
Diffstat (limited to 'llvm/test/Transforms/EarlyCSE')
| -rw-r--r-- | llvm/test/Transforms/EarlyCSE/guards.ll | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/llvm/test/Transforms/EarlyCSE/guards.ll b/llvm/test/Transforms/EarlyCSE/guards.ll index 5d1e3835c9a..de43264db6f 100644 --- a/llvm/test/Transforms/EarlyCSE/guards.ll +++ b/llvm/test/Transforms/EarlyCSE/guards.ll @@ -3,6 +3,8 @@ declare void @llvm.experimental.guard(i1,...) +declare void @llvm.assume(i1) + define i32 @test0(i32* %ptr, i1 %cond) { ; We can do store to load forwarding over a guard, since it does not ; clobber memory @@ -336,3 +338,191 @@ if.false: merge: ret void } + +define void @test12(i32 %a, i32 %b) { +; Check that the assume marks its condition as being true (and thus allows to +; eliminate the dominated guards). + +; CHECK-LABEL: @test12( +; CHECK-NEXT: %cmp = icmp eq i32 %a, %b +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: ret void + + %cmp = icmp eq i32 %a, %b + call void @llvm.assume(i1 %cmp) + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + ret void +} + +define void @test13(i32 %a, i32 %b, i32* %ptr) { +; Check that we deal correctly with stores when removing guards due to assume. + +; CHECK-LABEL: @test13( +; CHECK-NEXT: %cmp = icmp eq i32 %a, %b +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: store i32 400, i32* %ptr +; CHECK-NEXT: ret void + + %cmp = icmp eq i32 %a, %b + call void @llvm.assume(i1 %cmp) + store i32 100, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 200, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 300, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 400, i32* %ptr + ret void +} + +define void @test14(i32 %a, i32 %b, i1 %c, i32* %ptr) { +; Similar to test13, but with more control flow. +; TODO: Can we get rid of the store in the end of entry given that it is +; post-dominated by other stores? + +; CHECK-LABEL: @test14( +; CHECK: entry: +; CHECK-NEXT: %cmp = icmp eq i32 %a, %b +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: store i32 400, i32* %ptr +; CHECK-NEXT: br i1 %c, label %if.true, label %if.false +; CHECK: if.true: +; CHECK-NEXT: store i32 500, i32* %ptr +; CHECK-NEXT: br label %merge +; CHECK: if.false: +; CHECK-NEXT: store i32 600, i32* %ptr +; CHECK-NEXT: br label %merge +; CHECK: merge: +; CHECK-NEXT: ret void + +entry: + %cmp = icmp eq i32 %a, %b + call void @llvm.assume(i1 %cmp) + store i32 100, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 200, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 300, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 400, i32* %ptr + br i1 %c, label %if.true, label %if.false + +if.true: + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 500, i32* %ptr + br label %merge + +if.false: + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 600, i32* %ptr + br label %merge + +merge: + ret void +} + +define void @test15(i32 %a, i32 %b, i1 %c, i32* %ptr) { +; Make sure that non-dominating assumes do not cause guards removal. + +; CHECK-LABEL: @test15( +; CHECK: entry: +; CHECK-NEXT: %cmp = icmp eq i32 %a, %b +; CHECK-NEXT: br i1 %c, label %if.true, label %if.false +; CHECK: if.true: +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: store i32 100, i32* %ptr +; CHECK-NEXT: br label %merge +; CHECK: if.false: +; CHECK-NEXT: store i32 200, i32* %ptr +; CHECK-NEXT: br label %merge +; CHECK: merge: +; CHECK-NEXT: store i32 300, i32* %ptr +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] +; CHECK-NEXT: store i32 400, i32* %ptr +; CHECK-NEXT: ret void + +entry: + %cmp = icmp eq i32 %a, %b + br i1 %c, label %if.true, label %if.false + +if.true: + call void @llvm.assume(i1 %cmp) + store i32 100, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + br label %merge + +if.false: + store i32 200, i32* %ptr + br label %merge + +merge: + store i32 300, i32* %ptr + call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] + store i32 400, i32* %ptr + ret void +} + +define void @test16(i32 %a, i32 %b) { +; Check that we don't bother to do anything with assumes even if we know the +; condition being true. + +; CHECK-LABEL: @test16( +; CHECK-NEXT: %cmp = icmp eq i32 %a, %b +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: ret void + + %cmp = icmp eq i32 %a, %b + call void @llvm.assume(i1 %cmp) + call void @llvm.assume(i1 %cmp) + ret void +} + +define void @test17(i32 %a, i32 %b, i1 %c, i32* %ptr) { +; Check that we don't bother to do anything with assumes even if we know the +; condition being true or false (includes come control flow). + +; CHECK-LABEL: @test17( +; CHECK: entry: +; CHECK-NEXT: %cmp = icmp eq i32 %a, %b +; CHECK-NEXT: br i1 %c, label %if.true, label %if.false +; CHECK: if.true: +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: br label %merge +; CHECK: if.false: +; CHECK-NEXT: call void @llvm.assume(i1 %cmp) +; CHECK-NEXT: br label %merge +; CHECK: merge: +; CHECK-NEXT: ret void + +entry: + %cmp = icmp eq i32 %a, %b + br i1 %c, label %if.true, label %if.false + +if.true: + call void @llvm.assume(i1 %cmp) + br label %merge + +if.false: + call void @llvm.assume(i1 %cmp) + br label %merge + +merge: + ret void +} + +define void @test18(i1 %c) { +; Check that we don't bother to do anything with assumes even if we know the +; condition being true and not being an instruction. + +; CHECK-LABEL: @test18( +; CHECK-NEXT: call void @llvm.assume(i1 %c) +; CHECK-NEXT: call void @llvm.assume(i1 %c) +; CHECK-NEXT: ret void + + call void @llvm.assume(i1 %c) + call void @llvm.assume(i1 %c) + ret void +} |

