[llvm] [AArch64] Sanitise pow inputs using a target DAG combine (PR #192958)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 22 08:36:49 PDT 2026
================
@@ -27763,6 +27714,65 @@ static SDValue trySwapVSelectOperands(SDNode *N, SelectionDAG &DAG) {
{InverseSetCC, SelectB, SelectA});
}
+static SDValue performVselectPowCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ SDValue Cond = N->getOperand(0);
+ SDValue TrueVal = N->getOperand(1);
+ SDValue FalseVal = N->getOperand(2);
+ bool TrueValIsPow = TrueVal.getOpcode() == ISD::FPOW;
+ bool FalseValIsPow = FalseVal.getOpcode() == ISD::FPOW;
+
+ // If both inputs are pow we could equally remove the select and simply
+ // select between pow inputs instead.
+ if (TrueValIsPow && FalseValIsPow)
+ return SDValue();
+
+ if ((TrueValIsPow && !TrueVal.hasOneUse()) ||
+ (FalseValIsPow && !FalseVal.hasOneUse()))
+ return SDValue();
+
+ EVT VT = N->getValueType(0);
+ RTLIB::Libcall LC = RTLIB::getPOW(VT);
+ SelectionDAG &DAG = DCI.DAG;
+ auto &TLI = DAG.getTargetLoweringInfo();
+ bool HasLibCall =
+ TLI.getLibcallLoweringInfo().getLibcallImpl(LC) != RTLIB::Unsupported;
+ if (!HasLibCall)
+ return SDValue();
+
+ // TODO: For scalable vectors we should really just be able to pass in the
+ // mask when lowering FPOW to a call instruction.
+
+ // For a given call pow(x, y) when x=1.0 it is guaranteed to return 1.0 for
+ // any value of y.
+ SDLoc DL(N);
+ SDValue One = DAG.getConstantFP(1.0, DL, VT.getVectorElementType());
+ SDValue SplatOne = DAG.getSplatVector(VT, DL, One);
+
+ SDValue OldPow = TrueValIsPow ? TrueVal : FalseVal;
+ SDValue OldPowArg0 = OldPow->getOperand(0);
+
+ // Bail out if argument 0 is already a select.
+ if (OldPowArg0.getOpcode() == ISD::VSELECT)
+ return SDValue();
+
+ SDValue NewPowArg0;
+ if (TrueValIsPow)
+ NewPowArg0 = DAG.getNode(ISD::VSELECT, DL, VT, Cond, OldPowArg0, SplatOne);
+ else
+ NewPowArg0 = DAG.getNode(ISD::VSELECT, DL, VT, Cond, SplatOne, OldPowArg0);
+ SDValue NewPow =
+ DAG.getNode(ISD::FPOW, DL, VT, NewPowArg0, OldPow->getOperand(1));
+ NewPow->setFlags(OldPow->getFlags());
----------------
paulwalker-arm wrote:
```suggestion
DAG.getNode(ISD::FPOW, DL, VT, NewPowArg0, OldPow->getOperand(1), OldPow->getFlags());
```
https://github.com/llvm/llvm-project/pull/192958
More information about the llvm-commits
mailing list