Skip to content

Commit

Permalink
[InstCombine] Allow InstCombine to merge adjacent guards
Browse files Browse the repository at this point in the history
Summary:
If there are two adjacent guards with different conditions, we can
remove one of them and include its condition into the condition of
another one. This patch allows InstCombine to merge them by the
following pattern:

    guard(a); guard(b) -> guard(a & b).

Reviewers: reames, apilipenko, igor-laevsky, anna, sanjoy

Reviewed By: sanjoy

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D29378

llvm-svn: 293778
  • Loading branch information
sanjoy committed Feb 1, 2017
1 parent ca931ef commit e0e5795
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
20 changes: 14 additions & 6 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Expand Up @@ -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);
}

Expand Down
18 changes: 10 additions & 8 deletions llvm/test/Transforms/InstCombine/call-guard.ll
Expand Up @@ -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"() ]
Expand All @@ -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
}

0 comments on commit e0e5795

Please sign in to comment.