mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[InstCombine] adjust branch on logical-and fold
The transform was just added with:
115d2f69a5
...but as noted in post-commit feedback, it was
confusingly coded. Now, we create the final
expected canonicalized form directly and put
an extra use check on the match, so we should
not ever end up with more instructions.
This commit is contained in:
@@ -3187,13 +3187,17 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
|
||||
return replaceOperand(BI, 0, X);
|
||||
}
|
||||
|
||||
// br (X && !Y), T, F --> br ((X && Y) || !X), F, T
|
||||
// Canonicalize logical-and-with-invert as logical-or-with-invert.
|
||||
// This is done by inverting the condition and swapping successors:
|
||||
// br (X && !Y), T, F --> br !(X && !Y), F, T --> br (!X || Y), F, T
|
||||
Value *Y;
|
||||
if (isa<SelectInst>(Cond) &&
|
||||
match(Cond, m_OneUse(m_LogicalAnd(m_Value(X), m_Not(m_Value(Y)))))) {
|
||||
Value *AndOr = Builder.CreateSelect(X, Y, Builder.getTrue());
|
||||
match(Cond,
|
||||
m_OneUse(m_LogicalAnd(m_Value(X), m_OneUse(m_Not(m_Value(Y))))))) {
|
||||
Value *NotX = Builder.CreateNot(X, "not." + X->getName());
|
||||
Value *Or = Builder.CreateLogicalOr(NotX, Y);
|
||||
BI.swapSuccessors();
|
||||
return replaceOperand(BI, 0, AndOr);
|
||||
return replaceOperand(BI, 0, Or);
|
||||
}
|
||||
|
||||
// If the condition is irrelevant, remove the use so that other
|
||||
|
||||
@@ -189,14 +189,15 @@ f:
|
||||
ret i32 3
|
||||
}
|
||||
|
||||
; negative test
|
||||
|
||||
define i32 @logical_and_not_use1(i1 %x, i1 %y) {
|
||||
; CHECK-LABEL: @logical_and_not_use1(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
|
||||
; CHECK-NEXT: call void @use(i1 [[NOTY]])
|
||||
; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y]]
|
||||
; CHECK-NEXT: br i1 [[TMP0]], label [[F:%.*]], label [[T:%.*]]
|
||||
; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
|
||||
; CHECK-NEXT: br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]
|
||||
; CHECK: t:
|
||||
; CHECK-NEXT: ret i32 42
|
||||
; CHECK: f:
|
||||
|
||||
Reference in New Issue
Block a user