[llvm] [ConstraintElimination] Add support for UCMP/SCMP intrinsics (PR #97974)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 8 16:07:36 PDT 2024
================
@@ -1434,6 +1436,33 @@ static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
return false;
}
+static bool checkAndReplaceCmp(IntrinsicInst *II, ConstraintInfo &Info,
+ SmallVectorImpl<Instruction *> &ToRemove) {
+ bool IsSigned = II->getIntrinsicID() == Intrinsic::scmp;
+ Value *LHS = II->getOperand(0);
+ Value *RHS = II->getOperand(1);
+ if (checkCondition(IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, LHS,
+ RHS, II, Info)
+ .value_or(false)) {
+ II->replaceAllUsesWith(ConstantInt::get(II->getType(), 1));
+ ToRemove.push_back(II);
+ return true;
+ }
+ if (checkCondition(IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, LHS,
+ RHS, II, Info)
+ .value_or(false)) {
+ II->replaceAllUsesWith(ConstantInt::getSigned(II->getType(), -1));
+ ToRemove.push_back(II);
+ return true;
+ }
+ if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, II, Info).value_or(false)) {
----------------
Poseydon42 wrote:
It's true in principle, but implementing it this way wouldn't fold specifically `scmp` in situations where equality is implied.
E.g. this test case doesn't fold:
```
define i8 @test(i32 noundef %x, i32 noundef %y) {
%cond = icmp eq i32 %x, %y
call void @llvm.assume(i1 %cond)
%r = call i8 @llvm.scmp.i8.i32(i32 %x, i32 %y)
ret i8 %r
}
```
I'm not sure why this is the case, but it looks like when constraint elimination state is fed an assumption that `x == y` it adds the two implied inequalities to its unsigned table, but not to the signed one. That's also why the same test above will fold nicely if you replace `scmp` with `ucmp`. Unless I'm missing something and this implication isn't necessarily correct I'm happy to change my code as per your suggestion and fix the contraint elimination pass in as a whole in a separate PR.
https://github.com/llvm/llvm-project/pull/97974
More information about the llvm-commits
mailing list