Author: Dávid Bolvanský Date: 2021-01-16T15:43:34+01:00 New Revision: a4e2a5145a29af678139f33e94ab3df0fc973e59
URL: https://github.com/llvm/llvm-project/commit/a4e2a5145a29af678139f33e94ab3df0fc973e59 DIFF: https://github.com/llvm/llvm-project/commit/a4e2a5145a29af678139f33e94ab3df0fc973e59.diff LOG: [InstSimplify] Add (~A & B) | ~(A | B) --> ~A Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/test/Transforms/InstSimplify/or.ll Removed: ################################################################################ diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 2ae4228495e3..6266e922f8c9 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2262,6 +2262,12 @@ 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 + // (~A & B) | ~(B | A) --> ~A + if (match(Op0, m_And(m_Not(m_Value(A)), m_Value(B))) && + match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B))))) + return cast<BinaryOperator>(Op0)->getOperand(0); + if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false)) return V; diff --git a/llvm/test/Transforms/InstSimplify/or.ll b/llvm/test/Transforms/InstSimplify/or.ll index e8284264c612..7e7361d12395 100644 --- a/llvm/test/Transforms/InstSimplify/or.ll +++ b/llvm/test/Transforms/InstSimplify/or.ll @@ -301,3 +301,97 @@ define i32 @poison(i32 %x) { %v = or i32 %x, poison ret i32 %v } + +declare void @use(i32) + +define i32 @and_or_not_or(i32 %A, i32 %B) { +; CHECK-LABEL: @and_or_not_or( +; CHECK-NEXT: [[I:%.*]] = xor i32 [[B:%.*]], -1 +; CHECK-NEXT: ret i32 [[I]] +; + %i = xor i32 %B, -1 + %i2 = and i32 %i, %A + %i3 = or i32 %B, %A + %i4 = xor i32 %i3, -1 + %i5 = or i32 %i2, %i4 + ret i32 %i5 +} + +define i32 @and_or_not_or2(i32 %A, i32 %B) { +; CHECK-LABEL: @and_or_not_or2( +; CHECK-NEXT: [[I:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: ret i32 [[I]] +; + %i = xor i32 %A, -1 + %i2 = and i32 %i, %B + %i3 = or i32 %B, %A + %i4 = xor i32 %i3, -1 + %i5 = or i32 %i2, %i4 + ret i32 %i5 +} + +define <4 x i32> @and_or_not_or3_vec(<4 x i32> %A, <4 x i32> %B) { +; CHECK-LABEL: @and_or_not_or3_vec( +; CHECK-NEXT: [[I:%.*]] = xor <4 x i32> [[A:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1> +; CHECK-NEXT: ret <4 x i32> [[I]] +; + %i = xor <4 x i32> %A, <i32 -1, i32 -1, i32 -1, i32 -1> + %i2 = and <4 x i32> %i, %B + %i3 = or <4 x i32> %B, %A + %i4 = xor <4 x i32> %i3, <i32 -1, i32 -1, i32 -1, i32 -1> + %i5 = or <4 x i32> %i2, %i4 + ret <4 x i32> %i5 +} + +define i32 @and_or_not_or4_use(i32 %A, i32 %B) { +; CHECK-LABEL: @and_or_not_or4_use( +; CHECK-NEXT: [[I:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], [[B:%.*]] +; CHECK-NEXT: tail call void @use(i32 [[I2]]) +; CHECK-NEXT: ret i32 [[I]] +; + %i = xor i32 %A, -1 + %i2 = and i32 %i, %B + tail call void @use(i32 %i2) + %i3 = or i32 %B, %A + %i4 = xor i32 %i3, -1 + %i5 = or i32 %i2, %i4 + ret i32 %i5 +} + +define i32 @and_or_not_or4_use2(i32 %A, i32 %B) { +; CHECK-LABEL: @and_or_not_or4_use2( +; CHECK-NEXT: [[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[I2:%.*]] = xor i32 [[I]], -1 +; CHECK-NEXT: tail call void @use(i32 [[I2]]) +; CHECK-NEXT: [[I3:%.*]] = xor i32 [[A]], -1 +; CHECK-NEXT: ret i32 [[I3]] +; + %i = or i32 %B, %A + %i2 = xor i32 %i, -1 + tail call void @use(i32 %i2) + %i3 = xor i32 %A, -1 + %i4 = and i32 %i3, %B + %i5 = or i32 %i4, %i2 + ret i32 %i5 +} + +define i32 @and_or_not_or4_use3(i32 %A, i32 %B) { +; CHECK-LABEL: @and_or_not_or4_use3( +; CHECK-NEXT: [[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[I2:%.*]] = xor i32 [[I]], -1 +; CHECK-NEXT: tail call void @use(i32 [[I2]]) +; CHECK-NEXT: [[I3:%.*]] = xor i32 [[A]], -1 +; CHECK-NEXT: [[I4:%.*]] = and i32 [[I3]], [[B]] +; CHECK-NEXT: tail call void @use(i32 [[I4]]) +; CHECK-NEXT: ret i32 [[I3]] +; + %i = or i32 %B, %A + %i2 = xor i32 %i, -1 + tail call void @use(i32 %i2) + %i3 = xor i32 %A, -1 + %i4 = and i32 %i3, %B + tail call void @use(i32 %i4) + %i5 = or i32 %i4, %i2 + ret i32 %i5 +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits