[llvm] r301625 - [EarlyCSE] Mark the condition of assume intrinsic as true
Max Kazantsev via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 27 23:25:39 PDT 2017
Author: mkazantsev
Date: Fri Apr 28 01:25:39 2017
New Revision: 301625
URL: http://llvm.org/viewvc/llvm-project?rev=301625&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp
llvm/trunk/test/Transforms/EarlyCSE/guards.ll
Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=301625&r1=301624&r2=301625&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Fri Apr 28 01:25:39 2017
@@ -635,10 +635,16 @@ bool EarlyCSE::processNode(DomTreeNode *
// Skip assume intrinsics, they don't really have side effects (although
// they're marked as such to ensure preservation of control dependencies),
- // and this pass will not disturb any of the assumption's control
- // dependencies.
+ // and this pass will not bother with its removal. However, we should mark
+ // its condition as true for all dominated blocks.
if (match(Inst, m_Intrinsic<Intrinsic::assume>())) {
- DEBUG(dbgs() << "EarlyCSE skipping assumption: " << *Inst << '\n');
+ auto *CondI =
+ dyn_cast<Instruction>(cast<CallInst>(Inst)->getArgOperand(0));
+ if (CondI && SimpleValue::canHandle(CondI)) {
+ DEBUG(dbgs() << "EarlyCSE considering assumption: " << *Inst << '\n');
+ AvailableValues.insert(CondI, ConstantInt::getTrue(BB->getContext()));
+ } else
+ DEBUG(dbgs() << "EarlyCSE skipping assumption: " << *Inst << '\n');
continue;
}
Modified: llvm/trunk/test/Transforms/EarlyCSE/guards.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/guards.ll?rev=301625&r1=301624&r2=301625&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/EarlyCSE/guards.ll (original)
+++ llvm/trunk/test/Transforms/EarlyCSE/guards.ll Fri Apr 28 01:25:39 2017
@@ -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
+}
More information about the llvm-commits
mailing list