[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