[llvm] AMDGPU: Libcall expand fast pow/powr/pown/rootn for float case (PR #180553)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 00:27:37 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);
+}
----------------
arsenm wrote:

```
----------------------------------------
define i1 @src(float %ay) {
entry:
  %#0 = trunc float %ay
  %cmp.i = fcmp oeq float %#0, %ay
  %mul.i = fmul float %ay, 0.500000
  %#1 = trunc float %mul.i
  %cmp.i.i = fcmp une float %#1, %mul.i
  %#2 = and i1 %cmp.i, %cmp.i.i
  ret i1 %#2
}
=>
define i1 @tgt(float %ay) {
entry:
  %astype = fptosi_sat float %ay to i32
  %#0 = trunc float %ay
  %cmp.i = fcmp oeq float %#0, %ay
  %and = and i32 %astype, 1
  %cmp = icmp eq i32 %and, 1
  %#1 = and i1 %cmp.i, %cmp
  ret i1 %#1
}
Transformation doesn't verify!

ERROR: Value mismatch

Example:
float %ay = #x6b841841 (319385488046169427334397952)

Source:
float %#0 = #x6b841841 (319385488046169427334397952)
i1 %cmp.i = #x1 (1)
float %mul.i = #x6b041841 (159692744023084713667198976)
float %#1 = #x6b041841 (159692744023084713667198976)
i1 %cmp.i.i = #x0 (0)
i1 %#2 = #x0 (0)

Target:
i32 %astype = #x7fffffff (2147483647)
float %#0 = #x6b841841 (319385488046169427334397952)
i1 %cmp.i = #x1 (1)
i32 %and = #x00000001 (1)
i1 %cmp = #x1 (1)
i1 %#1 = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)

```

https://github.com/llvm/llvm-project/pull/180553


More information about the llvm-commits mailing list