[llvm] 9300b13 - Revert "[InstCombine] (~(a | b) & c) | ~(c | (a ^ b)) -> ~((a | b) & (c | (b ^ a)))"

Stanislav Mekhanoshin via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 24 11:14:59 PST 2021


Author: Stanislav Mekhanoshin
Date: 2021-11-24T11:14:52-08:00
New Revision: 9300b133c80dfc1a15135f9fb9c5afaf8a6805f8

URL: https://github.com/llvm/llvm-project/commit/9300b133c80dfc1a15135f9fb9c5afaf8a6805f8
DIFF: https://github.com/llvm/llvm-project/commit/9300b133c80dfc1a15135f9fb9c5afaf8a6805f8.diff

LOG: Revert "[InstCombine] (~(a | b) & c) | ~(c | (a ^ b)) -> ~((a | b) & (c | (b ^ a)))"

This reverts commit c407769f5e6c81d56de0b251aed5750a16a7651c.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 5af453c972596..c994009ac374b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1727,18 +1727,16 @@ static Instruction *foldComplexAndOrPatterns(BinaryOperator &I,
       (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
 
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-  Value *A, *B, *C, *X, *Y, *Z;
+  Value *A, *B, *C;
 
   // (~(A | B) & C) | ... --> ...
   // (~(A & B) | C) & ... --> ...
   // TODO: One use checks are conservative. We just need to check that a total
   //       number of multiple used values does not exceed reduction
   //       in operations.
-  if (match(Op0,
-            m_c_BinOp(FlippedOpcode,
-                      m_CombineAnd(m_Value(X), m_Not(m_BinOp(Opcode, m_Value(A),
-                                                             m_Value(B)))),
-                      m_Value(C)))) {
+  if (match(Op0, m_c_BinOp(FlippedOpcode,
+                           m_Not(m_BinOp(Opcode, m_Value(A), m_Value(B))),
+                           m_Value(C)))) {
     // (~(A | B) & C) | (~(A | C) & B) --> (B ^ C) & ~A
     // (~(A & B) | C) & (~(A & C) | B) --> ~((B ^ C) & A)
     if (match(Op1,
@@ -1778,28 +1776,6 @@ static Instruction *foldComplexAndOrPatterns(BinaryOperator &I,
                        m_c_BinOp(Opcode, m_Specific(B), m_Specific(C)))))))
       return BinaryOperator::CreateNot(Builder.CreateBinOp(
           Opcode, Builder.CreateBinOp(FlippedOpcode, A, C), B));
-
-    // (~(A | B) & C) | ~(C | (A ^ B)) --> ~((A | B) & (C | (A ^ B)))
-    // (~(A & B) | C) & ~(C & (A ^ B)) --> (A ^ B ^ C) | ~(A | C)
-    // Note: X = ~(A | B) or ~(A & B)
-    if (Op0->hasOneUse() &&
-        match(Op1, m_OneUse(m_Not(m_CombineAnd(
-                       m_Value(Z),
-                       m_c_BinOp(Opcode, m_Specific(C),
-                                 m_CombineAnd(m_Value(Y),
-                                              m_c_Xor(m_Specific(A),
-                                                      m_Specific(B))))))))) {
-      Value *AndOr = cast<BinaryOperator>(X)->getOperand(0);
-      if (Opcode == Instruction::Or) {
-        // Z = (C | (A ^ B)
-        return BinaryOperator::CreateNot(Builder.CreateAnd(AndOr, Z));
-      } else if (X->hasOneUse() && AndOr->hasOneUse() && Z->hasOneUse()) {
-        // Y = A ^ B
-        Value *Xor = Builder.CreateXor(Y, C);
-        return BinaryOperator::CreateOr(
-            Xor, Builder.CreateNot(Builder.CreateOr(A, C)));
-      }
-    }
   }
 
   return nullptr;

diff  --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll
index a2baeea194107..adeb333b88c9e 100644
--- a/llvm/test/Transforms/InstCombine/and-xor-or.ll
+++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll
@@ -2018,15 +2018,17 @@ define i32 @and_or_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
   ret i32 %and3
 }
 
-; (a & ~(b | c)) | ~(a | (b ^ c)) --> ~((b | c) & (a | (b ^ c)))
+; (a & ~(b | c)) | ~(a | (b ^ c)) --> (~a & b & c) | ~(b | c)
 
 define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
   %or1 = or i32 %b, %c
@@ -2042,10 +2044,12 @@ define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) {
 define i32 @and_not_or_or_not_or_xor_commute1(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute1(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
   %or1 = or i32 %c, %b
@@ -2062,10 +2066,12 @@ define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute2(
 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
@@ -2082,10 +2088,12 @@ define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) {
 define i32 @and_not_or_or_not_or_xor_commute3(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute3(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C]], [[B]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
   %or1 = or i32 %b, %c
@@ -2102,10 +2110,12 @@ define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute4(
 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[XOR1]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
@@ -2122,10 +2132,12 @@ define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) {
 define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute5(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
   %or1 = or i32 %b, %c
@@ -2141,10 +2153,12 @@ define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) {
 define i32 @and_not_or_or_not_or_xor_use1(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use1(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
@@ -2163,10 +2177,11 @@ define i32 @and_not_or_or_not_or_xor_use2(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use2(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
@@ -2207,10 +2222,12 @@ define i32 @and_not_or_or_not_or_xor_use3(i32 %a, i32 %b, i32 %c) {
 define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use4(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    call void @use(i32 [[XOR1]])
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
@@ -2228,10 +2245,12 @@ define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) {
 define i32 @and_not_or_or_not_or_xor_use5(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use5(
 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
-; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
-; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
+; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
 ; CHECK-NEXT:    ret i32 [[OR3]]
 ;
@@ -2273,11 +2292,12 @@ define i32 @and_not_or_or_not_or_xor_use6(i32 %a, i32 %b, i32 %c) {
 
 define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor(
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;
   %and1 = and i32 %b, %c
@@ -2292,11 +2312,12 @@ define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) {
 
 define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute1(
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[A]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;
   %and1 = and i32 %c, %b
@@ -2312,11 +2333,12 @@ define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) {
 define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute2(
 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[A]], [[B]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;
   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
@@ -2332,11 +2354,12 @@ define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) {
 
 define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute3(
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;
   %and1 = and i32 %b, %c
@@ -2352,11 +2375,12 @@ define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) {
 define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute4(
 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[A]], [[B]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[XOR1]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;
   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
@@ -2372,11 +2396,12 @@ define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) {
 
 define i32 @or_not_and_and_not_and_xor_commute5(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute5(
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;
   %and1 = and i32 %b, %c
@@ -2457,11 +2482,12 @@ define i32 @or_not_and_and_not_and_xor_use3(i32 %a, i32 %b, i32 %c) {
 
 define i32 @or_not_and_and_not_and_xor_use4(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use4(
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XOR1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], -1
-; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
+; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
 ; CHECK-NEXT:    call void @use(i32 [[XOR1]])
 ; CHECK-NEXT:    ret i32 [[AND3]]
 ;


        


More information about the llvm-commits mailing list