[llvm] AMDGPU: Libcall expand fast pow/powr/pown/rootn for float case (PR #180553)
Steffen Larsen via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 10 00:21:38 PST 2026
================
@@ -1170,6 +1198,260 @@ bool AMDGPULibCalls::fold_rootn(FPMathOperator *FPOp, IRBuilder<> &B,
return false;
}
+// is_integer(y) => trunc(y) == y
+static Value *emitIsInteger(IRBuilder<> &B, Value *Y) {
+ Value *TruncY = B.CreateUnaryIntrinsic(Intrinsic::trunc, Y);
+ return B.CreateFCmpOEQ(TruncY, Y);
+}
+
+static Value *emitIsEvenInteger(IRBuilder<> &B, Value *Y) {
+ // Even integers are still integers after division by 2.
+ auto *HalfY = B.CreateFMul(Y, ConstantFP::get(Y->getType(), 0.5));
+ return emitIsInteger(B, HalfY);
+}
+
+// is_odd_integer(y) => is_integer(y) && !is_even_integer(y)
+static Value *emitIsOddInteger(IRBuilder<> &B, Value *Y) {
+ Value *IsIntY = emitIsInteger(B, Y);
+ Value *IsEvenY = emitIsEvenInteger(B, Y);
+ Value *NotEvenY = B.CreateNot(IsEvenY);
+ return B.CreateAnd(IsIntY, NotEvenY);
+}
----------------
steffenlarsen wrote:
Ah, sorry! The last "not" is not right. As for casting, a bitcast isn't sufficient as we rely on being able to check the "odd bit" of two's complement based integers. Digging a little deeper, we should be able to use the saturated FP-to-SI cast for this, which lets us handle otherwise poisoning floating point values (NaN, inf, etc.):
```suggestion
// is_odd_integer(y) => is_integer(y) && !((iN)trunc(y) & 1)
static Value *emitIsOddInteger(IRBuilder<> &B, Value *Y) {
LLVMContext &C = B.getContext();
Value *IsIntY = emitIsInteger(B, Y);
auto *TruncIntTy = IntegerType::get(C, Y->getType()->getPrimitiveSizeInBits());
auto *One = ConstantInt::get(TruncIntTy, 1);
Value *TruncY = B.CreateIntrinsic(Intrinsic::fptosi_sat,
{TruncIntTy, Y->getType()}, Y);
Value *CheckOddBit = B.CreateAnd(TruncY, One);
Value *IsOddY = CreateICmpEQ(CheckOddBit, One);
return B.CreateAnd(IsIntY, IsOddY);
}
```
Without having tested it locally, it should end up looking something like [this](https://alive2.llvm.org/ce/z/wXmWJ9), though it looks like it's timing out.
https://github.com/llvm/llvm-project/pull/180553
More information about the llvm-commits
mailing list