[llvm] [AArch64] Combine vector FNEG+FMA into `FNML[A|S]` (PR #167900)
Sander de Smalen via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 1 08:35:51 PST 2025
================
@@ -7730,6 +7733,45 @@ SDValue AArch64TargetLowering::LowerFMUL(SDValue Op, SelectionDAG &DAG) const {
return FCVTNT(VT, BottomBF16, Pg, TopF32);
}
+SDValue AArch64TargetLowering::LowerFMA(SDValue Op, SelectionDAG &DAG) const {
+ SDValue OpA = Op->getOperand(0);
+ SDValue OpB = Op->getOperand(1);
+ SDValue OpC = Op->getOperand(2);
+ EVT VT = Op.getValueType();
+ SDLoc DL(Op);
+
+ // Bail early if we're definitely not looking to merge FNEGs into the FMA.
+ if (!VT.isFixedLengthVector() || OpC.getOpcode() != ISD::FNEG) {
+ if (VT.isScalableVector() || VT.getScalarType() == MVT::bf16 ||
+ useSVEForFixedLengthVectorVT(VT, !Subtarget->isNeonAvailable()))
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMA_PRED);
+ return Op; // Fallback to NEON lowering.
+ }
----------------
sdesmalen-arm wrote:
This condition is a little confusing, is the `VT.getScalarType() == MVT::bf16` really required? (when I remove the condition, there are no tests that break for me)
What about pulling out the case where `!VT.isVector()` (in this case, this function doesn't handle it, so return `Op`), and pull out the case where VT is a scalable vector (because the code below is only for fixed-length vectors), so that we end up with:
```
// Scalars are supported by patterns.
if (!VT.isVector())
return Op;
if (VT.isScalableVector())
return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMA_PRED);
if (OpC.getOpcode() != ISD::FNEG) {
if (VT.isScalableVector() ||
useSVEForFixedLengthVectorVT(VT, !Subtarget->isNeonAvailable()))
return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMA_PRED);
return Op; // Fallback to NEON lowering.
}
```
https://github.com/llvm/llvm-project/pull/167900
More information about the llvm-commits
mailing list