Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -728,6 +728,12 @@ default: return nullptr; } + // If x > -1 or x >= 0 is used to verify the legality of lshr, + // it shouldn't be combined. + if (auto *I = dyn_cast(RangeEnd)) + if (I->getOpcode() == Instruction::LShr) + return nullptr; + // This simplification is only valid if the upper range is not negative. KnownBits Known = computeKnownBits(RangeEnd, /*Depth=*/0, Cmp1); if (!Known.isNonNegative()) Index: llvm/test/Transforms/InstCombine/shift.ll =================================================================== --- llvm/test/Transforms/InstCombine/shift.ll +++ llvm/test/Transforms/InstCombine/shift.ll @@ -1851,3 +1851,31 @@ %r = and i8 %s, 7 ; 0b00000111 ret i8 %r } + +define i32 @cmp_lshr_cmp(i32 %0) { +; CHECK-LABEL: @cmp_lshr_cmp( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0:%.*]], 0 +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 7, [[TMP0]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[SHR]], [[TMP0]] +; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP1]] +; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.false: +; CHECK-NEXT: ret i32 1 +; CHECK: cond.end: +; CHECK-NEXT: ret i32 0 +; +entry: + %cmp = icmp slt i32 %0, 0 + %shr = lshr i32 7, %0 + %cmp1 = icmp sgt i32 %0, %shr + %or.cond = or i1 %cmp, %cmp1 + br i1 %or.cond, label %cond.end, label %cond.false + +cond.false: ; preds = %entry + ret i32 1 + +cond.end: ; preds = %entry, %cond.false + ret i32 0 +} +