Skip to content

Commit 3073074

Browse files
committed
[InstCombine] allow more commutative matches for logical-and to select fold
When the common value is part of either select condition, this is safe to reduce. Otherwise, it is not poison-safe (with the select form of the pattern): https://alive2.llvm.org/ce/z/FxQTzB This is another patch motivated by issue llvm#58313.
1 parent 7dd2f4b commit 3073074

File tree

2 files changed

+12
-16
lines changed

2 files changed

+12
-16
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,11 +2851,19 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
28512851
Value *C;
28522852

28532853
// (C && A) || (!C && B) --> sel C, A, B
2854+
// (A && C) || (!C && B) --> sel C, A, B
28542855
if (match(FalseVal, m_LogicalAnd(m_Not(m_Value(C)), m_Value(B))) &&
28552856
match(CondVal, m_c_LogicalAnd(m_Specific(C), m_Value(A))))
28562857
return SelectInst::Create(C, A, B);
28572858

2859+
// (C && A) || (B && !C) --> sel C, A, B
2860+
// TODO: (A && C) || (B && !C) is safe to transform with real 'and' ops.
2861+
if (match(FalseVal, m_LogicalAnd(m_Value(B), m_Not(m_Value(C)))) &&
2862+
match(CondVal, m_LogicalAnd(m_Specific(C), m_Value(A))))
2863+
return SelectInst::Create(C, A, B);
2864+
28582865
// (!C && A) || (C && B) --> sel C, B, A
2866+
// (!C && A) || (B && C) --> sel C, B, A
28592867
if (match(CondVal, m_LogicalAnd(m_Not(m_Value(C)), m_Value(A))) &&
28602868
match(FalseVal, m_c_LogicalAnd(m_Specific(C), m_Value(B))))
28612869
return SelectInst::Create(C, B, A);

llvm/test/Transforms/InstCombine/select-safe-transforms.ll

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,7 @@ define i1 @bools2_logical_commute1_and1_and2(i1 %a, i1 %b, i1 %c) {
479479

480480
define i1 @bools2_logical_commute2(i1 %a, i1 %b, i1 %c) {
481481
; CHECK-LABEL: @bools2_logical_commute2(
482-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
483-
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C]], i1 [[A:%.*]], i1 false
484-
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[B:%.*]], i1 [[NOT]], i1 false
485-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
482+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
486483
; CHECK-NEXT: ret i1 [[OR]]
487484
;
488485
%not = xor i1 %c, -1
@@ -494,10 +491,7 @@ define i1 @bools2_logical_commute2(i1 %a, i1 %b, i1 %c) {
494491

495492
define i1 @bools2_logical_commute2_and1(i1 %a, i1 %b, i1 %c) {
496493
; CHECK-LABEL: @bools2_logical_commute2_and1(
497-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
498-
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C]], [[A:%.*]]
499-
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[B:%.*]], i1 [[NOT]], i1 false
500-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
494+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
501495
; CHECK-NEXT: ret i1 [[OR]]
502496
;
503497
%not = xor i1 %c, -1
@@ -510,10 +504,7 @@ define i1 @bools2_logical_commute2_and1(i1 %a, i1 %b, i1 %c) {
510504
define i1 @bools2_logical_commute2_and2(i1 %a, i1 %c) {
511505
; CHECK-LABEL: @bools2_logical_commute2_and2(
512506
; CHECK-NEXT: [[B:%.*]] = call i1 @gen1()
513-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
514-
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C]], i1 [[A:%.*]], i1 false
515-
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[B]], [[NOT]]
516-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
507+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]]
517508
; CHECK-NEXT: ret i1 [[OR]]
518509
;
519510
%b = call i1 @gen1()
@@ -527,10 +518,7 @@ define i1 @bools2_logical_commute2_and2(i1 %a, i1 %c) {
527518
define i1 @bools2_logical_commute2_and1_and2(i1 %a, i1 %c) {
528519
; CHECK-LABEL: @bools2_logical_commute2_and1_and2(
529520
; CHECK-NEXT: [[B:%.*]] = call i1 @gen1()
530-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
531-
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C]], [[A:%.*]]
532-
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[B]], [[NOT]]
533-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
521+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]]
534522
; CHECK-NEXT: ret i1 [[OR]]
535523
;
536524
%b = call i1 @gen1()

0 commit comments

Comments
 (0)