[llvm] r341559 - [InstCombine] add xor+not folds
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 6 09:23:40 PDT 2018
Author: spatel
Date: Thu Sep 6 09:23:40 2018
New Revision: 341559
URL: http://llvm.org/viewvc/llvm-project?rev=341559&view=rev
Log:
[InstCombine] add xor+not folds
This fold is needed to avoid a regression when we try
to recommit rL300977.
We can't see the most basic win currently because
demanded bits changes the patterns:
https://rise4fun.com/Alive/plpp
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/trunk/test/Transforms/InstCombine/xor.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=341559&r1=341558&r2=341559&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Thu Sep 6 09:23:40 2018
@@ -2702,6 +2702,22 @@ Instruction *InstCombiner::visitXor(Bina
return BinaryOperator::CreateSub(ConstantExpr::getNeg(AddOne(C)), X);
}
+ // Use DeMorgan and reassociation to eliminate a 'not' op.
+ Constant *C1;
+ if (match(Op1, m_Constant(C1))) {
+ Constant *C2;
+ if (match(Op0, m_OneUse(m_Or(m_Not(m_Value(X)), m_Constant(C2))))) {
+ // (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1
+ Value *And = Builder.CreateAnd(X, ConstantExpr::getNot(C2));
+ return BinaryOperator::CreateXor(And, ConstantExpr::getNot(C1));
+ }
+ if (match(Op0, m_OneUse(m_And(m_Not(m_Value(X)), m_Constant(C2))))) {
+ // (~X & C2) ^ C1 --> ((X | ~C2) ^ -1) ^ C1 --> (X | ~C2) ^ ~C1
+ Value *Or = Builder.CreateOr(X, ConstantExpr::getNot(C2));
+ return BinaryOperator::CreateXor(Or, ConstantExpr::getNot(C1));
+ }
+ }
+
// not (cmp A, B) = !cmp A, B
CmpInst::Predicate Pred;
if (match(&I, m_Not(m_OneUse(m_Cmp(Pred, m_Value(), m_Value()))))) {
Modified: llvm/trunk/test/Transforms/InstCombine/xor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/xor.ll?rev=341559&r1=341558&r2=341559&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/xor.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/xor.ll Thu Sep 6 09:23:40 2018
@@ -587,7 +587,7 @@ define i32 @and_xor_extra_use(i32 %a, i3
ret i32 %r
}
-; TODO: (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1
+; (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1
; The extra use (store) is here because the simpler case
; may be transformed using demanded bits.
@@ -595,8 +595,8 @@ define i8 @xor_or_not(i8 %x, i8* %p) {
; CHECK-LABEL: @xor_or_not(
; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
; CHECK-NEXT: store i8 [[NX]], i8* [[P:%.*]], align 1
-; CHECK-NEXT: [[OR:%.*]] = or i8 [[NX]], 7
-; CHECK-NEXT: [[R:%.*]] = xor i8 [[OR]], 12
+; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -8
+; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -13
; CHECK-NEXT: ret i8 [[R]]
;
%nx = xor i8 %x, -1
@@ -623,7 +623,7 @@ define i8 @xor_or_not_uses(i8 %x, i8* %p
ret i8 %r
}
-; TODO: (~X & C2) ^ C1 --> ((X | ~C2) ^ -1) ^ C1 --> (X | ~C2) ^ ~C1
+; (~X & C2) ^ C1 --> ((X | ~C2) ^ -1) ^ C1 --> (X | ~C2) ^ ~C1
; The extra use (store) is here because the simpler case
; may be transformed using demanded bits.
@@ -631,8 +631,8 @@ define i8 @xor_and_not(i8 %x, i8* %p) {
; CHECK-LABEL: @xor_and_not(
; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
; CHECK-NEXT: store i8 [[NX]], i8* [[P:%.*]], align 1
-; CHECK-NEXT: [[AND:%.*]] = and i8 [[NX]], 42
-; CHECK-NEXT: [[R:%.*]] = xor i8 [[AND]], 31
+; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], -43
+; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -32
; CHECK-NEXT: ret i8 [[R]]
;
%nx = xor i8 %x, -1
More information about the llvm-commits
mailing list