[InstCombine] Use KnownBits::shl() in SimplifyDemandedBits()
authorNikita Popov <npopov@redhat.com>
Fri, 26 May 2023 12:39:57 +0000 (14:39 +0200)
committerNikita Popov <npopov@redhat.com>
Fri, 26 May 2023 12:43:10 +0000 (14:43 +0200)
It is more precise than the custom logic we had. This came up when
trying to enforce a consistency assertion with computeKnownBits().

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll
llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
llvm/test/Transforms/InstCombine/select-obo-peo-ops.ll

index ad30309..3e0c024 100644 (file)
@@ -644,24 +644,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
         return I;
       assert(!Known.hasConflict() && "Bits known to be one AND zero?");
 
-      bool SignBitZero = Known.Zero.isSignBitSet();
-      bool SignBitOne = Known.One.isSignBitSet();
-      Known.Zero <<= ShiftAmt;
-      Known.One  <<= ShiftAmt;
-      // low bits known zero.
-      if (ShiftAmt)
-        Known.Zero.setLowBits(ShiftAmt);
-
-      // If this shift has "nsw" keyword, then the result is either a poison
-      // value or has the same sign bit as the first operand.
-      if (IOp->hasNoSignedWrap()) {
-        if (SignBitZero)
-          Known.Zero.setSignBit();
-        else if (SignBitOne)
-          Known.One.setSignBit();
-        if (Known.hasConflict())
-          return PoisonValue::get(VTy);
-      }
+      Known = KnownBits::shl(Known,
+                             KnownBits::makeConstant(APInt(BitWidth, ShiftAmt)),
+                             /* NUW */ IOp->hasNoUnsignedWrap(),
+                             /* NSW */ IOp->hasNoSignedWrap());
     } else {
       // This is a variable shift, so we can't shift the demand mask by a known
       // amount. But if we are not demanding high bits, then we are not
index bace0b2..00e2bdf 100644 (file)
@@ -189,7 +189,7 @@ define i8 @positive_biggerashr_shlnuwnsw(i8 %x) {
 define i8 @positive_biggershl_shlnuwnsw(i8 %x) {
 ; CHECK-LABEL: @positive_biggershl_shlnuwnsw(
 ; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw nsw i8 [[X:%.*]], 3
-; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], -64
+; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], 64
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
   %tmp0 = ashr i8 %x, 3
index ecdc00a..0b8165e 100644 (file)
@@ -189,7 +189,7 @@ define i8 @positive_biggerlshr_shlnuwnsw(i8 %x) {
 define i8 @positive_biggershl_shlnuwnsw(i8 %x) {
 ; CHECK-LABEL: @positive_biggershl_shlnuwnsw(
 ; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw nsw i8 [[X:%.*]], 3
-; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], -64
+; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], 64
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
   %t0 = lshr i8 %x, 3
index 82ef5d7..5e3950c 100644 (file)
@@ -139,11 +139,7 @@ define i64 @test_shl__nuw_is_safe(i32 %x, i64 %y) {
 
 define i32 @test_shl_nuw_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_shl_nuw_nsw__nsw_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
-; CHECK-NEXT:    ret i32 [[TMP4]]
+; CHECK-NEXT:    ret i32 0
 ;
   %1 = or i32 %x, -83886080
   %2 = icmp eq i32 %1, -83886079
@@ -156,11 +152,7 @@ define i32 @test_shl_nuw_nsw__nsw_is_safe(i32 %x) {
 
 define i32 @test_shl_nuw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_shl_nuw__nsw_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
-; CHECK-NEXT:    ret i32 [[TMP4]]
+; CHECK-NEXT:    ret i32 0
 ;
   %1 = or i32 %x, -83886080
   %2 = icmp eq i32 %1, -83886079