diff options
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 20 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/call-guard.ll | 18 |
2 files changed, 24 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 56983dc6036..f088671c6d7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3255,16 +3255,24 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } case Intrinsic::experimental_guard: { - Value *IIOperand = II->getArgOperand(0); + // Is this guard followed by another guard? + Instruction *NextInst = II->getNextNode(); + Value *NextCond = nullptr; + if (match(NextInst, + m_Intrinsic<Intrinsic::experimental_guard>(m_Value(NextCond)))) { + Value *CurrCond = II->getArgOperand(0); - // Remove a guard if it is immediately followed by an identical guard. - if (match(II->getNextNode(), - m_Intrinsic<Intrinsic::experimental_guard>(m_Specific(IIOperand)))) - return eraseInstFromFunction(*II); + // Remove a guard that it is immediately preceeded by an identical guard. + if (CurrCond == NextCond) + return eraseInstFromFunction(*NextInst); + + // Otherwise canonicalize guard(a); guard(b) -> guard(a & b). + II->setArgOperand(0, Builder->CreateAnd(CurrCond, NextCond)); + return eraseInstFromFunction(*NextInst); + } break; } } - return visitCallSite(II); } diff --git a/llvm/test/Transforms/InstCombine/call-guard.ll b/llvm/test/Transforms/InstCombine/call-guard.ll index 18da465e606..9664467f914 100644 --- a/llvm/test/Transforms/InstCombine/call-guard.ll +++ b/llvm/test/Transforms/InstCombine/call-guard.ll @@ -2,8 +2,8 @@ declare void @llvm.experimental.guard(i1, ...) -define void @test_guard_adjacent(i1 %A) { -; CHECK-LABEL: @test_guard_adjacent( +define void @test_guard_adjacent_same_cond(i1 %A) { +; CHECK-LABEL: @test_guard_adjacent_same_cond( ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ] ; CHECK-NEXT: ret void call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] @@ -19,12 +19,14 @@ define void @test_guard_adjacent(i1 %A) { ret void } -define void @test_guard_adjacent_neg(i1 %A, i1 %B) { -; CHECK-LABEL: @test_guard_adjacent_neg( -; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ] -; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %B) [ "deopt"() ] +define void @test_guard_adjacent_diff_cond(i1 %A, i1 %B, i1 %C) { +; CHECK-LABEL: @test_guard_adjacent_diff_cond( +; CHECK-NEXT: %1 = and i1 %A, %B +; CHECK-NEXT: %2 = and i1 %1, %C +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %2, i32 123) [ "deopt"() ] ; CHECK-NEXT: ret void - call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] - call void(i1, ...) @llvm.experimental.guard( i1 %B )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[ "deopt"() ] ret void } |

