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,25 @@ 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())) { + Value *NewV = nullptr; + Domain Divisor = getDomain(SDI->getOperand(1), LVI, SDI); + if (Divisor == Domain::NonNegative) + NewV = SDI->getOperand(0); + else if (Divisor == Domain::NonPositive) + NewV = BinaryOperator::CreateNeg( + SDI->getOperand(0), SDI->getOperand(0)->getName() + ".neg", SDI); + + if (NewV) { + SDI->replaceAllUsesWith(NewV); + 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,8 @@ ; 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: [[X_NEG:%.*]] = sub i8 0, [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X_NEG]], [[X]] ; CHECK-NEXT: ret void ; CHECK: if.then: ; CHECK-NEXT: ret void