Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1212,6 +1212,15 @@ return BinaryOperator::CreateOr(And, ConstantInt::get(I.getType(), Together)); } + const APInt *ShlC; + if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_APInt(ShlC))))) { + if (!isa(X) || !cast(X)->isShift()) { + Constant *NewMask = ConstantInt::get(I.getType(), C->lshr(*ShlC)); + Value *NewAnd = Builder.CreateAnd(X, NewMask); + return BinaryOperator::CreateShl(NewAnd, + ConstantInt::get(I.getType(), *ShlC)); + } + } // If the mask is only needed on one incoming arm, push the 'and' op up. if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_Value(Y)))) || Index: lib/Transforms/InstCombine/InstCombineShifts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineShifts.cpp +++ lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -505,7 +505,10 @@ // If the operand is a bitwise operator with a constant RHS, and the // shift is the only use, we can pull it out of the shift. const APInt *Op0C; - if (match(Op0BO->getOperand(1), m_APInt(Op0C))) { + if (match(Op0BO->getOperand(1), m_APInt(Op0C)) && + ((!isLeftShift || Op0BO->getOpcode() != Instruction::And) || + (isa(Op0BO->getOperand(0)) && + cast(Op0BO->getOperand(0))->isShift()))) { if (canShiftBinOpWithConstantRHS(I, Op0BO, *Op0C)) { Constant *NewRHS = ConstantExpr::get(I.getOpcode(), cast(Op0BO->getOperand(1)), Op1); Index: test/Transforms/InstCombine/2010-11-01-lshr-mask.ll =================================================================== --- test/Transforms/InstCombine/2010-11-01-lshr-mask.ll +++ test/Transforms/InstCombine/2010-11-01-lshr-mask.ll @@ -4,8 +4,8 @@ define i32 @main(i32 %argc) { ; CHECK-LABEL: @main( ; CHECK-NEXT: [[TMP3151:%.*]] = trunc i32 %argc to i8 -; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[TMP3151]], 5 -; CHECK-NEXT: [[TMP4126:%.*]] = and i8 [[TMP1]], 64 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[TMP3151]], 2 +; CHECK-NEXT: [[TMP4126:%.*]] = shl nuw nsw i8 [[TMP1]], 5 ; CHECK-NEXT: [[TMP4127:%.*]] = xor i8 [[TMP4126]], 64 ; CHECK-NEXT: [[TMP4086:%.*]] = zext i8 [[TMP4127]] to i32 ; CHECK-NEXT: ret i32 [[TMP4086]] Index: test/Transforms/InstCombine/bswap.ll =================================================================== --- test/Transforms/InstCombine/bswap.ll +++ test/Transforms/InstCombine/bswap.ll @@ -98,7 +98,14 @@ ; PR23863 define i32 @test7(i32 %x) { ; CHECK-LABEL: @test7( -; CHECK-NEXT: [[OR6:%.*]] = call i32 @llvm.bswap.i32(i32 %x) +; CHECK-NEXT: [[SHL:%.*]] = shl i32 %x, 16 +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 %x, 16 +; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR]], 16711935 +; CHECK-NEXT: [[SHL3:%.*]] = shl nuw i32 [[TMP1]], 8 +; CHECK-NEXT: [[AND4:%.*]] = lshr i32 [[OR]], 8 +; CHECK-NEXT: [[SHR5:%.*]] = and i32 [[AND4]], 16711935 +; CHECK-NEXT: [[OR6:%.*]] = or i32 [[SHL3]], [[SHR5]] ; CHECK-NEXT: ret i32 [[OR6]] ; %shl = shl i32 %x, 16 @@ -141,9 +148,13 @@ define i16 @test10(i32 %a) { ; CHECK-LABEL: @test10( -; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 %a to i16 -; CHECK-NEXT: [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]]) -; CHECK-NEXT: ret i16 [[REV]] +; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 %a, 8 +; CHECK-NEXT: [[AND1:%.*]] = and i32 [[SHR1]], 255 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 255 +; CHECK-NEXT: [[SHL1:%.*]] = shl nuw nsw i32 [[TMP1]], 8 +; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND1]], [[SHL1]] +; CHECK-NEXT: [[CONV:%.*]] = trunc i32 [[OR]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %shr1 = lshr i32 %a, 8 %and1 = and i32 %shr1, 255 Index: test/Transforms/InstCombine/cast.ll =================================================================== --- test/Transforms/InstCombine/cast.ll +++ test/Transforms/InstCombine/cast.ll @@ -589,8 +589,8 @@ define i64 @test46(i64 %A) { ; CHECK-LABEL: @test46( -; CHECK-NEXT: [[C:%.*]] = shl i64 %A, 8 -; CHECK-NEXT: [[D:%.*]] = and i64 [[C]], 10752 +; CHECK-NEXT: [[C:%.*]] = and i64 %A, 42 +; CHECK-NEXT: [[D:%.*]] = shl nuw nsw i64 [[C]], 8 ; CHECK-NEXT: ret i64 [[D]] ; %B = trunc i64 %A to i32 @@ -602,8 +602,8 @@ define <2 x i64> @test46vec(<2 x i64> %A) { ; CHECK-LABEL: @test46vec( -; CHECK-NEXT: [[C:%.*]] = shl <2 x i64> [[A:%.*]], -; CHECK-NEXT: [[D:%.*]] = and <2 x i64> [[C]], +; CHECK-NEXT: [[C:%.*]] = and <2 x i64> %A, +; CHECK-NEXT: [[D:%.*]] = shl nuw nsw <2 x i64> [[C]], ; CHECK-NEXT: ret <2 x i64> [[D]] ; %B = trunc <2 x i64> %A to <2 x i32> @@ -811,13 +811,12 @@ define i64 @test59(i8 %A, i8 %B) nounwind { ; CHECK-LABEL: @test59( -; CHECK-NEXT: [[C:%.*]] = zext i8 %A to i64 -; CHECK-NEXT: [[D:%.*]] = shl nuw nsw i64 [[C]], 4 -; CHECK-NEXT: [[E:%.*]] = and i64 [[D]], 48 -; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 %B, 4 -; CHECK-NEXT: [[G:%.*]] = zext i8 [[TMP1]] to i64 -; CHECK-NEXT: [[H:%.*]] = or i64 [[E]], [[G]] -; CHECK-NEXT: ret i64 [[H]] +; CHECK-NEXT: [[TMP1:%.*]] = and i8 %A, 3 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i8 [[TMP1]], 4 +; CHECK-NEXT: [[TMP3:%.*]] = lshr i8 %B, 4 +; CHECK-NEXT: [[H:%.*]] = or i8 [[TMP3]], [[TMP2]] +; CHECK-NEXT: [[I:%.*]] = zext i8 [[H]] to i64 +; CHECK-NEXT: ret i64 [[I]] ; %C = zext i8 %A to i32 %D = shl i32 %C, 4 @@ -1277,8 +1276,8 @@ define i64 @test82(i64 %A) nounwind { ; CHECK-LABEL: @test82( -; CHECK-NEXT: [[TMP1:%.*]] = shl i64 %A, 1 -; CHECK-NEXT: [[E:%.*]] = and i64 [[TMP1]], 4294966784 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 %A, 2147483392 +; CHECK-NEXT: [[E:%.*]] = shl nuw nsw i64 %1, 1 ; CHECK-NEXT: ret i64 [[E]] ; %B = trunc i64 %A to i32 Index: test/Transforms/InstCombine/or-shifted-masks.ll =================================================================== --- test/Transforms/InstCombine/or-shifted-masks.ll +++ test/Transforms/InstCombine/or-shifted-masks.ll @@ -2,10 +2,10 @@ define i32 @or_and_shifts1(i32 %x) { ; CHECK-LABEL: @or_and_shifts1( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 8 -; CHECK-NEXT: [[TMP3:%.*]] = shl i32 %x, 5 -; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 32 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 1 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 3 +; CHECK-NEXT: [[TMP3:%.*]] = and i32 %x, 1 +; CHECK-NEXT: [[TMP4:%.*]] = shl nuw nsw i32 [[TMP3]], 5 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] ; CHECK-NEXT: ret i32 [[TMP5]] ; @@ -19,8 +19,8 @@ define i32 @or_and_shifts2(i32 %x) { ; CHECK-LABEL: @or_and_shifts2( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 896 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 112 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 3 ; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 %x, 4 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 7 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] @@ -36,10 +36,10 @@ define i32 @or_and_shift_shift_and(i32 %x) { ; CHECK-LABEL: @or_and_shift_shift_and( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 56 -; CHECK-NEXT: [[TMP3:%.*]] = shl i32 %x, 2 -; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 28 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 7 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 3 +; CHECK-NEXT: [[TMP3:%.*]] = and i32 %x, 7 +; CHECK-NEXT: [[TMP4:%.*]] = shl nuw nsw i32 [[TMP3]], 2 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] ; CHECK-NEXT: ret i32 [[TMP5]] ; @@ -53,8 +53,8 @@ define i32 @multiuse1(i32 %x) { ; CHECK-LABEL: @multiuse1( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 6 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 384 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 6 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 6 ; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 %x, 1 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 3 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP4]], [[TMP2]] @@ -74,18 +74,12 @@ define i32 @multiuse2(i32 %x) { ; CHECK-LABEL: @multiuse2( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 1 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 12 -; CHECK-NEXT: [[TMP3:%.*]] = shl i32 %x, 8 -; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 24576 -; CHECK-NEXT: [[TMP5:%.*]] = shl i32 %x, 8 -; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 7680 -; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP4]], [[TMP6]] -; CHECK-NEXT: [[TMP8:%.*]] = shl i32 %x, 1 -; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 240 -; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP2]], [[TMP9]] -; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP7]], [[TMP10]] -; CHECK-NEXT: ret i32 [[TMP11]] +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 126 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 8 +; CHECK-NEXT: [[TMP3:%.*]] = and i32 %x, 126 +; CHECK-NEXT: [[TMP4:%.*]] = shl nuw nsw i32 [[TMP3]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] +; CHECK-NEXT: ret i32 [[TMP5]] ; %1 = and i32 %x, 6 %2 = shl nuw nsw i32 %1, 8 @@ -106,17 +100,15 @@ define i32 @multiuse3(i32 %x) { ; CHECK-LABEL: @multiuse3( -; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 96 -; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 6 -; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i32 [[TMP1]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = shl i32 %x, 6 -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1920 -; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP2]], [[TMP5]] -; CHECK-NEXT: [[TMP7:%.*]] = lshr i32 %x, 1 -; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], 15 -; CHECK-NEXT: [[TMP9:%.*]] = or i32 [[TMP3]], [[TMP8]] -; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP6]] -; CHECK-NEXT: ret i32 [[TMP10]] +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 %x, 1 +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 48 +; CHECK-NEXT: [[TMP3:%.*]] = and i32 %x, 126 +; CHECK-NEXT: [[TMP4:%.*]] = shl nuw nsw i32 [[TMP3]], 6 +; CHECK-NEXT: [[TMP5:%.*]] = lshr i32 %x, 1 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 15 +; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP2]], [[TMP6]] +; CHECK-NEXT: [[TMP8:%.*]] = or i32 [[TMP7]], [[TMP4]] +; CHECK-NEXT: ret i32 [[TMP8]] ; %1 = and i32 %x, 96 %2 = shl nuw nsw i32 %1, 6 @@ -182,14 +174,14 @@ ; CHECK-NEXT: br i1 [[TMP2]], label %if, label %else ; CHECK: {{.*}}if:{{.*}} ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP1]], 21760 -; CHECK-NEXT: [[TMP4:%.*]] = shl i32 %x, 5 -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 43520 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 %x, 1360 +; CHECK-NEXT: [[TMP5:%.*]] = shl nuw nsw i32 [[TMP4]], 5 ; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[TMP3]] ; CHECK-NEXT: br label %end ; CHECK: {{.*}}else:{{.*}} ; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP1]], 5570560 -; CHECK-NEXT: [[TMP8:%.*]] = shl i32 %x, 5 -; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 11141120 +; CHECK-NEXT: [[TMP8:%.*]] = and i32 %x, 348160 +; CHECK-NEXT: [[TMP9:%.*]] = shl nuw nsw i32 [[TMP8]], 5 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP7]] ; CHECK-NEXT: br label %end ; CHECK: {{.*}}end{{.*}} Index: test/Transforms/InstCombine/pr17827.ll =================================================================== --- test/Transforms/InstCombine/pr17827.ll +++ test/Transforms/InstCombine/pr17827.ll @@ -4,8 +4,8 @@ ; With left shift, the comparison should not be modified. define i1 @test_shift_and_cmp_not_changed1(i8 %p) { ; CHECK-LABEL: @test_shift_and_cmp_not_changed1( -; CHECK-NEXT: [[SHLP:%.*]] = shl i8 %p, 5 -; CHECK-NEXT: [[ANDP:%.*]] = and i8 [[SHLP]], -64 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 %p, 6 +; CHECK-NEXT: [[ANDP:%.*]] = shl nuw i8 [[TMP1]], 5 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[ANDP]], 32 ; CHECK-NEXT: ret i1 [[CMP]] ; @@ -33,8 +33,8 @@ ; The extra input parameter should be optimized away. define i1 @test_shift_and_cmp_changed1(i8 %p, i8 %q) { ; CHECK-LABEL: @test_shift_and_cmp_changed1( -; CHECK-NEXT: [[ANDP:%.*]] = shl i8 %p, 5 -; CHECK-NEXT: [[SHL:%.*]] = and i8 [[ANDP]], -64 +; CHECK-NEXT: [[ANDP:%.*]] = and i8 %p, 6 +; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 %andp, 5 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[SHL]], 32 ; CHECK-NEXT: ret i1 [[CMP]] ; @@ -49,8 +49,8 @@ define <2 x i1> @test_shift_and_cmp_changed1_vec(<2 x i8> %p, <2 x i8> %q) { ; CHECK-LABEL: @test_shift_and_cmp_changed1_vec( -; CHECK-NEXT: [[ANDP:%.*]] = shl <2 x i8> [[P:%.*]], -; CHECK-NEXT: [[SHL:%.*]] = and <2 x i8> [[ANDP]], +; CHECK-NEXT: [[ANDP:%.*]] = and <2 x i8> %p, +; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i8> [[ANDP]], ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[SHL]], ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; @@ -66,8 +66,8 @@ ; Unsigned compare allows a transformation to compare against 0. define i1 @test_shift_and_cmp_changed2(i8 %p) { ; CHECK-LABEL: @test_shift_and_cmp_changed2( -; CHECK-NEXT: [[ANDP:%.*]] = and i8 %p, 6 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[ANDP]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 %p, 6 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %shlp = shl i8 %p, 5 @@ -91,8 +91,8 @@ ; nsw on the shift should not affect the comparison. define i1 @test_shift_and_cmp_changed3(i8 %p) { ; CHECK-LABEL: @test_shift_and_cmp_changed3( -; CHECK-NEXT: [[SHLP:%.*]] = shl nsw i8 %p, 5 -; CHECK-NEXT: [[ANDP:%.*]] = and i8 [[SHLP]], -64 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 %p, 6 +; CHECK-NEXT: [[ANDP:%.*]] = shl nuw i8 [[TMP1]], 5 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[ANDP]], 32 ; CHECK-NEXT: ret i1 [[CMP]] ; Index: test/Transforms/InstCombine/rem.ll =================================================================== --- test/Transforms/InstCombine/rem.ll +++ test/Transforms/InstCombine/rem.ll @@ -362,8 +362,8 @@ define i32 @test18(i16 %x, i32 %y) { ; CHECK-LABEL: @test18( -; CHECK-NEXT: [[TMP1:%.*]] = shl i16 %x, 3 -; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 32 +; CHECK-NEXT: [[TMP1:%.*]] = and i16 %x, 4 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i16 [[TMP1]], 3 ; CHECK-NEXT: [[TMP3:%.*]] = xor i16 [[TMP2]], 63 ; CHECK-NEXT: [[TMP4:%.*]] = zext i16 [[TMP3]] to i32 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], %y Index: test/Transforms/InstCombine/select-bitext-bitwise-ops.ll =================================================================== --- test/Transforms/InstCombine/select-bitext-bitwise-ops.ll +++ test/Transforms/InstCombine/select-bitext-bitwise-ops.ll @@ -21,11 +21,13 @@ define i64 @sel_false_val_is_a_masked_shl_of_true_val2(i32 %x, i64 %y) { ; CHECK-LABEL: @sel_false_val_is_a_masked_shl_of_true_val2( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 2 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 60 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 15 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2 ; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64 -; CHECK-NEXT: [[TMP4:%.*]] = ashr i64 %y, [[TMP3]] -; CHECK-NEXT: ret i64 [[TMP4]] +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP1]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i64 0, i64 [[TMP3]] +; CHECK-NEXT: [[TMP6:%.*]] = ashr i64 %y, [[TMP5]] +; CHECK-NEXT: ret i64 [[TMP6]] ; %1 = and i32 %x, 15 %2 = shl nuw nsw i32 %1, 2 Index: test/Transforms/InstCombine/select-with-bitwise-ops.ll =================================================================== --- test/Transforms/InstCombine/select-with-bitwise-ops.ll +++ test/Transforms/InstCombine/select-with-bitwise-ops.ll @@ -5,8 +5,8 @@ define i32 @select_icmp_eq_and_1_0_or_2(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2( -; CHECK-NEXT: [[AND:%.*]] = shl i32 %x, 1 -; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2 +; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 1 +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[AND]], 1 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], %y ; CHECK-NEXT: ret i32 [[TMP2]] ; @@ -19,8 +19,8 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec( -; CHECK-NEXT: [[AND:%.*]] = shl <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[AND]], +; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> %x, +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw <2 x i32> [[AND]], ; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: ret <2 x i32> [[TMP2]] ; @@ -337,8 +337,8 @@ define i32 @select_icmp_ne_0_and_32_or_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_32_or_4096( -; CHECK-NEXT: [[AND:%.*]] = shl i32 %x, 7 -; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 4096 +; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 32 +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[AND]], 7 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 4096 ; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP2]], %y ; CHECK-NEXT: ret i32 [[TMP3]] @@ -352,8 +352,8 @@ define <2 x i32> @select_icmp_ne_0_and_32_or_4096_vec(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_32_or_4096_vec( -; CHECK-NEXT: [[AND:%.*]] = shl <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[AND]], +; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> %x, +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw <2 x i32> [[AND]], ; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], ; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i32> [[TMP2]], [[Y:%.*]] ; CHECK-NEXT: ret <2 x i32> [[TMP3]] @@ -970,10 +970,10 @@ define i32 @shift_no_xor_multiuse_or(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_no_xor_multiuse_or( -; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2 -; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1 -; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2 -; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[Y]] +; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 1 +; CHECK-NEXT: [[OR:%.*]] = or i32 %y, 2 +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[AND]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], %y ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[TMP2]], [[OR]] ; CHECK-NEXT: ret i32 [[RES]] ; Index: test/Transforms/InstCombine/select.ll =================================================================== --- test/Transforms/InstCombine/select.ll +++ test/Transforms/InstCombine/select.ll @@ -385,8 +385,8 @@ %t3 = select i1 %t2, i32 256, i32 0 ret i32 %t3 ; CHECK-LABEL: @test15e( -; CHECK: %t1 = shl i32 %X, 1 -; CHECK: and i32 %t1, 256 +; CHECK: %t1 = and i32 %X, 128 +; CHECK: shl nuw nsw i32 %t1, 1 ; CHECK: ret i32 } @@ -397,8 +397,8 @@ %t3 = select i1 %t2, i32 0, i32 256 ret i32 %t3 ; CHECK-LABEL: @test15f( -; CHECK: %t1 = shl i32 %X, 1 -; CHECK: and i32 %t1, 256 +; CHECK: %t1 = and i32 %X, 128 +; CHECK: shl nuw nsw i32 %t1, 1 ; CHECK: xor i32 %{{.*}}, 256 ; CHECK: ret i32 } @@ -433,8 +433,8 @@ %t3 = select i1 %t2, i32 577, i32 1089 ret i32 %t3 ; CHECK-LABEL: @test15i( -; CHECK-NEXT: %t1 = shl i32 %X, 8 -; CHECK-NEXT: %1 = and i32 %t1, 512 +; CHECK-NEXT: %t1 = and i32 %X, 2 +; CHECK-NEXT: %1 = shl nuw nsw i32 %t1, 8 ; CHECK-NEXT: %2 = xor i32 %1, 512 ; CHECK-NEXT: %3 = add nuw nsw i32 %2, 577 ; CHECK-NEXT: ret i32 %3 @@ -447,8 +447,8 @@ %t3 = select i1 %t2, i32 1089, i32 577 ret i32 %t3 ; CHECK-LABEL: @test15j( -; CHECK-NEXT: %t1 = shl i32 %X, 8 -; CHECK-NEXT: %1 = and i32 %t1, 512 +; CHECK-NEXT: %t1 = and i32 %X, 2 +; CHECK-NEXT: %1 = shl nuw nsw i32 %t1, 8 ; CHECK-NEXT: %2 = add nuw nsw i32 %1, 577 ; CHECK-NEXT: ret i32 %2 } Index: test/Transforms/InstCombine/shift-shift.ll =================================================================== --- test/Transforms/InstCombine/shift-shift.ll +++ test/Transforms/InstCombine/shift-shift.ll @@ -51,11 +51,11 @@ ; CHECK: for.cond: ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ 0, %codeRepl ], [ 5, %for.cond ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* %g, align 4 -; CHECK-NEXT: [[TMP0:%.*]] = shl nuw nsw i32 [[STOREMERGE]], 6 -; CHECK-NEXT: [[CONV2:%.*]] = and i32 [[TMP0]], 64 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[CONV2]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[STOREMERGE]], 1 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TOBOOL]], label %for.cond, label %codeRepl2 ; CHECK: codeRepl2: +; CHECK-NEXT: [[CONV2:%.*]] = shl nuw nsw i32 [[TMP0]], 6 ; CHECK-NEXT: ret i32 [[CONV2]] ; codeRepl: Index: test/Transforms/InstCombine/shift.ll =================================================================== --- test/Transforms/InstCombine/shift.ll +++ test/Transforms/InstCombine/shift.ll @@ -708,11 +708,11 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 %a0 to i8 ; CHECK-NEXT: [[TMP5:%.*]] = shl i8 [[TMP4]], 5 -; CHECK-NEXT: [[TMP49:%.*]] = shl i8 [[TMP4]], 6 -; CHECK-NEXT: [[TMP50:%.*]] = and i8 [[TMP49]], 64 +; CHECK-NEXT: [[TMP49:%.*]] = and i8 [[TMP4]], 1 +; CHECK-NEXT: [[TMP50:%.*]] = shl nuw nsw i8 [[TMP49]], 6 ; CHECK-NEXT: [[TMP51:%.*]] = xor i8 [[TMP50]], [[TMP5]] -; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[TMP4]], 2 -; CHECK-NEXT: [[TMP54:%.*]] = and i8 [[TMP0]], 16 +; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[TMP4]], 4 +; CHECK-NEXT: [[TMP54:%.*]] = shl nuw nsw i8 [[TMP0]], 2 ; CHECK-NEXT: [[TMP551:%.*]] = or i8 [[TMP54]], [[TMP51]] ; CHECK-NEXT: ret i8 [[TMP551]] ; @@ -1055,8 +1055,8 @@ define i8 @test53_no_nuw(i8 %x) { ; CHECK-LABEL: @test53_no_nuw( -; CHECK-NEXT: [[TMP1:%.*]] = shl i8 %x, 2 -; CHECK-NEXT: [[B:%.*]] = and i8 [[TMP1]], 124 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 %x, 31 +; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i8 [[TMP1]], 2 ; CHECK-NEXT: ret i8 [[B]] ; %A = shl i8 %x, 3 @@ -1068,8 +1068,8 @@ define <2 x i8> @test53_no_nuw_splat_vec(<2 x i8> %x) { ; CHECK-LABEL: @test53_no_nuw_splat_vec( -; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> %x, -; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> %x, +; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i8> [[TMP1]], ; CHECK-NEXT: ret <2 x i8> [[B]] ; %A = shl <2 x i8> %x, @@ -1079,8 +1079,8 @@ define i32 @test54(i32 %x) { ; CHECK-LABEL: @test54( -; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP1]], 16 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 2 +; CHECK-NEXT: [[AND:%.*]] = shl nuw nsw i32 [[TMP1]], 3 ; CHECK-NEXT: ret i32 [[AND]] ; %shr2 = lshr i32 %x, 1 @@ -1091,8 +1091,8 @@ define <2 x i32> @test54_splat_vec(<2 x i32> %x) { ; CHECK-LABEL: @test54_splat_vec( -; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> %x, -; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %x, +; CHECK-NEXT: [[AND:%.*]] = shl nuw nsw <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[AND]] ; %shr2 = lshr <2 x i32> %x,