mirror of
https://github.com/RPCSX/llvm.git
synced 2025-05-13 10:56:01 +00:00
[InstCombine] Allow InstCombine to merge adjacent guards
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293778 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
299e3e8880
commit
387f151ad9
@ -3255,16 +3255,24 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Intrinsic::experimental_guard: {
|
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.
|
// Remove a guard that it is immediately preceeded by an identical guard.
|
||||||
if (match(II->getNextNode(),
|
if (CurrCond == NextCond)
|
||||||
m_Intrinsic<Intrinsic::experimental_guard>(m_Specific(IIOperand))))
|
return eraseInstFromFunction(*NextInst);
|
||||||
return eraseInstFromFunction(*II);
|
|
||||||
|
// Otherwise canonicalize guard(a); guard(b) -> guard(a & b).
|
||||||
|
II->setArgOperand(0, Builder->CreateAnd(CurrCond, NextCond));
|
||||||
|
return eraseInstFromFunction(*NextInst);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return visitCallSite(II);
|
return visitCallSite(II);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
declare void @llvm.experimental.guard(i1, ...)
|
declare void @llvm.experimental.guard(i1, ...)
|
||||||
|
|
||||||
define void @test_guard_adjacent(i1 %A) {
|
define void @test_guard_adjacent_same_cond(i1 %A) {
|
||||||
; CHECK-LABEL: @test_guard_adjacent(
|
; CHECK-LABEL: @test_guard_adjacent_same_cond(
|
||||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ]
|
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
|
call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
|
||||||
@ -19,12 +19,14 @@ define void @test_guard_adjacent(i1 %A) {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_guard_adjacent_neg(i1 %A, i1 %B) {
|
define void @test_guard_adjacent_diff_cond(i1 %A, i1 %B, i1 %C) {
|
||||||
; CHECK-LABEL: @test_guard_adjacent_neg(
|
; CHECK-LABEL: @test_guard_adjacent_diff_cond(
|
||||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ]
|
; CHECK-NEXT: %1 = and i1 %A, %B
|
||||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %B) [ "deopt"() ]
|
; CHECK-NEXT: %2 = and i1 %1, %C
|
||||||
|
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %2, i32 123) [ "deopt"() ]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
|
call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
|
||||||
call void(i1, ...) @llvm.experimental.guard( i1 %B )[ "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
|
ret void
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user