}
}
- // (1 << (C - x)) -> ((1 << C) >> x) if C is bitwidth - 1
- if (match(Op0, m_One()) &&
- match(Op1, m_Sub(m_SpecificInt(BitWidth - 1), m_Value(X))))
- return BinaryOperator::CreateLShr(
- ConstantInt::get(Ty, APInt::getSignMask(BitWidth)), X);
+ if (match(Op0, m_One())) {
+ // (1 << (C - x)) -> ((1 << C) >> x) if C is bitwidth - 1
+ if (match(Op1, m_Sub(m_SpecificInt(BitWidth - 1), m_Value(X))))
+ return BinaryOperator::CreateLShr(
+ ConstantInt::get(Ty, APInt::getSignMask(BitWidth)), X);
+
+ // The only way to shift out the 1 is with an over-shift, and that would
+ // be poison either way.
+ if (!I.hasNoUnsignedWrap()) {
+ I.setHasNoUnsignedWrap();
+ return &I;
+ }
+ }
return nullptr;
}
define i1 @bitwise_and_bitwise_and_icmps(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_and_bitwise_and_icmps_comm1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_and_bitwise_and_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_and_bitwise_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_and_logical_and_icmps(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_logical_and_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_and_logical_and_icmps_comm1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_and_logical_and_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i8 [[Z_SHIFT]]
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], [[X:%.*]]
define i1 @bitwise_and_logical_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
; CHECK-LABEL: @logical_and_bitwise_and_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
; CHECK-LABEL: @logical_and_logical_and_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
; CHECK-LABEL: @logical_and_logical_and_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
; CHECK-LABEL: @logical_and_logical_and_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
define i1 @logical_and_logical_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_and_logical_and_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_logical_or_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i1 @bitwise_or_logical_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i8 [[Z_SHIFT]]
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], [[X:%.*]]
define i1 @bitwise_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
; CHECK-LABEL: @logical_or_bitwise_or_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-LABEL: @logical_or_logical_or_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-LABEL: @logical_or_logical_or_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-LABEL: @logical_or_logical_or_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
define i1 @logical_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_logical_or_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
define i8 @and1_shl1_is_cmp_eq_0_multiuse(i8 %x) {
; CHECK-LABEL: @and1_shl1_is_cmp_eq_0_multiuse(
-; CHECK-NEXT: [[SH:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[SH:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i8 [[SH]], 1
-; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SH]], [[AND]]
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[SH]], [[AND]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%sh = shl i8 1, %x
define i1 @test0(i39 %X, i39 %A) {
; CHECK-LABEL: @test0(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i39 1, [[A:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i39 1, [[A:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = and i39 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[D:%.*]] = icmp ne i39 [[TMP2]], 0
; CHECK-NEXT: ret i1 [[D]]
define i1 @test1(i799 %X, i799 %A) {
; CHECK-LABEL: @test1(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i799 1, [[A:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i799 1, [[A:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = and i799 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[D:%.*]] = icmp ne i799 [[TMP2]], 0
; CHECK-NEXT: ret i1 [[D]]
define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
define i1 @p0(i8 %x, i8 %y) {
; CHECK-LABEL: @p0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X_HIGHBITS]], 0
define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @p1_vec(
-; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <2 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef0(<3 x i8> %x, <3 x i8> %y) {
; CHECK-LABEL: @p2_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X_HIGHBITS]], zeroinitializer
define <3 x i1> @p3_vec_undef0(<3 x i8> %x, <3 x i8> %y) {
; CHECK-LABEL: @p3_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 1, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 1, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X_HIGHBITS]], zeroinitializer
define <3 x i1> @p4_vec_undef2(<3 x i8> %x, <3 x i8> %y) {
; CHECK-LABEL: @p4_vec_undef2(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X_HIGHBITS]], zeroinitializer
define i1 @c0(i8 %y) {
; CHECK-LABEL: @c0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
define i1 @c1(i8 %y) {
; CHECK-LABEL: @c1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
define i1 @c2(i8 %y) {
; CHECK-LABEL: @c2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
define i1 @oneuse0(i8 %x, i8 %y) {
; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: call void @use8(i8 [[T1]])
define i1 @oneuse1(i8 %x, i8 %y) {
; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
define i1 @oneuse2(i8 %x, i8 %y) {
; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: call void @use8(i8 [[T1]])
define i1 @n0(i8 %x, i8 %y, i8 %notx) {
; CHECK-LABEL: @n0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
define i1 @n2(i8 %x, i8 %y) {
; CHECK-LABEL: @n2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], 1
+; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
; CHECK-NEXT: ret i1 [[RET]]
define i1 @p0(i8 %x, i8 %y) {
; CHECK-LABEL: @p0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X_HIGHBITS]], 0
define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @p1_vec(
-; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <2 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[X_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef0(<3 x i8> %x, <3 x i8> %y) {
; CHECK-LABEL: @p2_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[X_HIGHBITS]], zeroinitializer
define <3 x i1> @p3_vec_undef0(<3 x i8> %x, <3 x i8> %y) {
; CHECK-LABEL: @p3_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 1, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 1, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[X_HIGHBITS]], zeroinitializer
define <3 x i1> @p4_vec_undef2(<3 x i8> %x, <3 x i8> %y) {
; CHECK-LABEL: @p4_vec_undef2(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[Y:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[X_HIGHBITS]], zeroinitializer
define i1 @c0(i8 %y) {
; CHECK-LABEL: @c0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
define i1 @c1(i8 %y) {
; CHECK-LABEL: @c1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
define i1 @c2(i8 %y) {
; CHECK-LABEL: @c2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[X_HIGHBITS:%.*]] = lshr i8 [[X]], [[Y]]
define i1 @oneuse0(i8 %x, i8 %y) {
; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: call void @use8(i8 [[T1]])
define i1 @oneuse1(i8 %x, i8 %y) {
; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
define i1 @oneuse2(i8 %x, i8 %y) {
; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: call void @use8(i8 [[T1]])
define i1 @n0(i8 %x, i8 %y, i8 %notx) {
; CHECK-LABEL: @n0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
define i1 @n2(i8 %x, i8 %y) {
; CHECK-LABEL: @n2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], 1
+; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
; CHECK-NEXT: ret i1 [[RET]]
define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T1:%.*]] = lshr i8 [[T0]], [[Y]]
-; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
-; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
-; CHECK-NEXT: ret i1 [[RET]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], 2
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%t0 = shl i8 1, %y ; not -1
call void @use8(i8 %t0)
define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T1:%.*]] = lshr i8 [[T0]], [[Y]]
-; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
-; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
-; CHECK-NEXT: ret i1 [[RET]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], 1
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%t0 = shl i8 1, %y ; not -1
call void @use8(i8 %t0)
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 1, [[NBITS]]
+; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 1, [[NBITS]]
+; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
-; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 1, [[NBITS_16BIT]]
+; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
-; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 1, [[NBITS_16BIT]]
+; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = zext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 1, [[NBITS]]
+; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i32 1, [[NBITS]]
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 1, [[NBITS]]
+; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
-; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 1, [[NBITS_16BIT]]
+; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 1, [[NBITS]]
+; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i32 1, [[NBITS]]
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
; Negative test, cannot take exact log2
define i8 @udiv_umin_(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @udiv_umin_(
-; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z:%.*]])
; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]]
; CHECK-NEXT: ret i8 [[D]]
; Negative test, extra use
define i8 @udiv_umin_extra_use(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @udiv_umin_extra_use(
-; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]]
-; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]])
; CHECK-NEXT: call void @use(i8 [[M]])
; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]]
; Negative test, signed min/max
define i8 @udiv_smin(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @udiv_smin(
-; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]]
-; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y2]], i8 [[Z2]])
; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]]
; CHECK-NEXT: ret i8 [[D]]
; Negative test, signed min/max
define i8 @udiv_smax(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @udiv_smax(
-; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]]
-; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
+; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y2]], i8 [[Z2]])
; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]]
; CHECK-NEXT: ret i8 [[D]]
define i32 @t10(i32 %x, i32 %y) {
; CHECK-LABEL: @t10(
-; CHECK-NEXT: [[R:%.*]] = shl nsw i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw nsw i32 1, [[Y:%.*]]
; CHECK-NEXT: ret i32 [[R]]
;
%shl = shl nsw i32 %x, %y
define <2 x i32> @t11(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @t11(
-; CHECK-NEXT: [[R:%.*]] = shl nsw <2 x i32> <i32 1, i32 1>, [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw nsw <2 x i32> <i32 1, i32 1>, [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[R]]
;
%shl = shl nsw <2 x i32> %x, %y
; One-use tests
define i8 @t6_extrause0(i8 %x) {
; CHECK-LABEL: @t6_extrause0(
-; CHECK-NEXT: [[BITMASK:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK]])
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 7, [[X]]
; CHECK-NEXT: [[MASK:%.*]] = lshr i8 -1, [[TMP1]]
}
define i8 @t7_extrause1(i8 %x) {
; CHECK-LABEL: @t7_extrause1(
-; CHECK-NEXT: [[BITMASK:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: [[LOWBITMASK:%.*]] = add i8 [[BITMASK]], -1
; CHECK-NEXT: call void @use8(i8 [[LOWBITMASK]])
; CHECK-NEXT: [[MASK:%.*]] = or i8 [[LOWBITMASK]], [[BITMASK]]
}
define i8 @t8_extrause2(i8 %x) {
; CHECK-LABEL: @t8_extrause2(
-; CHECK-NEXT: [[BITMASK:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK]])
; CHECK-NEXT: [[LOWBITMASK:%.*]] = add i8 [[BITMASK]], -1
; CHECK-NEXT: call void @use8(i8 [[LOWBITMASK]])
; Non-CSE'd test
define i8 @t9_nocse(i8 %x) {
; CHECK-LABEL: @t9_nocse(
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i8 -1, [[X]]
; CHECK-NEXT: [[LOWBITMASK:%.*]] = xor i8 [[NOTMASK]], -1
; CHECK-NEXT: [[MASK:%.*]] = or i8 [[BITMASK1]], [[LOWBITMASK]]
; Non-CSE'd extra uses test
define i8 @t10_nocse_extrause0(i8 %x) {
; CHECK-LABEL: @t10_nocse_extrause0(
-; CHECK-NEXT: [[BITMASK0:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK0:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK0]])
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 7, [[X]]
; CHECK-NEXT: [[MASK:%.*]] = lshr i8 -1, [[TMP1]]
}
define i8 @t11_nocse_extrause1(i8 %x) {
; CHECK-LABEL: @t11_nocse_extrause1(
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK1]])
; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i8 -1, [[X]]
; CHECK-NEXT: [[LOWBITMASK:%.*]] = xor i8 [[NOTMASK]], -1
}
define i8 @t12_nocse_extrause2(i8 %x) {
; CHECK-LABEL: @t12_nocse_extrause2(
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i8 -1, [[X]]
; CHECK-NEXT: [[LOWBITMASK:%.*]] = xor i8 [[NOTMASK]], -1
; CHECK-NEXT: call void @use8(i8 [[LOWBITMASK]])
}
define i8 @t13_nocse_extrause3(i8 %x) {
; CHECK-LABEL: @t13_nocse_extrause3(
-; CHECK-NEXT: [[BITMASK0:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK0:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK0]])
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK1]])
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 7, [[X]]
; CHECK-NEXT: [[MASK:%.*]] = lshr i8 -1, [[TMP1]]
}
define i8 @t14_nocse_extrause4(i8 %x) {
; CHECK-LABEL: @t14_nocse_extrause4(
-; CHECK-NEXT: [[BITMASK0:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK0:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK0]])
; CHECK-NEXT: [[LOWBITMASK:%.*]] = add i8 [[BITMASK0]], -1
; CHECK-NEXT: call void @use8(i8 [[LOWBITMASK]])
}
define i8 @t15_nocse_extrause5(i8 %x) {
; CHECK-LABEL: @t15_nocse_extrause5(
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK1]])
; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i8 -1, [[X]]
; CHECK-NEXT: [[LOWBITMASK:%.*]] = xor i8 [[NOTMASK]], -1
}
define i8 @t16_nocse_extrause6(i8 %x) {
; CHECK-LABEL: @t16_nocse_extrause6(
-; CHECK-NEXT: [[BITMASK0:%.*]] = shl i8 1, [[X:%.*]]
+; CHECK-NEXT: [[BITMASK0:%.*]] = shl nuw i8 1, [[X:%.*]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK0]])
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X]]
; CHECK-NEXT: call void @use8(i8 [[BITMASK1]])
; CHECK-NEXT: [[LOWBITMASK:%.*]] = add i8 [[BITMASK0]], -1
; CHECK-NEXT: call void @use8(i8 [[LOWBITMASK]])
; Non-CSE'd test with mismatching X's.
define i8 @t17_nocse_mismatching_x(i8 %x0, i8 %x1) {
; CHECK-LABEL: @t17_nocse_mismatching_x(
-; CHECK-NEXT: [[BITMASK1:%.*]] = shl i8 1, [[X1:%.*]]
+; CHECK-NEXT: [[BITMASK1:%.*]] = shl nuw i8 1, [[X1:%.*]]
; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i8 -1, [[X0:%.*]]
; CHECK-NEXT: [[LOWBITMASK:%.*]] = xor i8 [[NOTMASK]], -1
; CHECK-NEXT: [[MASK:%.*]] = or i8 [[BITMASK1]], [[LOWBITMASK]]
define i1 @shl1_trunc_eq0_use1(i8 %a) {
; CHECK-LABEL: @shl1_trunc_eq0_use1(
-; CHECK-NEXT: [[SHL:%.*]] = shl i8 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 1, [[A:%.*]]
; CHECK-NEXT: call void @use(i8 [[SHL]])
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[A]], 5
; CHECK-NEXT: ret i1 [[R]]
define i1 @shl1_trunc_ne0_use2(i37 %a) {
; CHECK-LABEL: @shl1_trunc_ne0_use2(
-; CHECK-NEXT: [[SHL:%.*]] = shl i37 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i37 1, [[A:%.*]]
; CHECK-NEXT: [[T:%.*]] = trunc i37 [[SHL]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp ult i37 [[A]], 8
define i1 @shl1_trunc_sgt0(i9 %a) {
; CHECK-LABEL: @shl1_trunc_sgt0(
-; CHECK-NEXT: [[SHL:%.*]] = shl i9 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i9 1, [[A:%.*]]
; CHECK-NEXT: [[T:%.*]] = trunc i9 [[SHL]] to i6
; CHECK-NEXT: [[R:%.*]] = icmp sgt i6 [[T]], 0
; CHECK-NEXT: ret i1 [[R]]
define i1 @shl1_trunc_eq1(i64 %a) {
; CHECK-LABEL: @shl1_trunc_eq1(
-; CHECK-NEXT: [[SHL:%.*]] = shl i64 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 1, [[A:%.*]]
; CHECK-NEXT: [[T:%.*]] = trunc i64 [[SHL]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[A]], 0
define i1 @shl1_trunc_ne32(i8 %a) {
; CHECK-LABEL: @shl1_trunc_ne32(
-; CHECK-NEXT: [[SHL:%.*]] = shl i8 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 1, [[A:%.*]]
; CHECK-NEXT: call void @use(i8 [[SHL]])
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[A]], 5
; CHECK-NEXT: ret i1 [[R]]
define i1 @shl1_trunc_sgt4(i32 %a) {
; CHECK-LABEL: @shl1_trunc_sgt4(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[A:%.*]]
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[SHL]] to i16
; CHECK-NEXT: [[R:%.*]] = icmp sgt i16 [[T]], 4
; CHECK-NEXT: ret i1 [[R]]
define i1 @p0(i8 %val, i8 %bits) {
; CHECK-LABEL: @p0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[VAL_HIGHBITS]], 0
define <2 x i1> @p1_vec(<2 x i8> %val, <2 x i8> %bits) {
; CHECK-LABEL: @p1_vec(
-; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <2 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef0(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef1(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef1(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 1, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 1, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef2(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef2(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define i1 @c0(i8 %bits) {
; CHECK-LABEL: @c0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL]], [[BITS]]
; What if we have the same pattern on both sides?
define i1 @both(i8 %bits0, i8 %bits1) {
; CHECK-LABEL: @both(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS0:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS0:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T2:%.*]] = shl i8 1, [[BITS1:%.*]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i8 1, [[BITS1:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T2]])
; CHECK-NEXT: [[T3:%.*]] = add i8 [[T2]], -1
; CHECK-NEXT: [[T3_HIGHBITS:%.*]] = lshr i8 [[T3]], [[BITS0]]
define i1 @oneuse(i8 %val, i8 %bits) {
; CHECK-LABEL: @oneuse(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: call void @use8(i8 [[T1]])
define i1 @n1(i8 %val, i8 %bits) {
; CHECK-LABEL: @n1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], 1
+; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
; CHECK-LABEL: @n3_vec_nonsplat(
-; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add <2 x i8> [[T0]], <i8 -1, i8 1>
; CHECK-NEXT: [[R:%.*]] = icmp uge <2 x i8> [[T1]], [[VAL:%.*]]
define i1 @n3(i8 %val, i8 %bits) {
; CHECK-LABEL: @n3(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T1]], [[VAL:%.*]]
define i1 @n4(i8 %bits) {
; CHECK-LABEL: @n4(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()
define i1 @n0(i8 %val, i8 %bits) {
; CHECK-LABEL: @n0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
; What if we have the same pattern on both sides?
define i1 @both(i8 %bits0, i8 %bits1) {
; CHECK-LABEL: @both(
-; CHECK-NEXT: [[T1:%.*]] = shl i8 1, [[BITS1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i8 1, [[BITS1:%.*]]
; CHECK-NEXT: [[T1_HIGHBITS:%.*]] = lshr i8 [[T1]], [[BITS0:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[T1_HIGHBITS]], 0
; CHECK-NEXT: ret i1 [[R]]
define i1 @oneuse0(i8 %val, i8 %bits) {
; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T0]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
define i1 @n2(i8 %val, i8 %bits) {
; CHECK-LABEL: @n2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T0]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
define i1 @n3(i8 %bits) {
; CHECK-LABEL: @n3(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[VAL]], [[T0]]
; CHECK-NEXT: ret i1 [[R]]
; What if we have the same pattern on both sides?
define i1 @both(i8 %bits0, i8 %bits1) {
; CHECK-LABEL: @both(
-; CHECK-NEXT: [[T1:%.*]] = shl i8 1, [[BITS1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i8 1, [[BITS1:%.*]]
; CHECK-NEXT: [[T1_HIGHBITS:%.*]] = lshr i8 [[T1]], [[BITS0:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[T1_HIGHBITS]], 0
; CHECK-NEXT: ret i1 [[R]]
define i1 @oneuse0(i8 %val, i8 %bits) {
; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[T0]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
define i1 @n2(i8 %val, i8 %bits) {
; CHECK-LABEL: @n2(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T0]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
define i1 @n3(i8 %bits) {
; CHECK-LABEL: @n3(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[VAL]], [[T0]]
; CHECK-NEXT: ret i1 [[R]]
define i1 @p0(i8 %val, i8 %bits) {
; CHECK-LABEL: @p0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[VAL_HIGHBITS]], 0
define <2 x i1> @p1_vec(<2 x i8> %val, <2 x i8> %bits) {
; CHECK-LABEL: @p1_vec(
-; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <2 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef0(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef1(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef1(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 1, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 1, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef2(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef2(
-; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define i1 @c0(i8 %bits) {
; CHECK-LABEL: @c0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL]], [[BITS]]
; What if we have the same pattern on both sides?
define i1 @both(i8 %bits0, i8 %bits1) {
; CHECK-LABEL: @both(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS0:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS0:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T2:%.*]] = shl i8 1, [[BITS1:%.*]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i8 1, [[BITS1:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T2]])
; CHECK-NEXT: [[T3:%.*]] = add i8 [[T2]], -1
; CHECK-NEXT: [[T3_HIGHBITS:%.*]] = lshr i8 [[T3]], [[BITS0]]
define i1 @oneuse(i8 %val, i8 %bits) {
; CHECK-LABEL: @oneuse(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: call void @use8(i8 [[T1]])
define i1 @n1(i8 %val, i8 %bits) {
; CHECK-LABEL: @n1(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
-; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], 1
+; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T1]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
; CHECK-LABEL: @n3_vec_nonsplat(
-; CHECK-NEXT: [[T0:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use2i8(<2 x i8> [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add <2 x i8> [[T0]], <i8 -1, i8 1>
; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[T1]], [[VAL:%.*]]
define i1 @n3(i8 %val, i8 %bits) {
; CHECK-LABEL: @n3(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[T1]], [[VAL:%.*]]
define i1 @n4(i8 %bits) {
; CHECK-LABEL: @n4(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen8()
define i1 @n0(i8 %val, i8 %bits) {
; CHECK-LABEL: @n0(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T1]], [[VAL:%.*]]
; CHECK-NEXT: ret i1 [[R]]
define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[CMP]]
define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 255
; CHECK-NEXT: [[MEMCHR_BOUNDS:%.*]] = icmp ult i16 [[TMP2]], 16
-; CHECK-NEXT: [[TMP3:%.*]] = shl i16 1, [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i16 1, [[TMP2]]
; CHECK-NEXT: [[TMP4:%.*]] = and i16 [[TMP3]], 9217
; CHECK-NEXT: [[MEMCHR_BITS:%.*]] = icmp ne i16 [[TMP4]], 0
; CHECK-NEXT: [[MEMCHR:%.*]] = select i1 [[MEMCHR_BOUNDS]], i1 [[MEMCHR_BITS]], i1 false
; rdar://7293527
define i32 @test15(i32 %A, i32 %B) {
; CHECK-LABEL: @test15(
-; CHECK-NEXT: [[M:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: ret i32 [[M]]
+; CHECK-NEXT: [[M1:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[M1]]
;
%shl = shl i32 1, %B
%m = mul i32 %shl, %A
define i32 @test26(i32 %A, i32 %B) {
; CHECK-LABEL: @test26(
-; CHECK-NEXT: [[D:%.*]] = shl nsw i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: ret i32 [[D]]
+; CHECK-NEXT: [[D1:%.*]] = shl nsw i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[D1]]
;
%C = shl nsw i32 1, %B
%D = mul nsw i32 %A, %C
define i32 @test27(i32 %A, i32 %B) {
; CHECK-LABEL: @test27(
-; CHECK-NEXT: [[D:%.*]] = shl nuw i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: ret i32 [[D]]
+; CHECK-NEXT: [[D1:%.*]] = shl nuw i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[D1]]
;
%C = shl i32 1, %B
%D = mul nuw i32 %A, %C
define i32 @test28(i32 %A) {
; CHECK-LABEL: @test28(
-; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[A:%.*]]
-; CHECK-NEXT: [[C:%.*]] = shl i32 [[B]], [[A]]
-; CHECK-NEXT: ret i32 [[C]]
+; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[A:%.*]]
+; CHECK-NEXT: [[C1:%.*]] = shl i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[C1]]
;
%B = shl i32 1, %A
%C = mul nsw i32 %B, %B
@PR22087 = external global i32
define i32 @test31(i32 %V) {
; CHECK-LABEL: @test31(
-; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[V:%.*]], zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32)
-; CHECK-NEXT: ret i32 [[MUL]]
+; CHECK-NEXT: [[MUL1:%.*]] = shl i32 [[V:%.*]], zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32)
+; CHECK-NEXT: ret i32 [[MUL1]]
;
%mul = mul i32 %V, shl (i32 1, i32 zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32))
ret i32 %mul
define i32 @shl1_nsw(i32 %A) {
; CHECK-LABEL: @shl1_nsw(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[A:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[A:%.*]]
; CHECK-NEXT: [[C1:%.*]] = shl i32 [[SHL]], [[A]]
; CHECK-NEXT: ret i32 [[C1]]
;
define i32 @shl1_increment_use(i32 %x, i32 %y) {
; CHECK-LABEL: @shl1_increment_use(
-; CHECK-NEXT: [[POW2X:%.*]] = shl i32 1, [[X:%.*]]
+; CHECK-NEXT: [[POW2X:%.*]] = shl nuw i32 1, [[X:%.*]]
; CHECK-NEXT: call void @use32(i32 [[POW2X]])
-; CHECK-NEXT: [[X1:%.*]] = add i32 [[POW2X]], 1
+; CHECK-NEXT: [[X1:%.*]] = add nuw i32 [[POW2X]], 1
; CHECK-NEXT: [[M:%.*]] = mul i32 [[X1]], [[Y:%.*]]
; CHECK-NEXT: ret i32 [[M]]
;
define i1 @foo1_and(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
define i1 @foo1_and_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_logical(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[K:%.*]]
define <2 x i1> @foo1_and_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
; CHECK-LABEL: @foo1_and_vector(
-; CHECK-NEXT: [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], [[TMP1]]
define i1 @foo1_and_commuted(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_commuted(
; CHECK-NEXT: [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[K2]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
define i1 @foo1_and_commuted_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_commuted_logical(
; CHECK-NEXT: [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[K2]], [[TMP2]]
define <2 x i1> @foo1_and_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
; CHECK-LABEL: @foo1_and_commuted_vector(
; CHECK-NEXT: [[K2:%.*]] = mul <2 x i32> [[K:%.*]], [[K]]
-; CHECK-NEXT: [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[K2]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], [[TMP1]]
define i1 @foo1_or(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
define i1 @foo1_or_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_logical(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[K:%.*]]
define <2 x i1> @foo1_or_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
; CHECK-LABEL: @foo1_or_vector(
-; CHECK-NEXT: [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], [[TMP1]]
define i1 @foo1_or_commuted(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_commuted(
; CHECK-NEXT: [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[K2]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
define i1 @foo1_or_commuted_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_commuted_logical(
; CHECK-NEXT: [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[K2]], [[TMP2]]
define <2 x i1> @foo1_or_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
; CHECK-LABEL: @foo1_or_commuted_vector(
; CHECK-NEXT: [[K2:%.*]] = mul <2 x i32> [[K:%.*]], [[K]]
-; CHECK-NEXT: [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
-; CHECK-NEXT: [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[K2]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], [[TMP1]]
define i1 @foo1_and_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_signbit_lshr(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
define i1 @foo1_and_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_signbit_lshr_logical(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
define <2 x i1> @foo1_and_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
; CHECK-LABEL: @foo1_and_signbit_lshr_vector(
-; CHECK-NEXT: [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
define i1 @foo1_or_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_signbit_lshr(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
define i1 @foo1_or_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_signbit_lshr_logical(
-; CHECK-NEXT: [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
define <2 x i1> @foo1_or_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
; CHECK-LABEL: @foo1_or_signbit_lshr_vector(
-; CHECK-NEXT: [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
+; CHECK-NEXT: [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
; Same as last two, but shift-of-signbit replaced with 'icmp s*'
define i1 @foo1_and_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
define i1 @foo1_or_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
define i1 @foo1_or_signbit_lshr_without_shifting_signbit_logical(i32 %k, i32 %c1, i32 %c2) {
; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
; Expect to fold
define i1 @foo1_and_extra_use_shl(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_shl(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: store i32 [[T0]], ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
define i1 @foo1_and_extra_use_shl_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_shl_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: store i32 [[T0]], ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T1]]
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T0]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[K:%.*]]
; Should not fold
define i1 @foo1_and_extra_use_and(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_and(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: store i32 [[T2]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
define i1 @foo1_and_extra_use_and_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_and_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: store i32 [[T2]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T1]]
; Should not fold
define i1 @foo1_and_extra_use_cmp(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_cmp(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 0
; CHECK-NEXT: store i1 [[T3]], ptr [[P:%.*]], align 1
define i1 @foo1_and_extra_use_cmp_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_cmp_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 0
; CHECK-NEXT: store i1 [[T3]], ptr [[P:%.*]], align 1
; Expect to fold
define i1 @foo1_and_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_shl2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: store i32 [[T1]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
define i1 @foo1_and_extra_use_shl2_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_shl2_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T1]]
; CHECK-NEXT: store i32 [[TMP1]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[T0]], [[TMP1]]
; Should not fold
define i1 @foo1_and_extra_use_and2(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_and2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T1]], [[K:%.*]]
; CHECK-NEXT: store i32 [[T4]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
define i1 @foo1_and_extra_use_and2_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_and2_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T1]]
; CHECK-NEXT: [[T4:%.*]] = and i32 [[TMP1]], [[K:%.*]]
; CHECK-NEXT: store i32 [[T4]], ptr [[P:%.*]], align 4
; Should not fold
define i1 @foo1_and_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_cmp2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T1]], [[K:%.*]]
; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], 0
; CHECK-NEXT: store i1 [[T5]], ptr [[P:%.*]], align 1
define i1 @foo1_and_extra_use_cmp2_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_extra_use_cmp2_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[C2:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[T1]]
; CHECK-NEXT: [[T4:%.*]] = and i32 [[TMP1]], [[K:%.*]]
; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], 0
; Expect to fold
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: store i32 [[T0]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: store i32 [[T0]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; Not fold
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: store i32 [[T1]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: store i32 [[T1]], ptr [[P:%.*]], align 4
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; Not fold
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: store i1 [[T2]], ptr [[P:%.*]], align 1
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: store i1 [[T2]], ptr [[P:%.*]], align 1
; Not fold
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
; Not fold
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2_logical(i32 %k, i32 %c1, i32 %c2, ptr %p) {
; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2_logical(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[C1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
; CHECK-LABEL: @t0_basic(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
; CHECK-NEXT: [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT: [[T2:%.*]] = shl i64 1, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i64 1, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add i64 [[T2]], -1
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[T0]])
; CHECK-LABEL: @t1_vec_splat(
; CHECK-NEXT: [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>
-; CHECK-NEXT: [[T2:%.*]] = shl <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
; CHECK-NEXT: [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
; CHECK-NEXT: call void @use8xi32(<8 x i32> [[T0]])
; CHECK-LABEL: @t2_vec_splat_undef(
; CHECK-NEXT: [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 undef, i32 -1>
; CHECK-NEXT: [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>
-; CHECK-NEXT: [[T2:%.*]] = shl <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 undef, i64 1>, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 undef, i64 1>, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 undef, i64 -1>
; CHECK-NEXT: [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 undef, i32 32>, [[NBITS]]
; CHECK-NEXT: call void @use8xi32(<8 x i32> [[T0]])
; CHECK-LABEL: @t3_vec_nonsplat(
; CHECK-NEXT: [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>
; CHECK-NEXT: [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>
-; CHECK-NEXT: [[T2:%.*]] = shl <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
; CHECK-NEXT: [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
; CHECK-NEXT: call void @use8xi32(<8 x i32> [[T0]])
; CHECK-LABEL: @n4_extrause0(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
; CHECK-NEXT: [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT: [[T2:%.*]] = shl i64 1, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i64 1, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add i64 [[T2]], -1
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[T0]])
; CHECK-LABEL: @n5_extrause1(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
; CHECK-NEXT: [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT: [[T2:%.*]] = shl i64 1, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i64 1, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add i64 [[T2]], -1
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[T0]])
; CHECK-LABEL: @n6_extrause2(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
; CHECK-NEXT: [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT: [[T2:%.*]] = shl i64 1, [[T1]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i64 1, [[T1]]
; CHECK-NEXT: [[T3:%.*]] = add i64 [[T2]], -1
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[T0]])
define i32 @t0_basic(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t0_basic(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], -1
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[T0]])
define <8 x i32> @t1_vec_splat(<8 x i32> %x, <8 x i32> %nbits) {
; CHECK-LABEL: @t1_vec_splat(
; CHECK-NEXT: [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
-; CHECK-NEXT: [[T1:%.*]] = shl <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add <8 x i32> [[T1]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
; CHECK-NEXT: call void @use8xi32(<8 x i32> [[T0]])
define <8 x i32> @t1_vec_splat_undef(<8 x i32> %x, <8 x i32> %nbits) {
; CHECK-LABEL: @t1_vec_splat_undef(
; CHECK-NEXT: [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 undef, i32 -1>
-; CHECK-NEXT: [[T1:%.*]] = shl <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 undef, i32 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 undef, i32 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add <8 x i32> [[T1]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 undef, i32 -1>
; CHECK-NEXT: [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 undef, i32 32>, [[NBITS]]
; CHECK-NEXT: call void @use8xi32(<8 x i32> [[T0]])
define <8 x i32> @t2_vec_nonsplat(<8 x i32> %x, <8 x i32> %nbits) {
; CHECK-LABEL: @t2_vec_nonsplat(
; CHECK-NEXT: [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>
-; CHECK-NEXT: [[T1:%.*]] = shl <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add <8 x i32> [[T1]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
; CHECK-NEXT: call void @use8xi32(<8 x i32> [[T0]])
define i32 @n3_extrause(i32 %x, i32 %nbits) {
; CHECK-LABEL: @n3_extrause(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], -1
; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], [[X:%.*]]
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
define i32 @t0_basic(i64 %x, i32 %nbits) {
; CHECK-LABEL: @t0_basic(
; CHECK-NEXT: [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT: [[T1:%.*]] = shl i64 1, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i64 1, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add i64 [[T1]], -1
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
define <8 x i32> @t1_vec_splat(<8 x i64> %x, <8 x i32> %nbits) {
; CHECK-LABEL: @t1_vec_splat(
; CHECK-NEXT: [[T0:%.*]] = zext <8 x i32> [[NBITS:%.*]] to <8 x i64>
-; CHECK-NEXT: [[T1:%.*]] = shl <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add <8 x i64> [[T1]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
; CHECK-NEXT: [[T3:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
; CHECK-NEXT: [[T4:%.*]] = and <8 x i64> [[T2]], [[X:%.*]]
define <8 x i32> @t2_vec_splat_undef(<8 x i64> %x, <8 x i32> %nbits) {
; CHECK-LABEL: @t2_vec_splat_undef(
; CHECK-NEXT: [[T0:%.*]] = zext <8 x i32> [[NBITS:%.*]] to <8 x i64>
-; CHECK-NEXT: [[T1:%.*]] = shl <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 undef, i64 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 undef, i64 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add <8 x i64> [[T1]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 undef, i64 -1>
; CHECK-NEXT: [[T3:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 undef, i32 32>, [[NBITS]]
; CHECK-NEXT: [[T4:%.*]] = and <8 x i64> [[T2]], [[X:%.*]]
define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {
; CHECK-LABEL: @t3_vec_nonsplat(
; CHECK-NEXT: [[T0:%.*]] = zext <8 x i32> [[NBITS:%.*]] to <8 x i64>
-; CHECK-NEXT: [[T1:%.*]] = shl <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add <8 x i64> [[T1]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
; CHECK-NEXT: [[T3:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
; CHECK-NEXT: [[T4:%.*]] = and <8 x i64> [[T2]], [[X:%.*]]
define i32 @n4_extrause(i64 %x, i32 %nbits) {
; CHECK-LABEL: @n4_extrause(
; CHECK-NEXT: [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT: [[T1:%.*]] = shl i64 1, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i64 1, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add i64 [[T1]], -1
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
define i32 @t0_basic(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t0_basic(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
define i32 @t1_bigger_shift(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t1_bigger_shift(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 33, [[NBITS]]
define i32 @t2_bigger_mask(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t2_bigger_mask(
; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], 1
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add nsw i32 [[T1]], -1
; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], [[X:%.*]]
; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]
define <3 x i32> @t3_vec_splat(<3 x i32> %x, <3 x i32> %nbits) {
; CHECK-LABEL: @t3_vec_splat(
-; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[NBITS:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <3 x i32> <i32 1, i32 1, i32 1>, [[NBITS:%.*]]
; CHECK-NEXT: [[T2:%.*]] = add nsw <3 x i32> [[T1]], <i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]
; CHECK-NEXT: [[T4:%.*]] = sub <3 x i32> <i32 32, i32 32, i32 32>, [[NBITS]]
define <3 x i32> @t4_vec_nonsplat(<3 x i32> %x, <3 x i32> %nbits) {
; CHECK-LABEL: @t4_vec_nonsplat(
; CHECK-NEXT: [[T0:%.*]] = add <3 x i32> [[NBITS:%.*]], <i32 -1, i32 0, i32 1>
-; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[T0]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <3 x i32> <i32 1, i32 1, i32 1>, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = add nsw <3 x i32> [[T1]], <i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]
; CHECK-NEXT: [[T4:%.*]] = sub <3 x i32> <i32 33, i32 32, i32 32>, [[NBITS]]
define <3 x i32> @t5_vec_undef(<3 x i32> %x, <3 x i32> %nbits) {
; CHECK-LABEL: @t5_vec_undef(
-; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> <i32 1, i32 undef, i32 1>, [[NBITS:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw <3 x i32> <i32 1, i32 undef, i32 1>, [[NBITS:%.*]]
; CHECK-NEXT: [[T2:%.*]] = add nsw <3 x i32> [[T1]], <i32 -1, i32 undef, i32 -1>
; CHECK-NEXT: [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]
; CHECK-NEXT: [[T4:%.*]] = sub <3 x i32> <i32 32, i32 undef, i32 32>, [[NBITS]]
define i32 @t6_commutativity0(i32 %nbits) {
; CHECK-LABEL: @t6_commutativity0(
; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], [[T1]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
define i32 @t7_commutativity1(i32 %nbits0, i32 %nbits1) {
; CHECK-LABEL: @t7_commutativity1(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS0:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS0:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
-; CHECK-NEXT: [[T2:%.*]] = shl i32 1, [[NBITS1:%.*]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i32 1, [[NBITS1:%.*]]
; CHECK-NEXT: [[T3:%.*]] = add nsw i32 [[T2]], -1
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], [[T1]]
; CHECK-NEXT: [[T5:%.*]] = sub i32 32, [[NBITS0]]
}
define i32 @t8_commutativity2(i32 %nbits0, i32 %nbits1) {
; CHECK-LABEL: @t8_commutativity2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS0:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS0:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
-; CHECK-NEXT: [[T2:%.*]] = shl i32 1, [[NBITS1:%.*]]
+; CHECK-NEXT: [[T2:%.*]] = shl nuw i32 1, [[NBITS1:%.*]]
; CHECK-NEXT: [[T3:%.*]] = add nsw i32 [[T2]], -1
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], [[T1]]
; CHECK-NEXT: [[T5:%.*]] = sub i32 32, [[NBITS1]]
define i32 @t9_nuw(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t9_nuw(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
define i32 @t10_nsw(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t10_nsw(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
define i32 @t11_nuw_nsw(i32 %x, i32 %nbits) {
; CHECK-LABEL: @t11_nuw_nsw(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
define i32 @n13_not_minus_one(i32 %x, i32 %nbits) {
; CHECK-LABEL: @n13_not_minus_one(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[NBITS:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], 2147483647
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = add nuw nsw i32 [[T0]], 2147483647
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]
; CHECK-NEXT: call void @use32(i32 [[T0]])
define i64 @test14(i64 %x, i32 %y) {
; CHECK-LABEL: @test14(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[ZEXT]], -1
; CHECK-NEXT: [[UREM:%.*]] = and i64 [[TMP1]], [[X:%.*]]
define i32 @test19(i32 %x, i32 %y) {
; CHECK-LABEL: @test19(
-; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]]
-; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]
+; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], [[B]]
; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A]]
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1
define i32 @test19_commutative0(i32 %x, i32 %y) {
; CHECK-LABEL: @test19_commutative0(
-; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]]
-; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]
+; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[C:%.*]] = and i32 [[B]], [[A]]
; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A]]
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1
define i32 @test19_commutative1(i32 %x, i32 %y) {
; CHECK-LABEL: @test19_commutative1(
-; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]]
-; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]
+; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], [[B]]
; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]]
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1
define i32 @test19_commutative2(i32 %x, i32 %y) {
; CHECK-LABEL: @test19_commutative2(
-; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]]
-; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]
+; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[C:%.*]] = and i32 [[B]], [[A]]
; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]]
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1
; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[PHI_BO:%.*]] = srem i32 [[V]], 5
+; CHECK-NEXT: [[TMP0:%.*]] = srem i32 [[V]], 5
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
-; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[PHI_BO]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[LHS]]
;
entry:
; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[PHI_BO:%.*]] = and i32 [[V]], 2147483647
+; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[V]], 2147483647
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
-; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[PHI_BO]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ]
; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]
; CHECK: rem.is.safe:
; CHECK-NEXT: ret i32 [[LHS]]
; CHECK-LABEL: @PR45762(
; CHECK-NEXT: [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false), !range [[RNG2:![0-9]+]]
; CHECK-NEXT: [[T7:%.*]] = zext i3 [[T4]] to i4
-; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl i4 1, [[T7]]
+; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i3 [[X4]], 0
-; CHECK-NEXT: [[UMUL_23:%.*]] = select i1 [[DOTNOT]], i4 0, i4 [[T7]]
-; CHECK-NEXT: [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_23]]
+; CHECK-NEXT: [[UMUL_231:%.*]] = select i1 [[DOTNOT]], i4 0, i4 [[T7]]
+; CHECK-NEXT: [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_231]]
; CHECK-NEXT: ret i4 [[SEL_71]]
;
%t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)
; CHECK-LABEL: @PR45762_logical(
; CHECK-NEXT: [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false), !range [[RNG2]]
; CHECK-NEXT: [[T7:%.*]] = zext i3 [[T4]] to i4
-; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl i4 1, [[T7]]
+; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i3 [[X4]], 0
-; CHECK-NEXT: [[UMUL_23:%.*]] = select i1 [[DOTNOT]], i4 0, i4 [[T7]]
-; CHECK-NEXT: [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_23]]
+; CHECK-NEXT: [[UMUL_231:%.*]] = select i1 [[DOTNOT]], i4 0, i4 [[T7]]
+; CHECK-NEXT: [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_231]]
; CHECK-NEXT: ret i4 [[SEL_71]]
;
%t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)
; One use only.
define i32 @bad_oneuse0(i32 %NBits) {
; CHECK-LABEL: @bad_oneuse0(
-; CHECK-NEXT: [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: call void @use32(i32 [[SETBIT]])
; CHECK-NEXT: [[RET:%.*]] = add i32 [[SETBIT]], -1
; CHECK-NEXT: ret i32 [[RET]]
define i32 @bad_add0(i32 %NBits, i32 %addop2) {
; CHECK-LABEL: @bad_add0(
-; CHECK-NEXT: [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[RET:%.*]] = add i32 [[SETBIT]], [[ADDOP2:%.*]]
; CHECK-NEXT: ret i32 [[RET]]
;
define i32 @bad_add1(i32 %NBits) {
; CHECK-LABEL: @bad_add1(
-; CHECK-NEXT: [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
-; CHECK-NEXT: [[RET:%.*]] = add i32 [[SETBIT]], 1
+; CHECK-NEXT: [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[RET:%.*]] = add nuw i32 [[SETBIT]], 1
; CHECK-NEXT: ret i32 [[RET]]
;
%setbit = shl i32 1, %NBits
define i32 @bad_add2(i32 %NBits) {
; CHECK-LABEL: @bad_add2(
-; CHECK-NEXT: [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT: [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
; CHECK-NEXT: [[RET:%.*]] = add i32 [[SETBIT]], -2
; CHECK-NEXT: ret i32 [[RET]]
;
define i32 @shl_nsw_add_negative(i32 %x) {
; CHECK-LABEL: @shl_nsw_add_negative(
-; CHECK-NEXT: [[R:%.*]] = shl i32 1, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[X:%.*]]
; CHECK-NEXT: ret i32 [[R]]
;
%a = add i32 %x, -1
define i1 @t7_twoshifts2(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @t7_twoshifts2(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[B:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[B:%.*]]
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[C:%.*]], [[D:%.*]]
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 0
define i1 @t8_twoshifts3(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @t8_twoshifts3(
; CHECK-NEXT: [[T0:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[T1:%.*]] = shl i32 1, [[D:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[D:%.*]]
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 0
; CHECK-NEXT: ret i1 [[T3]]
define i1 @t12_shift_of_const0(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @t12_shift_of_const0(
-; CHECK-NEXT: [[T0:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], [[Z:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
; CHECK-NEXT: ret i1 [[T2]]
}
define i1 @t15_and_with_const1(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @t15_and_with_const1(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP2]], 0
; CHECK-NEXT: ret i1 [[T2]]
define i32 @test38(i32 %x) nounwind readnone {
; CHECK-LABEL: @test38(
; CHECK-NEXT: [[REM1:%.*]] = and i32 [[X:%.*]], 31
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[REM1]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[REM1]]
; CHECK-NEXT: ret i32 [[SHL]]
;
%rem = srem i32 %x, 32
define <2 x i32> @test38_uniform(<2 x i32> %x) nounwind readnone {
; CHECK-LABEL: @test38_uniform(
; CHECK-NEXT: [[REM1:%.*]] = and <2 x i32> [[X:%.*]], <i32 31, i32 31>
-; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[REM1]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[REM1]]
; CHECK-NEXT: ret <2 x i32> [[SHL]]
;
%rem = srem <2 x i32> %x, <i32 32, i32 32>
define <3 x i32> @test38_nonuniform(<3 x i32> %x) nounwind readnone {
; CHECK-LABEL: @test38_nonuniform(
; CHECK-NEXT: [[REM1:%.*]] = and <3 x i32> [[X:%.*]], <i32 31, i32 15, i32 0>
-; CHECK-NEXT: [[SHL:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[REM1]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw <3 x i32> <i32 1, i32 1, i32 1>, [[REM1]]
; CHECK-NEXT: ret <3 x i32> [[SHL]]
;
%rem = srem <3 x i32> %x, <i32 32, i32 16, i32 1>
define <vscale x 8 x i8> @ashr_demanded_bits_splat2(<vscale x 8 x i8> %x) {
; CHECK-LABEL: @ashr_demanded_bits_splat2(
-; CHECK-NEXT: [[AND:%.*]] = ashr <vscale x 8 x i8> [[X:%.*]], shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 7, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
-; CHECK-NEXT: ret <vscale x 8 x i8> [[AND]]
+; CHECK-NEXT: [[SHR:%.*]] = ashr <vscale x 8 x i8> [[X:%.*]], shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 7, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
+; CHECK-NEXT: ret <vscale x 8 x i8> [[SHR]]
;
%and = and <vscale x 8 x i8> %x, shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 128, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
%shr = ashr <vscale x 8 x i8> %and, shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 7, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
define <vscale x 8 x i8> @lshr_demanded_bits_splat2(<vscale x 8 x i8> %x) {
; CHECK-LABEL: @lshr_demanded_bits_splat2(
-; CHECK-NEXT: [[AND:%.*]] = lshr <vscale x 8 x i8> [[X:%.*]], shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 7, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
-; CHECK-NEXT: ret <vscale x 8 x i8> [[AND]]
+; CHECK-NEXT: [[SHR:%.*]] = lshr <vscale x 8 x i8> [[X:%.*]], shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 7, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
+; CHECK-NEXT: ret <vscale x 8 x i8> [[SHR]]
;
%and = and <vscale x 8 x i8> %x, shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 128, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
%shr = lshr <vscale x 8 x i8> %and, shufflevector (<vscale x 8 x i8> insertelement (<vscale x 8 x i8> poison, i8 7, i32 0), <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer)
define i32 @shl_bad_sub_i32(i32 %x) {
; CHECK-LABEL: @shl_bad_sub_i32(
; CHECK-NEXT: [[S:%.*]] = sub i32 32, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = shl i32 1, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[S]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = sub i32 32, %x
define i32 @shl_bad_sub2_i32(i32 %x) {
; CHECK-LABEL: @shl_bad_sub2_i32(
; CHECK-NEXT: [[S:%.*]] = add i32 [[X:%.*]], -31
-; CHECK-NEXT: [[R:%.*]] = shl i32 1, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[S]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = sub i32 %x, 31
define i32 @bad_shl2_sub_i32(i32 %x) {
; CHECK-LABEL: @bad_shl2_sub_i32(
; CHECK-NEXT: [[S:%.*]] = add i32 [[X:%.*]], -31
-; CHECK-NEXT: [[R:%.*]] = shl i32 1, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[S]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = sub i32 %x, 31
define i8 @shl_bad_sub_i8(i8 %x) {
; CHECK-LABEL: @shl_bad_sub_i8(
; CHECK-NEXT: [[S:%.*]] = sub i8 4, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = shl i8 1, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw i8 1, [[S]]
; CHECK-NEXT: ret i8 [[R]]
;
%s = sub i8 4, %x
define i64 @shl_bad_sub_i64(i64 %x) {
; CHECK-LABEL: @shl_bad_sub_i64(
; CHECK-NEXT: [[S:%.*]] = sub i64 67, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = shl i64 1, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw i64 1, [[S]]
; CHECK-NEXT: ret i64 [[R]]
;
%s = sub i64 67, %x
define <2 x i64> @shl_bad_sub_i64_vec(<2 x i64> %x) {
; CHECK-LABEL: @shl_bad_sub_i64_vec(
; CHECK-NEXT: [[S:%.*]] = sub <2 x i64> <i64 53, i64 53>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = shl <2 x i64> <i64 1, i64 1>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw <2 x i64> <i64 1, i64 1>, [[S]]
; CHECK-NEXT: ret <2 x i64> [[R]]
;
%s = sub <2 x i64> <i64 53, i64 53>, %x
define <3 x i64> @shl_sub_i64_vec_undef_bad(<3 x i64> %x) {
; CHECK-LABEL: @shl_sub_i64_vec_undef_bad(
; CHECK-NEXT: [[S:%.*]] = sub <3 x i64> <i64 63, i64 undef, i64 63>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = shl <3 x i64> <i64 1, i64 1, i64 1>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw <3 x i64> <i64 1, i64 1, i64 1>, [[S]]
; CHECK-NEXT: ret <3 x i64> [[R]]
;
%s = sub <3 x i64> <i64 63, i64 undef, i64 63>, %x
define <3 x i64> @shl_sub_i64_vec_undef_bad2(<3 x i64> %x) {
; CHECK-LABEL: @shl_sub_i64_vec_undef_bad2(
; CHECK-NEXT: [[S:%.*]] = sub <3 x i64> <i64 63, i64 undef, i64 63>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = shl <3 x i64> <i64 1, i64 undef, i64 1>, [[S]]
+; CHECK-NEXT: [[R:%.*]] = shl nuw <3 x i64> <i64 1, i64 undef, i64 1>, [[S]]
; CHECK-NEXT: ret <3 x i64> [[R]]
;
%s = sub <3 x i64> <i64 63, i64 undef, i64 63>, %x
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 255
; CHECK-NEXT: [[MEMCHR_BOUNDS:%.*]] = icmp ult i16 [[TMP2]], 16
-; CHECK-NEXT: [[TMP3:%.*]] = shl i16 1, [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i16 1, [[TMP2]]
; CHECK-NEXT: [[TMP4:%.*]] = and i16 [[TMP3]], 9217
; CHECK-NEXT: [[MEMCHR_BITS:%.*]] = icmp ne i16 [[TMP4]], 0
; CHECK-NEXT: [[MEMCHR1:%.*]] = select i1 [[MEMCHR_BOUNDS]], i1 [[MEMCHR_BITS]], i1 false
}
define i8 @n8(i8 %x, i1 %y, i8 %z) {
; CHECK-LABEL: @n8(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
}
define i8 @n8(i8 %x, i1 %y, i8 %z) {
; CHECK-LABEL: @n8(
-; CHECK-NEXT: [[T0:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Z:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
define <2 x i8> @cttz_pow2(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @cttz_pow2(
-; CHECK-NEXT: [[S:%.*]] = shl <2 x i8> <i8 1, i8 1>, [[X:%.*]]
+; CHECK-NEXT: [[S:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[X:%.*]]
; CHECK-NEXT: [[D:%.*]] = udiv exact <2 x i8> [[S]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> [[D]], i1 true)
; CHECK-NEXT: ret <2 x i8> [[R]]
define i32 @masked_bit_set_use1(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_set_use1(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: call void @use32(i32 [[SH1]])
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1
define i32 @masked_bit_set_use2(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_set_use2(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: call void @use32(i32 [[AND]])
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
define i32 @masked_bit_set_use3(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_set_use3(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
; CHECK-NEXT: call void @use1(i1 [[CMP]])
define i32 @masked_bit_clear_use1(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_clear_use1(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: call void @use32(i32 [[SH1]])
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], [[Y]]
define i32 @masked_bit_clear_use2(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_clear_use2(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: call void @use32(i32 [[AND]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
define i32 @masked_bit_clear_use3(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_clear_use3(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: call void @use1(i1 [[CMP]])
define i32 @div_bit_set(i32 %x, i32 %y) {
; CHECK-LABEL: @div_bit_set(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = sdiv i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
define i32 @masked_bit_set_nonzero_cmp(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_set_nonzero_cmp(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 1
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
define i32 @masked_bit_wrong_pred(i32 %x, i32 %y) {
; CHECK-LABEL: @masked_bit_wrong_pred(
-; CHECK-NEXT: [[SH1:%.*]] = shl i32 1, [[Y:%.*]]
+; CHECK-NEXT: [[SH1:%.*]] = shl nuw i32 1, [[Y:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SH1]], [[X:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[AND]], 0
; CHECK-NEXT: [[R:%.*]] = zext i1 [[CMP]] to i32
define i32 @zext_or_masked_bit_test(i32 %a, i32 %b, i32 %x) {
; CHECK-LABEL: @zext_or_masked_bit_test(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[A:%.*]]
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 0
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[B]]
define i32 @zext_or_masked_bit_test_uses(i32 %a, i32 %b, i32 %x) {
; CHECK-LABEL: @zext_or_masked_bit_test_uses(
-; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[A:%.*]]
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 0
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[B]]