Skip to content

Commit 64dcc5e

Browse files
committed
[ConstraintElim] Optimize usub.sat intrinsic based on known constraints
1 parent 81499ed commit 64dcc5e

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,7 @@ void State::addInfoFor(BasicBlock &BB) {
11321132
case Intrinsic::umax:
11331133
case Intrinsic::smin:
11341134
case Intrinsic::smax:
1135+
case Intrinsic::usub_sat:
11351136
// TODO: handle llvm.abs as well
11361137
WorkList.push_back(
11371138
FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
@@ -1142,7 +1143,6 @@ void State::addInfoFor(BasicBlock &BB) {
11421143
[[fallthrough]];
11431144
case Intrinsic::abs:
11441145
case Intrinsic::uadd_sat:
1145-
case Intrinsic::usub_sat:
11461146
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
11471147
break;
11481148
}
@@ -1519,6 +1519,24 @@ static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
15191519
return false;
15201520
}
15211521

1522+
static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info,
1523+
SmallVectorImpl<Instruction *> &ToRemove) {
1524+
Value *LHS = I->getOperand(0);
1525+
Value *RHS = I->getOperand(1);
1526+
if (checkCondition(ICmpInst::ICMP_UGT, LHS, RHS, I, Info).value_or(false)) {
1527+
IRBuilder<> Builder(I->getParent(), I->getIterator());
1528+
I->replaceAllUsesWith(Builder.CreateSub(LHS, RHS));
1529+
ToRemove.push_back(I);
1530+
return true;
1531+
}
1532+
if (checkCondition(ICmpInst::ICMP_ULE, LHS, RHS, I, Info).value_or(false)) {
1533+
I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
1534+
ToRemove.push_back(I);
1535+
return true;
1536+
}
1537+
return false;
1538+
}
1539+
15221540
static void
15231541
removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
15241542
Module *ReproducerModule,
@@ -1840,6 +1858,11 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
18401858
Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
18411859
} else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
18421860
Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
1861+
} else if (auto *SatIntr = dyn_cast<SaturatingInst>(Inst)) {
1862+
if (SatIntr->getIntrinsicID() == Intrinsic::usub_sat)
1863+
Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove);
1864+
else
1865+
llvm_unreachable("Unexpected intrinsic.");
18431866
}
18441867
continue;
18451868
}

0 commit comments

Comments
 (0)