[llvm] r301924 - revert r301923 : [InstCombine] don't use DeMorgan's Law on integer constants

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue May 2 07:48:24 PDT 2017


Author: spatel
Date: Tue May  2 09:48:23 2017
New Revision: 301924

URL: http://llvm.org/viewvc/llvm-project?rev=301924&view=rev
Log:
revert r301923 : [InstCombine] don't use DeMorgan's Law on integer constants

There's a clang test that is wrongly using -O1 and failing after this commit.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/test/Transforms/InstCombine/assume2.ll
    llvm/trunk/test/Transforms/InstCombine/demorgan.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=301924&r1=301923&r2=301924&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Tue May  2 09:48:23 2017
@@ -2433,32 +2433,29 @@ Instruction *InstCombiner::visitXor(Bina
   if (Value *V = SimplifyBSwap(I))
     return replaceInstUsesWith(I, V);
 
-  // Apply DeMorgan's Law for 'nand' / 'nor' logic with an inverted operand.
-  Value *X, *Y;
-
-  // We must eliminate the and/or (one-use) for these transforms to not increase
-  // the instruction count.
-  // ~(~X & Y) --> (X | ~Y)
-  // ~(Y & ~X) --> (X | ~Y)
-  if (match(&I, m_Not(m_OneUse(m_c_And(m_Not(m_Value(X)), m_Value(Y)))))) {
-    Value *NotY = Builder->CreateNot(Y, Y->getName() + ".not");
-    return BinaryOperator::CreateOr(X, NotY);
-  }
-  // ~(~X | Y) --> (X & ~Y)
-  // ~(Y | ~X) --> (X & ~Y)
-  if (match(&I, m_Not(m_OneUse(m_c_Or(m_Not(m_Value(X)), m_Value(Y)))))) {
-    Value *NotY = Builder->CreateNot(Y, Y->getName() + ".not");
-    return BinaryOperator::CreateAnd(X, NotY);
-  }
-
   // Is this a 'not' (~) fed by a binary operator?
   BinaryOperator *NotOp;
   if (match(&I, m_Not(m_BinOp(NotOp)))) {
     if (NotOp->getOpcode() == Instruction::And ||
         NotOp->getOpcode() == Instruction::Or) {
-      // Apply DeMorgan's Law when inverts are free:
-      // ~(X & Y) --> (~X | ~Y)
-      // ~(X | Y) --> (~X & ~Y)
+      // We must eliminate the and/or for this transform to not increase the
+      // instruction count.
+      if (NotOp->hasOneUse()) {
+        // ~(~X & Y) --> (X | ~Y) - De Morgan's Law
+        // ~(~X | Y) === (X & ~Y) - De Morgan's Law
+        if (dyn_castNotVal(NotOp->getOperand(1)))
+          NotOp->swapOperands();
+        if (Value *Op0NotVal = dyn_castNotVal(NotOp->getOperand(0))) {
+          Value *NotY = Builder->CreateNot(
+              NotOp->getOperand(1), NotOp->getOperand(1)->getName() + ".not");
+          if (NotOp->getOpcode() == Instruction::And)
+            return BinaryOperator::CreateOr(Op0NotVal, NotY);
+          return BinaryOperator::CreateAnd(Op0NotVal, NotY);
+        }
+      }
+
+      // ~(X & Y) --> (~X | ~Y) - De Morgan's Law
+      // ~(X | Y) === (~X & ~Y) - De Morgan's Law
       if (IsFreeToInvert(NotOp->getOperand(0),
                          NotOp->getOperand(0)->hasOneUse()) &&
           IsFreeToInvert(NotOp->getOperand(1),

Modified: llvm/trunk/test/Transforms/InstCombine/assume2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/assume2.ll?rev=301924&r1=301923&r2=301924&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/assume2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/assume2.ll Tue May  2 09:48:23 2017
@@ -21,8 +21,8 @@ define i32 @test1(i32 %a) #0 {
 
 define i32 @test2(i32 %a) #0 {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 15
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 10
+; CHECK-NEXT:    [[A_NOT:%.*]] = or i32 [[A:%.*]], -16
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A_NOT]], -6
 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
 ; CHECK-NEXT:    ret i32 2
 ;
@@ -50,8 +50,8 @@ define i32 @test3(i32 %a) #0 {
 
 define i32 @test4(i32 %a) #0 {
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT:    [[V:%.*]] = or i32 [[A:%.*]], -16
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V]], -6
+; CHECK-NEXT:    [[A_NOT:%.*]] = and i32 [[A:%.*]], 15
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A_NOT]], 10
 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
 ; CHECK-NEXT:    ret i32 2
 ;

Modified: llvm/trunk/test/Transforms/InstCombine/demorgan.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/demorgan.ll?rev=301924&r1=301923&r2=301924&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/demorgan.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/demorgan.ll Tue May  2 09:48:23 2017
@@ -367,12 +367,12 @@ define i8 @demorgan_nor_use2bc(i8 %A, i8
   ret i8 %r2
 }
 
-; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
+; FIXME: Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
 
 define i32 @demorganize_constant1(i32 %a) {
 ; CHECK-LABEL: @demorganize_constant1(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 %a, 15
-; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[AND]], -1
+; CHECK-NEXT:    [[A_NOT:%.*]] = or i32 %a, -16
+; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[A_NOT]], 15
 ; CHECK-NEXT:    ret i32 [[AND1]]
 ;
   %and = and i32 %a, 15
@@ -380,12 +380,12 @@ define i32 @demorganize_constant1(i32 %a
   ret i32 %and1
 }
 
-; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
+; FIXME: Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
 
 define i32 @demorganize_constant2(i32 %a) {
 ; CHECK-LABEL: @demorganize_constant2(
-; CHECK-NEXT:    [[AND:%.*]] = or i32 %a, 15
-; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[AND]], -1
+; CHECK-NEXT:    [[A_NOT:%.*]] = and i32 %a, -16
+; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[A_NOT]], -16
 ; CHECK-NEXT:    ret i32 [[AND1]]
 ;
   %and = or i32 %a, 15




More information about the llvm-commits mailing list