diff options
| author | Mehrnoosh Heidarpour <mehrnoosh.heidarpour@huawei.com> | 2021-11-15 18:54:07 -0500 |
|---|---|---|
| committer | Muhammad Asif Manzoor <muhammad.asif.manzoor1@huawei.com> | 2021-11-15 18:55:04 -0500 |
| commit | 62c51a72f9e7540fb58bba7e116a4b411ab18bef (patch) | |
| tree | 2188c9d813303edd54f57197fb4703e139c79d7d | |
| parent | 4c3d916c4bd2a392101c74dd270bd1e6a4fec15b (diff) | |
| download | llvm-62c51a72f9e7540fb58bba7e116a4b411ab18bef.zip llvm-62c51a72f9e7540fb58bba7e116a4b411ab18bef.tar.gz llvm-62c51a72f9e7540fb58bba7e116a4b411ab18bef.tar.bz2 | |
[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
Reviewed By: rampitec
Differential Revision: https://reviews.llvm.org/D113861
| -rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstSimplify/or.ll | 36 |
2 files changed, 43 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index d406583..864eeea 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2265,6 +2265,19 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B))))) return Op0; + // (A | B) | (A ^ B) --> A | B + // (B | A) | (A ^ B) --> B | A + if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && + match(Op0, m_c_Or(m_Specific(A), m_Specific(B)))) + return Op0; + + // Commute the outer 'or' operands. + // (A ^ B) | (A | B) --> A | B + // (A ^ B) | (B | A) --> B | A + if (match(Op0, m_Xor(m_Value(A), m_Value(B))) && + match(Op1, m_c_Or(m_Specific(A), m_Specific(B)))) + return Op1; + // (~A & B) | ~(A | B) --> ~A // (~A & B) | ~(B | A) --> ~A // (B & ~A) | ~(A | B) --> ~A diff --git a/llvm/test/Transforms/InstSimplify/or.ll b/llvm/test/Transforms/InstSimplify/or.ll index 038112a..d11aedf 100644 --- a/llvm/test/Transforms/InstSimplify/or.ll +++ b/llvm/test/Transforms/InstSimplify/or.ll @@ -451,9 +451,7 @@ define i32 @and_or_not_or8(i32 %A, i32 %B) { define i69 @or_or_xor(i69 %A, i69 %B) { ; CHECK-LABEL: @or_or_xor( ; CHECK-NEXT: [[I1:%.*]] = or i69 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[I2:%.*]] = xor i69 [[A]], [[B]] -; CHECK-NEXT: [[I3:%.*]] = or i69 [[I1]], [[I2]] -; CHECK-NEXT: ret i69 [[I3]] +; CHECK-NEXT: ret i69 [[I1]] ; %i1 = or i69 %A, %B %i2 = xor i69 %A, %B @@ -461,12 +459,25 @@ define i69 @or_or_xor(i69 %A, i69 %B) { ret i69 %i3 } +; (B | A) | (A ^ B) --> B | A + +define i8 @or_or_xor_inner_or_commuted(i8 %A, i8 %B) { +; CHECK-LABEL: @or_or_xor_inner_or_commuted( +; CHECK-NEXT: [[I1:%.*]] = or i8 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: ret i8 [[I1]] +; + %i1 = or i8 %B, %A + %i2 = xor i8 %A, %B + %i3 = or i8 %i1, %i2 + ret i8 %i3 +} + +; (A ^ B) | (A | B) --> A | B + define <4 x i4> @or_or_xor_commuted(<4 x i4> %A, <4 x i4> %B) { ; CHECK-LABEL: @or_or_xor_commuted( ; CHECK-NEXT: [[I1:%.*]] = or <4 x i4> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[I2:%.*]] = xor <4 x i4> [[A]], [[B]] -; CHECK-NEXT: [[I3:%.*]] = or <4 x i4> [[I2]], [[I1]] -; CHECK-NEXT: ret <4 x i4> [[I3]] +; CHECK-NEXT: ret <4 x i4> [[I1]] ; %i1 = or <4 x i4> %A, %B %i2 = xor <4 x i4> %A, %B @@ -474,6 +485,19 @@ define <4 x i4> @or_or_xor_commuted(<4 x i4> %A, <4 x i4> %B) { ret <4 x i4> %i3 } +; (A ^ B) | (B | A) --> B | A + +define i4 @or_or_xor_inner_or_outer_or_commuted(i4 %A, i4 %B) { +; CHECK-LABEL: @or_or_xor_inner_or_outer_or_commuted( +; CHECK-NEXT: [[I1:%.*]] = or i4 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: ret i4 [[I1]] +; + %i1 = or i4 %B, %A + %i2 = xor i4 %A, %B + %i3 = or i4 %i2, %i1 + ret i4 %i3 +} + define i32 @shifted_all_ones(i32 %shamt) { ; CHECK-LABEL: @shifted_all_ones( ; CHECK-NEXT: ret i32 -1 |
