Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1932,11 +1932,20 @@ } } - // If this is a signed comparison to 0 and the shift is sign preserving, - // use the shift LHS operand instead; isSignTest may change 'Pred', so only - // do that if we're sure to not continue on in this function. - if (Shl->hasNoSignedWrap() && isSignTest(Pred, *C)) - return new ICmpInst(Pred, X, Constant::getNullValue(X->getType())); + if (Shl->hasNoSignedWrap()) { + // TODO: What other predicates (possibly with extra pre-conditions) can we + // handle here? + if (Pred == ICmpInst::ICMP_SGT) { + APInt ShiftedC = C->ashr(*ShiftAmt); + return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), ShiftedC)); + } + + // If this is a signed comparison to 0 and the shift is sign preserving, + // use the shift LHS operand instead; isSignTest may change 'Pred', so only + // do that if we're sure to not continue on in this function. + if (isSignTest(Pred, *C)) + return new ICmpInst(Pred, X, Constant::getNullValue(X->getType())); + } // Otherwise, if this is a comparison of the sign bit, simplify to and/test. bool TrueIfSigned = false; Index: test/Transforms/InstCombine/icmp-shl-nsw.ll =================================================================== --- test/Transforms/InstCombine/icmp-shl-nsw.ll +++ test/Transforms/InstCombine/icmp-shl-nsw.ll @@ -84,8 +84,7 @@ define i1 @icmp_sgt2(i8 %x) { ; CHECK-LABEL: @icmp_sgt2( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], -127 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -64 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 1 @@ -95,8 +94,7 @@ define i1 @icmp_sgt3(i8 %x) { ; CHECK-LABEL: @icmp_sgt3( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], -16 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -8 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 1 @@ -106,8 +104,7 @@ define i1 @icmp_sgt4(i8 %x) { ; CHECK-LABEL: @icmp_sgt4( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], -2 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 1 @@ -120,8 +117,7 @@ define i1 @icmp_sgt5(i8 %x) { ; CHECK-LABEL: @icmp_sgt5( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 1 @@ -131,8 +127,7 @@ define i1 @icmp_sgt6(i8 %x) { ; CHECK-LABEL: @icmp_sgt6( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], 16 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 8 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 1 @@ -142,8 +137,7 @@ define i1 @icmp_sgt7(i8 %x) { ; CHECK-LABEL: @icmp_sgt7( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], 124 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 62 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 1 @@ -181,8 +175,7 @@ define i1 @icmp_sgt10(i8 %x) { ; CHECK-LABEL: @icmp_sgt10( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 7 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], -127 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 7 @@ -192,8 +185,7 @@ define i1 @icmp_sgt11(i8 %x) { ; CHECK-LABEL: @icmp_sgt11( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 %x, 7 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SHL]], -2 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %shl = shl nsw i8 %x, 7 @@ -205,8 +197,7 @@ define <2 x i1> @icmp_sgt11_vec(<2 x i8> %x) { ; CHECK-LABEL: @icmp_sgt11_vec( -; CHECK-NEXT: [[SHL:%.*]] = shl nsw <2 x i8> %x, -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[SHL]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %shl = shl nsw <2 x i8> %x,