]> granicus.if.org Git - llvm/commitdiff
[InstCombine] Fix a weakness in canEvaluateZExtd around 'and' instructions
authorCraig Topper <craig.topper@intel.com>
Mon, 21 Aug 2017 16:04:11 +0000 (16:04 +0000)
committerCraig Topper <craig.topper@intel.com>
Mon, 21 Aug 2017 16:04:11 +0000 (16:04 +0000)
Summary:
If the bitsToClear from the LHS of an 'and' comes back non-zero, but all of those bits are known zero on the RHS, we can reset bitsToClear.

Without this, the 'or' in the modified test case blocks the transform because it has non-zero bits in its RHS in those bits.

Reviewers: spatel, majnemer, davide

Reviewed By: davide

Subscribers: llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311343 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCasts.cpp
test/Transforms/InstCombine/cast.ll

index 05728c25db77a2e65b5755b44f8a9cad06769856..2fb5ce3faa0e67ec28b1dabd6827ad07937e6388 100644 (file)
@@ -950,8 +950,13 @@ static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear,
       unsigned VSize = V->getType()->getScalarSizeInBits();
       if (IC.MaskedValueIsZero(I->getOperand(1),
                                APInt::getHighBitsSet(VSize, BitsToClear),
-                               0, CxtI))
+                               0, CxtI)) {
+        // If this is an And instruction and all of the BitsToClear are
+        // known to be zero we can reset BitsToClear.
+        if (Opc == Instruction::And)
+          BitsToClear = 0;
         return true;
+      }
     }
 
     // Otherwise, we don't know how to analyze this BitsToClear case yet.
index 364337b9693752d409d6a4fe27875c2b37aded96..a9f51435dbe612c7e708144e6a4a74d51258883f 100644 (file)
@@ -1588,15 +1588,12 @@ define i64 @test94(i32 %a) {
 }
 
 ; We should be able to remove the zext and trunc here.
-; TODO: This is currently blocked because we don't realize the 'and' has cleared the extra bits that would be shifted in widening the lshr.
 define i32 @test95(i32 %x) {
 ; CHECK-LABEL: @test95(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], 6
-; CHECK-NEXT:    [[TMP3:%.*]] = and i8 [[TMP2]], 2
-; CHECK-NEXT:    [[TMP4:%.*]] = or i8 [[TMP3]], 40
-; CHECK-NEXT:    [[TMP5:%.*]] = zext i8 [[TMP4]] to i32
-; CHECK-NEXT:    ret i32 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 6
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP2]], 40
+; CHECK-NEXT:    ret i32 [[TMP3]]
 ;
   %1 = trunc i32 %x to i8
   %2 = lshr i8 %1, 6