Skip to content

Commit

Permalink
[CVP] Simplify minmax at use
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw committed Feb 1, 2025
1 parent bac0840 commit d5d2f34
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 26 deletions.
73 changes: 49 additions & 24 deletions llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,38 +579,63 @@ static bool processCmpIntrinsic(CmpIntrinsic *CI, LazyValueInfo *LVI) {
// See if this min/max intrinsic always picks it's one specific operand.
// If not, check whether we can canonicalize signed minmax into unsigned version
static bool processMinMaxIntrinsic(MinMaxIntrinsic *MM, LazyValueInfo *LVI) {
bool Changed = false;
CmpInst::Predicate Pred = CmpInst::getNonStrictPredicate(MM->getPredicate());
ConstantRange LHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(0),
/*UndefAllowed*/ false);
ConstantRange RHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(1),
/*UndefAllowed*/ false);
if (LHS_CR.icmp(Pred, RHS_CR)) {
++NumMinMax;
MM->replaceAllUsesWith(MM->getLHS());
MM->eraseFromParent();
return true;
for (Use &U : make_early_inc_range(MM->uses())) {
ConstantRange LHS_CR =
ConstantRange::getEmpty(MM->getType()->getScalarSizeInBits());
ConstantRange RHS_CR = LHS_CR;
auto *CxtI = cast<Instruction>(U.getUser());
if (auto *PN = dyn_cast<PHINode>(CxtI)) {
BasicBlock *FromBB = PN->getIncomingBlock(U);
LHS_CR = LVI->getConstantRangeOnEdge(MM->getOperand(0), FromBB,
CxtI->getParent(), CxtI);
RHS_CR = LVI->getConstantRangeOnEdge(MM->getOperand(1), FromBB,
CxtI->getParent(), CxtI);
} else {
LHS_CR = LVI->getConstantRange(MM->getOperand(0), CxtI,
/*UndefAllowed=*/false);
RHS_CR = LVI->getConstantRange(MM->getOperand(1), CxtI,
/*UndefAllowed=*/false);
}
if (LHS_CR.icmp(Pred, RHS_CR)) {
Changed = true;
++NumMinMax;
U.set(MM->getLHS());
continue;
}
if (RHS_CR.icmp(Pred, LHS_CR)) {
Changed = true;
++NumMinMax;
U.set(MM->getRHS());
continue;
}
}
if (RHS_CR.icmp(Pred, LHS_CR)) {
++NumMinMax;
MM->replaceAllUsesWith(MM->getRHS());

if (MM->use_empty()) {
MM->eraseFromParent();
return true;
}

if (MM->isSigned() &&
ConstantRange::areInsensitiveToSignednessOfICmpPredicate(LHS_CR,
RHS_CR)) {
++NumSMinMax;
IRBuilder<> B(MM);
MM->replaceAllUsesWith(B.CreateBinaryIntrinsic(
MM->getIntrinsicID() == Intrinsic::smin ? Intrinsic::umin
: Intrinsic::umax,
MM->getLHS(), MM->getRHS()));
MM->eraseFromParent();
return true;
if (MM->isSigned()) {
ConstantRange LHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(0),
/*UndefAllowed=*/false);
ConstantRange RHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(1),
/*UndefAllowed=*/false);
if (ConstantRange::areInsensitiveToSignednessOfICmpPredicate(LHS_CR,
RHS_CR)) {
++NumSMinMax;
IRBuilder<> B(MM);
MM->replaceAllUsesWith(B.CreateBinaryIntrinsic(
MM->getIntrinsicID() == Intrinsic::smin ? Intrinsic::umin
: Intrinsic::umax,
MM->getLHS(), MM->getRHS()));
MM->eraseFromParent();
return true;
}
}

return false;
return Changed;
}

// Rewrite this with.overflow intrinsic as non-overflowing.
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/Transforms/CorrelatedValuePropagation/min-max.ll
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,9 @@ define i64 @test_at_use2(i32 %x) {
; CHECK-LABEL: @test_at_use2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X:%.*]], 0
; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 -1)
; CHECK-NEXT: br i1 [[COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[SMAX]] to i64
; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[X]] to i64
; CHECK-NEXT: ret i64 [[EXT]]
; CHECK: if.end:
; CHECK-NEXT: ret i64 0
Expand Down

0 comments on commit d5d2f34

Please sign in to comment.