[llvm] 53e92b4 - [InstCombine] (~A & B) ^ A -> A | B

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 17 09:47:04 PDT 2020


Author: Sanjay Patel
Date: 2020-10-17T12:20:18-04:00
New Revision: 53e92b4c0efc95c8d9471f44829c86b6c9240ef4

URL: https://github.com/llvm/llvm-project/commit/53e92b4c0efc95c8d9471f44829c86b6c9240ef4
DIFF: https://github.com/llvm/llvm-project/commit/53e92b4c0efc95c8d9471f44829c86b6c9240ef4.diff

LOG: [InstCombine] (~A & B) ^ A -> A | B

Differential Revision: https://reviews.llvm.org/D86395

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/xor.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 1b83de2c3150..b9b73a46189f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3335,6 +3335,10 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
       match(Op1, m_Not(m_Specific(A))))
     return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
 
+  // (~A & B) ^ A --> A | B -- There are 4 commuted variants.
+  if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
+    return BinaryOperator::CreateOr(A, B);
+
   // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
   // TODO: Loosen one-use restriction if common operand is a constant.
   Value *D;

diff  --git a/llvm/test/Transforms/InstCombine/xor.ll b/llvm/test/Transforms/InstCombine/xor.ll
index c37983829fbb..569ca46145eb 100644
--- a/llvm/test/Transforms/InstCombine/xor.ll
+++ b/llvm/test/Transforms/InstCombine/xor.ll
@@ -1176,9 +1176,7 @@ define i8 @not_ashr_wrong_const(i8 %x) {
 
 define <2 x i32> @xor_andn_commute1(<2 x i32> %a, <2 x i32> %b) {
 ; CHECK-LABEL: @xor_andn_commute1(
-; CHECK-NEXT:    [[NOTA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 -1, i32 -1>
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[NOTA]], [[B:%.*]]
-; CHECK-NEXT:    [[Z:%.*]] = xor <2 x i32> [[R]], [[A]]
+; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret <2 x i32> [[Z]]
 ;
   %nota = xor <2 x i32> %a, <i32 -1, i32 -1>
@@ -1192,9 +1190,7 @@ define <2 x i32> @xor_andn_commute1(<2 x i32> %a, <2 x i32> %b) {
 define i33 @xor_andn_commute2(i33 %a, i33 %pb) {
 ; CHECK-LABEL: @xor_andn_commute2(
 ; CHECK-NEXT:    [[B:%.*]] = udiv i33 42, [[PB:%.*]]
-; CHECK-NEXT:    [[NOTA:%.*]] = xor i33 [[A:%.*]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i33 [[B]], [[NOTA]]
-; CHECK-NEXT:    [[Z:%.*]] = xor i33 [[R]], [[A]]
+; CHECK-NEXT:    [[Z:%.*]] = or i33 [[B]], [[A:%.*]]
 ; CHECK-NEXT:    ret i33 [[Z]]
 ;
   %b = udiv i33 42, %pb ; thwart complexity-based canonicalization
@@ -1209,9 +1205,7 @@ define i33 @xor_andn_commute2(i33 %a, i33 %pb) {
 define i32 @xor_andn_commute3(i32 %pa, i32 %b) {
 ; CHECK-LABEL: @xor_andn_commute3(
 ; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA:%.*]]
-; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[NOTA]], [[B:%.*]]
-; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[A]], [[R]]
+; CHECK-NEXT:    [[Z:%.*]] = or i32 [[A]], [[B:%.*]]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ;
   %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
@@ -1227,9 +1221,7 @@ define i32 @xor_andn_commute4(i32 %pa, i32 %pb) {
 ; CHECK-LABEL: @xor_andn_commute4(
 ; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA:%.*]]
 ; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[PB:%.*]]
-; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[NOTA]]
-; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[A]], [[R]]
+; CHECK-NEXT:    [[Z:%.*]] = or i32 [[A]], [[B]]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ;
   %a = udiv i32 42, %pa ; thwart complexity-based canonicalization


        


More information about the llvm-commits mailing list