[llvm] [AMDGPU] Gate fold_pow(x, ±0.5)->sqrt/rsqrt on nsz+ninf fast-math flags (PR #205592)

Wooseok Lee via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 25 07:10:37 PDT 2026


================
@@ -935,18 +935,30 @@ bool AMDGPULibCalls::fold_pow(FPMathOperator *FPOp, IRBuilder<> &B,
   }
 
   if (CF && (CF->isExactlyValue(0.5) || CF->isExactlyValue(-0.5))) {
-    // pow[r](x, [-]0.5) = sqrt(x)
-    bool issqrt = CF->isExactlyValue(0.5);
-    if (FunctionCallee FPExpr =
-            getFunction(M, AMDGPULibFunc(issqrt ? AMDGPULibFunc::EI_SQRT
-                                                : AMDGPULibFunc::EI_RSQRT,
-                                         FInfo))) {
-      LLVM_DEBUG(errs() << "AMDIC: " << *FPOp << " ---> " << FInfo.getName()
-                        << '(' << *opr0 << ")\n");
-      Value *nval = CreateCallEx(B,FPExpr, opr0, issqrt ? "__pow2sqrt"
-                                                        : "__pow2rsqrt");
-      replaceCall(FPOp, nval);
-      return true;
+    // pow[r](x, [-]0.5) = sqrt(x) / rsqrt(x)
+    //
+    // sqrt/rsqrt and pow disagree on two negative inputs:
+    //   pow(-Inf, 0.5) == +Inf  but  sqrt(-Inf) == NaN   (ninf case)
+    //   pow(-0.0, 0.5) == +0.0  but  sqrt(-0.0) == -0.0  (nsz case)
+    // powr requires x >= 0 by the OpenCL spec, so -Inf is undefined behaviour
+    // and the ninf check can be skipped for powr/powr_fast. -0.0 is a valid
+    // input for powr since -0.0 >= 0 by IEEE comparison, so nsz is still
+    // required for all variants.
+    bool isPowr = FInfo.getId() == AMDGPULibFunc::EI_POWR ||
----------------
wooseoklee wrote:

Thanks. I will fix it.

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


More information about the llvm-commits mailing list