// Change br (not X), label True, label False to: br X, label False, True
Value *Cond = BI.getCondition();
- Value *X = nullptr;
+ Value *X;
if (match(Cond, m_Not(m_Value(X))) && !isa<Constant>(X)) {
// Swap Destinations and condition...
BI.swapSuccessors();
return replaceOperand(BI, 0, X);
}
+ // br (X && !Y), T, F --> br ((X && Y) || !X), 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());
+ BI.swapSuccessors();
+ return replaceOperand(BI, 0, AndOr);
+ }
+
// If the condition is irrelevant, remove the use so that other
// transforms on the condition become more effective.
if (!isa<ConstantInt>(Cond) && BI.getSuccessor(0) == BI.getSuccessor(1))
ret i1 %merge.cond.2
}
-; if (x && !y) ret 42; ret 3
+; if (x && !y) ret 42; ret 3 --> if (!x || y) ret 3; ret 42
define i32 @logical_and_not(i1 %x, i1 %y) {
; CHECK-LABEL: @logical_and_not(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
-; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
-; CHECK-NEXT: br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]
+; 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: t:
; CHECK-NEXT: ret i32 42
; CHECK: f:
ret i32 3
}
-; if (x && y || !x) ret 3; ret 42
+; if (x && y || !x) ret 3; ret 42 --> if (!x || y) ret 3; ret 42
define i32 @logical_and_or(i1 %x, i1 %y) {
; CHECK-LABEL: @logical_and_or(
define i1 @PR58313(i1 %lhs, i1 %rhs) {
; CHECK-LABEL: @PR58313(
; CHECK-NEXT: andandend:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[RHS:%.*]], true
-; CHECK-NEXT: [[ANDANDVAL:%.*]] = select i1 [[LHS:%.*]], i1 [[TMP0]], i1 false
-; CHECK-NEXT: br i1 [[ANDANDVAL]], label [[OROREND:%.*]], label [[OROR:%.*]]
-; CHECK: oror:
-; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[LHS]], true
-; CHECK-NEXT: [[ANDANDVAL3:%.*]] = select i1 [[TMP1]], i1 [[RHS]], i1 false
-; CHECK-NEXT: br label [[OROREND]]
-; CHECK: ororend:
-; CHECK-NEXT: [[ORORVAL:%.*]] = phi i1 [ true, [[ANDANDEND:%.*]] ], [ [[ANDANDVAL3]], [[OROR]] ]
-; CHECK-NEXT: ret i1 [[ORORVAL]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = xor i1 [[LHS:%.*]], [[RHS:%.*]]
+; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
;
andandend:
%0 = xor i1 %rhs, true