Skip to content

Commit d7fecf2

Browse files
committed
[InstCombine] allow some commutative matches for logical-and to select fold
This is obviously correct for real logic instructions, and it also works for the poison-safe variants that use selects: https://alive2.llvm.org/ce/z/wyHiwX This is motivated by the lack of 'xor' folding seen in issue llvm#58313. This more general fold should help reduce some of those patterns, but I'm not sure if this specific case does anything for that particular example.
1 parent f6fc3e2 commit d7fecf2

File tree

2 files changed

+10
-34
lines changed

2 files changed

+10
-34
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,12 +2852,12 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
28522852

28532853
// (C && A) || (!C && B) --> sel C, A, B
28542854
if (match(FalseVal, m_LogicalAnd(m_Not(m_Value(C)), m_Value(B))) &&
2855-
match(CondVal, m_LogicalAnd(m_Specific(C), m_Value(A))))
2855+
match(CondVal, m_c_LogicalAnd(m_Specific(C), m_Value(A))))
28562856
return SelectInst::Create(C, A, B);
28572857

28582858
// (!C && A) || (C && B) --> sel C, B, A
28592859
if (match(CondVal, m_LogicalAnd(m_Not(m_Value(C)), m_Value(A))) &&
2860-
match(FalseVal, m_LogicalAnd(m_Specific(C), m_Value(B))))
2860+
match(FalseVal, m_c_LogicalAnd(m_Specific(C), m_Value(B))))
28612861
return SelectInst::Create(C, B, A);
28622862
}
28632863
}

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

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,7 @@ define i1 @bools_logical_commute1_and1_and2(i1 %b, i1 %c) {
271271

272272
define <2 x i1> @bools_logical_commute2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {
273273
; CHECK-LABEL: @bools_logical_commute2(
274-
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true>
275-
; CHECK-NEXT: [[AND1:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[A:%.*]], <2 x i1> zeroinitializer
276-
; CHECK-NEXT: [[AND2:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[C]], <2 x i1> zeroinitializer
277-
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[AND1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[AND2]]
274+
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]
278275
; CHECK-NEXT: ret <2 x i1> [[OR]]
279276
;
280277
%not = xor <2 x i1> %c, <i1 -1, i1 -1>
@@ -286,10 +283,7 @@ define <2 x i1> @bools_logical_commute2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {
286283

287284
define <2 x i1> @bools_logical_commute2_and1(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {
288285
; CHECK-LABEL: @bools_logical_commute2_and1(
289-
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true>
290-
; CHECK-NEXT: [[AND1:%.*]] = and <2 x i1> [[NOT]], [[A:%.*]]
291-
; CHECK-NEXT: [[AND2:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[C]], <2 x i1> zeroinitializer
292-
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[AND1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[AND2]]
286+
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]
293287
; CHECK-NEXT: ret <2 x i1> [[OR]]
294288
;
295289
%not = xor <2 x i1> %c, <i1 -1, i1 -1>
@@ -301,10 +295,7 @@ define <2 x i1> @bools_logical_commute2_and1(<2 x i1> %a, <2 x i1> %b, <2 x i1>
301295

302296
define <2 x i1> @bools_logical_commute2_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {
303297
; CHECK-LABEL: @bools_logical_commute2_and2(
304-
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true>
305-
; CHECK-NEXT: [[AND1:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[A:%.*]], <2 x i1> zeroinitializer
306-
; CHECK-NEXT: [[AND2:%.*]] = and <2 x i1> [[B:%.*]], [[C]]
307-
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[AND1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[AND2]]
298+
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]
308299
; CHECK-NEXT: ret <2 x i1> [[OR]]
309300
;
310301
%not = xor <2 x i1> %c, <i1 -1, i1 -1>
@@ -316,10 +307,7 @@ define <2 x i1> @bools_logical_commute2_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1>
316307

317308
define <2 x i1> @bools_logical_commute2_and1_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {
318309
; CHECK-LABEL: @bools_logical_commute2_and1_and2(
319-
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true>
320-
; CHECK-NEXT: [[AND1:%.*]] = and <2 x i1> [[NOT]], [[A:%.*]]
321-
; CHECK-NEXT: [[AND2:%.*]] = and <2 x i1> [[B:%.*]], [[C]]
322-
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[AND1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[AND2]]
310+
; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]
323311
; CHECK-NEXT: ret <2 x i1> [[OR]]
324312
;
325313
%not = xor <2 x i1> %c, <i1 -1, i1 -1>
@@ -443,10 +431,7 @@ define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) {
443431

444432
define i1 @bools2_logical_commute1(i1 %a, i1 %b, i1 %c) {
445433
; CHECK-LABEL: @bools2_logical_commute1(
446-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
447-
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
448-
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[NOT]], i1 [[B:%.*]], i1 false
449-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
434+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
450435
; CHECK-NEXT: ret i1 [[OR]]
451436
;
452437
%not = xor i1 %c, -1
@@ -458,10 +443,7 @@ define i1 @bools2_logical_commute1(i1 %a, i1 %b, i1 %c) {
458443

459444
define i1 @bools2_logical_commute1_and1(i1 %a, i1 %b, i1 %c) {
460445
; CHECK-LABEL: @bools2_logical_commute1_and1(
461-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
462-
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[A:%.*]], [[C]]
463-
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[NOT]], i1 [[B:%.*]], i1 false
464-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
446+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
465447
; CHECK-NEXT: ret i1 [[OR]]
466448
;
467449
%not = xor i1 %c, -1
@@ -473,10 +455,7 @@ define i1 @bools2_logical_commute1_and1(i1 %a, i1 %b, i1 %c) {
473455

474456
define i1 @bools2_logical_commute1_and2(i1 %a, i1 %b, i1 %c) {
475457
; CHECK-LABEL: @bools2_logical_commute1_and2(
476-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
477-
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
478-
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[NOT]], [[B:%.*]]
479-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
458+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
480459
; CHECK-NEXT: ret i1 [[OR]]
481460
;
482461
%not = xor i1 %c, -1
@@ -488,10 +467,7 @@ define i1 @bools2_logical_commute1_and2(i1 %a, i1 %b, i1 %c) {
488467

489468
define i1 @bools2_logical_commute1_and1_and2(i1 %a, i1 %b, i1 %c) {
490469
; CHECK-LABEL: @bools2_logical_commute1_and1_and2(
491-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true
492-
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[A:%.*]], [[C]]
493-
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[NOT]], [[B:%.*]]
494-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
470+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
495471
; CHECK-NEXT: ret i1 [[OR]]
496472
;
497473
%not = xor i1 %c, -1

0 commit comments

Comments
 (0)