[llvm] c65e651 - [InstSimplify] fix logic fold of 'or' for vectors
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 5 06:57:28 PST 2021
Author: Sanjay Patel
Date: 2021-12-05T09:57:07-05:00
New Revision: c65e651e6025dd04b69ea144a94962a5b4716681
URL: https://github.com/llvm/llvm-project/commit/c65e651e6025dd04b69ea144a94962a5b4716681
DIFF: https://github.com/llvm/llvm-project/commit/c65e651e6025dd04b69ea144a94962a5b4716681.diff
LOG: [InstSimplify] fix logic fold of 'or' for vectors
Reduce code duplication for commutative pattern matching
and fix a miscompile.
We can't safely propagate an undef element in this transform:
https://alive2.llvm.org/ce/z/s5xy55
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 2f018469871d3..8894a2c1b052e 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2198,6 +2198,18 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
Value *A, *B;
+ // (A ^ B) | (A | B) --> A | B
+ // (A ^ B) | (B | A) --> B | A
+ if (match(X, m_Xor(m_Value(A), m_Value(B))) &&
+ match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
+ return Y;
+
+ // ~(A ^ B) | (A | B) --> -1
+ // ~(A ^ B) | (B | A) --> -1
+ if (match(X, m_Not(m_Xor(m_Value(A), m_Value(B)))) &&
+ match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
+ return ConstantInt::getAllOnesValue(Ty);
+
// (A & ~B) | (A ^ B) --> A ^ B
// (~B & A) | (A ^ B) --> A ^ B
// (A & ~B) | (B ^ A) --> B ^ A
@@ -2214,18 +2226,6 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
return X;
- // (A ^ B) | (A | B) --> A | B
- // (A ^ B) | (B | A) --> B | A
- if (match(X, m_Xor(m_Value(A), m_Value(B))) &&
- match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
- return Y;
-
- // ~(A ^ B) | (A | B) --> -1
- // ~(A ^ B) | (B | A) --> -1
- if (match(X, m_Not(m_Xor(m_Value(A), m_Value(B)))) &&
- match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
- return ConstantInt::getAllOnesValue(Ty);
-
// (~A | B) | (A ^ B) --> -1
// (~A | B) | (B ^ A) --> -1
// (B | ~A) | (A ^ B) --> -1
@@ -2234,6 +2234,17 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
return ConstantInt::getAllOnesValue(Ty);
+ // (~A & B) | ~(A | B) --> ~A
+ // (~A & B) | ~(B | A) --> ~A
+ // (B & ~A) | ~(A | B) --> ~A
+ // (B & ~A) | ~(B | A) --> ~A
+ Value *NotA;
+ if (match(X,
+ m_c_And(m_CombineAnd(m_Value(NotA), m_NotForbidUndef(m_Value(A))),
+ m_Value(B))) &&
+ match(Y, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
+ return NotA;
+
return nullptr;
}
@@ -2267,27 +2278,6 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Or))
return V;
- Value *A, *B, *NotA;
-
- // (~A & B) | ~(A | B) --> ~A
- // (~A & B) | ~(B | A) --> ~A
- // (B & ~A) | ~(A | B) --> ~A
- // (B & ~A) | ~(B | A) --> ~A
- if (match(Op0, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
- m_Value(B))) &&
- match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
- return NotA;
-
- // Commute the 'or' operands.
- // ~(A | B) | (~A & B) --> ~A
- // ~(B | A) | (~A & B) --> ~A
- // ~(A | B) | (B & ~A) --> ~A
- // ~(B | A) | (B & ~A) --> ~A
- if (match(Op1, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
- m_Value(B))) &&
- match(Op0, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
- return NotA;
-
// Rotated -1 is still -1:
// (-1 << X) | (-1 >> (C - X)) --> -1
// (-1 >> X) | (-1 << (C - X)) --> -1
@@ -2343,6 +2333,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
}
// (A & C1)|(B & C2)
+ Value *A, *B;
const APInt *C1, *C2;
if (match(Op0, m_And(m_Value(A), m_APInt(C1))) &&
match(Op1, m_And(m_Value(B), m_APInt(C2)))) {
diff --git a/llvm/test/Transforms/InstSimplify/or.ll b/llvm/test/Transforms/InstSimplify/or.ll
index 6591dcedf7ec4..1f56c15ee102b 100644
--- a/llvm/test/Transforms/InstSimplify/or.ll
+++ b/llvm/test/Transforms/InstSimplify/or.ll
@@ -454,12 +454,16 @@ define <2 x i4> @and_or_not_or_commute7(<2 x i4> %A, <2 x i4> %B) {
ret <2 x i4> %r
}
-; FIXME: It is not safe to propagate an undef element from the 'not' op.
+; negative test - It is not safe to propagate an undef element from the 'not' op.
define <2 x i4> @and_or_not_or_commute7_undef_elt(<2 x i4> %A, <2 x i4> %B) {
; CHECK-LABEL: @and_or_not_or_commute7_undef_elt(
; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i4> [[A:%.*]], <i4 undef, i4 -1>
-; CHECK-NEXT: ret <2 x i4> [[NOTA]]
+; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[B:%.*]], [[NOTA]]
+; CHECK-NEXT: [[OR:%.*]] = or <2 x i4> [[B]], [[A]]
+; CHECK-NEXT: [[NOTAB:%.*]] = xor <2 x i4> [[OR]], <i4 -1, i4 -1>
+; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[NOTAB]], [[AND]]
+; CHECK-NEXT: ret <2 x i4> [[R]]
;
%nota = xor <2 x i4> %A, <i4 undef, i4 -1>
%and = and <2 x i4> %B, %nota
More information about the llvm-commits
mailing list