[llvm] [AArch64] Improve lowering of scalar abs(sub(a, b)). (PR #151180)
Ricardo Jesus via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 30 07:14:23 PDT 2025
================
@@ -7118,12 +7118,21 @@ SDValue AArch64TargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
return LowerToPredicatedOp(Op, DAG, AArch64ISD::ABS_MERGE_PASSTHRU);
SDLoc DL(Op);
- SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
- Op.getOperand(0));
- // Generate SUBS & CSEL.
- SDValue Cmp = DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, FlagsVT),
- Op.getOperand(0), DAG.getConstant(0, DL, VT));
- return DAG.getNode(AArch64ISD::CSEL, DL, VT, Op.getOperand(0), Neg,
+ SDValue Val = Op.getOperand(0);
+ SDValue Neg = DAG.getNegative(Val, DL, VT);
+ SDValue Cmp;
+
+ // For abs(sub(lhs, rhs)), we can compare lhs and rhs directly. This allows
+ // reusing the subs operation for the calculation and comparison.
+ if (Val.getOpcode() == ISD::SUB)
+ Cmp = DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, FlagsVT),
+ Val.getOperand(0), Val.getOperand(1));
+ else
----------------
rj-jesus wrote:
The reason I didn't implement this more generally, which I forgot to document, was because I think `subs(sub(a,b), 0) -> subs(a,b)` isn't valid for any use of the flags set by `subs(x, 0)`, and specifically should be invalid for users of the overflow flags C/V (right?). This should be valid here because we only require the N flag for AArch64CC::PL.
I think it would be possible to implement this as a general DAG combine, but we'd need to ensure the users of the `subs` (or hypothetically other flag-setting ops) only use the N/Z flags. Is this what you had in mind, or did I miss anything?
https://github.com/llvm/llvm-project/pull/151180
More information about the llvm-commits
mailing list