Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -1228,8 +1228,19 @@ return X; // shl nuw i8 C, %x -> C iff C has sign bit set. - if (isNUW && match(Op0, m_Negative())) - return Op0; + if (isNUW) { + if (match(Op0, m_Constant())) + return match(Op0, m_Negative()) ? Op0 : nullptr; + + // If Op0 is a constant, then ^ would already have definitively told us + // if it is negative, thus no point in going further it it is a constant. + + if (computeKnownBits(Op0, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT) + .isNegative()) + return Op0; + + // NOTE: Using LazyValueInfo could catch more cases. + } return nullptr; } Index: test/Transforms/InstCombine/select-obo-peo-ops.ll =================================================================== --- test/Transforms/InstCombine/select-obo-peo-ops.ll +++ test/Transforms/InstCombine/select-obo-peo-ops.ll @@ -157,11 +157,10 @@ ; CHECK-LABEL: @test_shl_nuw_nsw__nsw_is_safe( ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079 -; CHECK-NEXT: [[TMP3:%.*]] = shl nuw nsw i32 [[TMP1]], 2 -; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]] +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP1]] +; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP1]] ; CHECK-NEXT: [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]] -; CHECK-NEXT: [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]] -; CHECK-NEXT: ret i32 [[TMP6]] +; CHECK-NEXT: ret i32 [[TMP5]] ; %1 = or i32 %x, -83886080 %2 = icmp eq i32 %1, -83886079 @@ -176,11 +175,10 @@ ; CHECK-LABEL: @test_shl_nuw__nsw_is_safe( ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079 -; CHECK-NEXT: [[TMP3:%.*]] = shl nuw nsw i32 [[TMP1]], 2 -; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]] +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP1]] +; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP1]] ; CHECK-NEXT: [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]] -; CHECK-NEXT: [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]] -; CHECK-NEXT: ret i32 [[TMP6]] +; CHECK-NEXT: ret i32 [[TMP5]] ; %1 = or i32 %x, -83886080 %2 = icmp eq i32 %1, -83886079 Index: test/Transforms/InstSimplify/constantfold-shl-nuw-C-to-C.ll =================================================================== --- test/Transforms/InstSimplify/constantfold-shl-nuw-C-to-C.ll +++ test/Transforms/InstSimplify/constantfold-shl-nuw-C-to-C.ll @@ -44,8 +44,7 @@ ; CHECK-LABEL: @knownbits_negative( ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]] -; CHECK-NEXT: ret i8 [[RET]] +; CHECK-NEXT: ret i8 [[X]] ; %cmp = icmp slt i8 %x, 0 tail call void @llvm.assume(i1 %cmp)