[llvm] [X86][SelectionDAG] - Extend dag combiner to handle pow(1.5f), pow(x,2/3f) (PR #214202)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 07:06:35 PDT 2026


================
@@ -2408,6 +2408,49 @@ Value *LibCallSimplifier::replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B) {
   return Sqrt;
 }
 
+/// Use cube root in place of pow(x, 2/3).
+Value *LibCallSimplifier::replacePowWithCbrt(CallInst *Pow, IRBuilderBase &B) {
+  Value *Base = Pow->getArgOperand(0), *Expo = Pow->getArgOperand(1);
+  Module *Mod = Pow->getModule();
+  Type *Ty = Pow->getType();
+
+  // cbrt() has no vector version; only handle scalar float/double.
+  if (Ty->isVectorTy())
+    return nullptr;
+
+  // pow(-0.0, 2/3) = +0.0; cbrt(-0.0) * cbrt(-0.0) = +0.0.
+  // pow(-inf, 2/3) = +inf; cbrt(-inf) * cbrt(-inf) = +inf.
+  // pow(-val, 2/3) =  nan; cbrt(-val) * cbrt(-val) = num.
+  // For regular numbers, rounding may cause the results to differ.
+  // Therefore, we require { nnan ninf nsz afn } for this transform.
+  if (!Pow->hasNoNaNs() || !Pow->hasNoInfs() || !Pow->hasNoSignedZeros() ||
+      !Pow->hasApproxFunc())
+    return nullptr;
+
+  const APFloat *ExpoF;
+  if (!match(Expo, m_APFloat(ExpoF)))
+    return nullptr;
+
+  bool ExpoIsTwoThirds =
+      (Ty->isFloatTy() && ExpoF->isExactlyValue(2.0f / 3.0f)) ||
+      (Ty->isDoubleTy() && ExpoF->isExactlyValue(2.0 / 3.0));
+  if (!ExpoIsTwoThirds)
+    return nullptr;
+
+  // Do not create a cbrt() libcall if the target does not have it.
+  if (!hasFloatFn(Mod, TLI, Ty, LibFunc_cbrt, LibFunc_cbrtf, LibFunc_cbrtl))
+    return nullptr;
+
+  AttributeList NoAttrs; // Attributes are only meaningful on the original call.
+  Value *Cbrt = emitUnaryFloatFnCall(Base, TLI, LibFunc_cbrt, LibFunc_cbrtf,
+                                     LibFunc_cbrtl, B, NoAttrs);
+  if (!Cbrt)
----------------
arsenm wrote:

Why would this be able to fail? 

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


More information about the llvm-commits mailing list