Skip to content

Commit 193c40e

Browse files
committed
[InstSimplify] Fold A|B | (A^B) --> A|B
This patch adds the following fold opportunity: A|B | (A^B) --> A|B that is reported here : https://bugs.llvm.org/show_bug.cgi?id=52479 https://alive2.llvm.org/ce/z/33-My- Test cases with base results are added in D113860 (authored by MehrHeidar, committed by rampitec). Differential Revision: https://reviews.llvm.org/D113861
1 parent 1c3ef9e commit 193c40e

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,6 +2265,19 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
22652265
match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
22662266
return Op0;
22672267

2268+
// (A | B) | (A ^ B) --> A | B
2269+
// (B | A) | (A ^ B) --> B | A
2270+
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
2271+
match(Op0, m_c_Or(m_Specific(A), m_Specific(B))))
2272+
return Op0;
2273+
2274+
// Commute the outer 'or' operands.
2275+
// (A ^ B) | (A | B) --> A | B
2276+
// (A ^ B) | (B | A) --> B | A
2277+
if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
2278+
match(Op1, m_c_Or(m_Specific(A), m_Specific(B))))
2279+
return Op1;
2280+
22682281
// (~A & B) | ~(A | B) --> ~A
22692282
// (~A & B) | ~(B | A) --> ~A
22702283
// (B & ~A) | ~(A | B) --> ~A

llvm/test/Transforms/InstSimplify/or.ll

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -451,29 +451,53 @@ define i32 @and_or_not_or8(i32 %A, i32 %B) {
451451
define i69 @or_or_xor(i69 %A, i69 %B) {
452452
; CHECK-LABEL: @or_or_xor(
453453
; CHECK-NEXT: [[I1:%.*]] = or i69 [[A:%.*]], [[B:%.*]]
454-
; CHECK-NEXT: [[I2:%.*]] = xor i69 [[A]], [[B]]
455-
; CHECK-NEXT: [[I3:%.*]] = or i69 [[I1]], [[I2]]
456-
; CHECK-NEXT: ret i69 [[I3]]
454+
; CHECK-NEXT: ret i69 [[I1]]
457455
;
458456
%i1 = or i69 %A, %B
459457
%i2 = xor i69 %A, %B
460458
%i3 = or i69 %i1, %i2
461459
ret i69 %i3
462460
}
463461

462+
; (B | A) | (A ^ B) --> B | A
463+
464+
define i8 @or_or_xor_inner_or_commuted(i8 %A, i8 %B) {
465+
; CHECK-LABEL: @or_or_xor_inner_or_commuted(
466+
; CHECK-NEXT: [[I1:%.*]] = or i8 [[B:%.*]], [[A:%.*]]
467+
; CHECK-NEXT: ret i8 [[I1]]
468+
;
469+
%i1 = or i8 %B, %A
470+
%i2 = xor i8 %A, %B
471+
%i3 = or i8 %i1, %i2
472+
ret i8 %i3
473+
}
474+
475+
; (A ^ B) | (A | B) --> A | B
476+
464477
define <4 x i4> @or_or_xor_commuted(<4 x i4> %A, <4 x i4> %B) {
465478
; CHECK-LABEL: @or_or_xor_commuted(
466479
; CHECK-NEXT: [[I1:%.*]] = or <4 x i4> [[A:%.*]], [[B:%.*]]
467-
; CHECK-NEXT: [[I2:%.*]] = xor <4 x i4> [[A]], [[B]]
468-
; CHECK-NEXT: [[I3:%.*]] = or <4 x i4> [[I2]], [[I1]]
469-
; CHECK-NEXT: ret <4 x i4> [[I3]]
480+
; CHECK-NEXT: ret <4 x i4> [[I1]]
470481
;
471482
%i1 = or <4 x i4> %A, %B
472483
%i2 = xor <4 x i4> %A, %B
473484
%i3 = or <4 x i4> %i2, %i1
474485
ret <4 x i4> %i3
475486
}
476487

488+
; (A ^ B) | (B | A) --> B | A
489+
490+
define i4 @or_or_xor_inner_or_outer_or_commuted(i4 %A, i4 %B) {
491+
; CHECK-LABEL: @or_or_xor_inner_or_outer_or_commuted(
492+
; CHECK-NEXT: [[I1:%.*]] = or i4 [[B:%.*]], [[A:%.*]]
493+
; CHECK-NEXT: ret i4 [[I1]]
494+
;
495+
%i1 = or i4 %B, %A
496+
%i2 = xor i4 %A, %B
497+
%i3 = or i4 %i2, %i1
498+
ret i4 %i3
499+
}
500+
477501
define i32 @shifted_all_ones(i32 %shamt) {
478502
; CHECK-LABEL: @shifted_all_ones(
479503
; CHECK-NEXT: ret i32 -1

0 commit comments

Comments
 (0)