[llvm] r300075 - Teach SimplifyDemandedUseBits that adding or subtractings 0s from every bit below the highest demanded bit can be simplified

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 12 09:50:00 PDT 2017


Author: ctopper
Date: Wed Apr 12 11:49:59 2017
New Revision: 300075

URL: http://llvm.org/viewvc/llvm-project?rev=300075&view=rev
Log:
Teach SimplifyDemandedUseBits that adding or subtractings 0s from every bit below the highest demanded bit can be simplified

If we are adding/subtractings 0s below the highest demanded bit we can just use the other operand and remove the operation.

My primary motivation is observing that we can call ShrinkDemandedConstant for the add/sub and create a 0 constant, rather than removing the add completely. In the case I saw, we modified the constant on an add instruction to a 0, but the add is not put into the worklist. So we didn't revisit it until the next InstCombine iteration. This caused an IR modification to remove add and a subsequent iteration to be ran.

With this change we get bypass the add in the first iteration and prevent the second iteration from changing anything.

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


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
    llvm/trunk/test/Transforms/InstCombine/and2.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp?rev=300075&r1=300074&r2=300075&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp Wed Apr 12 11:49:59 2017
@@ -538,7 +538,7 @@ Value *InstCombiner::SimplifyDemandedUse
           SimplifyDemandedBits(I, 0, DemandedFromOps, LHSKnownZero, LHSKnownOne,
                                Depth + 1) ||
           ShrinkDemandedConstant(I, 1, DemandedFromOps) ||
-          SimplifyDemandedBits(I, 1, DemandedFromOps, LHSKnownZero, LHSKnownOne,
+          SimplifyDemandedBits(I, 1, DemandedFromOps, RHSKnownZero, RHSKnownOne,
                                Depth + 1)) {
         // Disable the nsw and nuw flags here: We can no longer guarantee that
         // we won't wrap after simplification. Removing the nsw/nuw flags is
@@ -548,6 +548,15 @@ Value *InstCombiner::SimplifyDemandedUse
         BinOP.setHasNoUnsignedWrap(false);
         return I;
       }
+
+      // If we are known to be adding/subtracting zeros to every bit below
+      // the highest demanded bit, we just return the other side.
+      if ((DemandedFromOps & RHSKnownZero) == DemandedFromOps)
+        return I->getOperand(0);
+      // We can't do this with the LHS for subtraction.
+      if (I->getOpcode() == Instruction::Add &&
+          (DemandedFromOps & LHSKnownZero) == DemandedFromOps)
+        return I->getOperand(1);
     }
 
     // Otherwise just hand the add/sub off to computeKnownBits to fill in

Modified: llvm/trunk/test/Transforms/InstCombine/and2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and2.ll?rev=300075&r1=300074&r2=300075&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/and2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/and2.ll Wed Apr 12 11:49:59 2017
@@ -122,12 +122,11 @@ define i64 @test10(i64 %x) {
   ret i64 %add
 }
 
-; The add in this test is unnecessary because the LSBs of the RHS are 0 and we only consume those bits.
+; The add in this test is unnecessary because the LSBs of the LHS are 0 and the 'and' only consumes bits from those LSBs. It doesn't matter what happens to the upper bits.
 define i32 @test11(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test11(
 ; CHECK-NEXT:    [[X:%.*]] = shl i32 [[A:%.*]], 8
-; CHECK-NEXT:    [[Y:%.*]] = add i32 [[X]], [[B:%.*]]
-; CHECK-NEXT:    [[Z:%.*]] = and i32 [[Y]], 128
+; CHECK-NEXT:    [[Z:%.*]] = and i32 [[B:%.*]], 128
 ; CHECK-NEXT:    [[W:%.*]] = mul i32 [[Z]], [[X]]
 ; CHECK-NEXT:    ret i32 [[W]]
 ;
@@ -138,12 +137,11 @@ define i32 @test11(i32 %a, i32 %b) {
   ret i32 %w
 }
 
-; The add in this test is unnecessary because the LSBs of the RHS are 0 and we only consume those bits.
+; The add in this test is unnecessary because the LSBs of the RHS are 0 and the 'and' only consumes bits from those LSBs. It doesn't matter what happens to the upper bits.
 define i32 @test12(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test12(
 ; CHECK-NEXT:    [[X:%.*]] = shl i32 [[A:%.*]], 8
-; CHECK-NEXT:    [[Y:%.*]] = add i32 [[X]], [[B:%.*]]
-; CHECK-NEXT:    [[Z:%.*]] = and i32 [[Y]], 128
+; CHECK-NEXT:    [[Z:%.*]] = and i32 [[B:%.*]], 128
 ; CHECK-NEXT:    [[W:%.*]] = mul i32 [[Z]], [[X]]
 ; CHECK-NEXT:    ret i32 [[W]]
 ;
@@ -154,12 +152,11 @@ define i32 @test12(i32 %a, i32 %b) {
   ret i32 %w
 }
 
-; The sub in this test is unnecessary because the LSBs of the RHS are 0 and we only consume those bits.
+; The sub in this test is unnecessary because the LSBs of the RHS are 0 and the 'and' only consumes bits from those LSBs. It doesn't matter what happens to the upper bits.
 define i32 @test13(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test13(
 ; CHECK-NEXT:    [[X:%.*]] = shl i32 [[A:%.*]], 8
-; CHECK-NEXT:    [[Y:%.*]] = sub i32 [[B:%.*]], [[X]]
-; CHECK-NEXT:    [[Z:%.*]] = and i32 [[Y]], 128
+; CHECK-NEXT:    [[Z:%.*]] = and i32 [[B:%.*]], 128
 ; CHECK-NEXT:    [[W:%.*]] = mul i32 [[Z]], [[X]]
 ; CHECK-NEXT:    ret i32 [[W]]
 ;
@@ -170,7 +167,7 @@ define i32 @test13(i32 %a, i32 %b) {
   ret i32 %w
 }
 
-; The sub in this test cannot be removed because we need to keep the negation of %b
+; The sub in this test cannot be removed because we need to keep the negation of %b. TODO: But we should be able to replace the LHS of it with a 0.
 define i32 @test14(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test14(
 ; CHECK-NEXT:    [[X:%.*]] = shl i32 [[A:%.*]], 8




More information about the llvm-commits mailing list