diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -843,6 +843,15 @@ if (SDI->getType()->isVectorTy()) return false; + ConstantRange LCR = LVI->getConstantRange(SDI->getOperand(0), SDI); + ConstantRange RCR = LVI->getConstantRange(SDI->getOperand(1), SDI); + + if (LCR.abs().icmp(CmpInst::ICMP_ULT, RCR.abs())) { + SDI->replaceAllUsesWith(SDI->getOperand(0)); + SDI->eraseFromParent(); + return true; + } + struct Operand { Value *V; Domain D; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll b/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll @@ -523,8 +523,7 @@ ; CHECK-NEXT: [[AND_COND:%.*]] = and i1 [[AND_X]], [[Y_CMP]] ; CHECK-NEXT: br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] ; CHECK: if.else: -; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REM]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X]], [[X]] ; CHECK-NEXT: ret void ; CHECK: if.then: ; CHECK-NEXT: ret void @@ -558,8 +557,7 @@ ; CHECK-NEXT: [[AND_COND:%.*]] = and i1 [[AND_X]], [[AND_Y]] ; CHECK-NEXT: br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] ; CHECK: if.else: -; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REM]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X]], [[X]] ; CHECK-NEXT: ret void ; CHECK: if.then: ; CHECK-NEXT: ret void @@ -595,8 +593,7 @@ ; CHECK-NEXT: [[AND_COND:%.*]] = and i1 [[AND_X]], [[AND_Y]] ; CHECK-NEXT: br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] ; CHECK: if.else: -; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REM]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X]], [[X]] ; CHECK-NEXT: ret void ; CHECK: if.then: ; CHECK-NEXT: ret void