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
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
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
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
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