[llvm] [DAG]Add splat_vector to TargetLowering::getNegatedExpression (PR #173967)

Liao Chunyu via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 31 03:27:08 PST 2025


================
@@ -7554,6 +7554,19 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
     Cost = NegatibleCost::Neutral;
     return CFP;
   }
+  case ISD::SPLAT_VECTOR: {
+    SDValue X = Op.getOperand(0);
+    if (!isOperationLegal(ISD::SPLAT_VECTOR, VT))
+      break;
+
+    NegatibleCost CostX = NegatibleCost::Expensive;
+    SDValue NegX =
+        getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
+    if (!NegX || CostX >= NegatibleCost::Neutral)
----------------
ChunyuLiao wrote:

```
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index da0f2b412af1..8d4afd374135 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -7562,7 +7562,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
     NegatibleCost CostX = NegatibleCost::Expensive;
     SDValue NegX =
         getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
-    if (!NegX || CostX >= NegatibleCost::Neutral)
+    if (!NegX || CostX > NegatibleCost::Neutral)
       break;
     Cost = CostX;
     return DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, NegX);
diff --git a/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll b/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll
index 905d110e001c..cdaf083d981c 100644
--- a/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll
@@ -753,8 +753,8 @@ define <vscale x 2 x double> @fmul_d_immtwo(<vscale x 2 x double> %a) #0 {
 define <vscale x 8 x half> @fsub_h_immhalf(<vscale x 8 x half> %a) #0 {
 ; CHECK-LABEL: fsub_h_immhalf:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.h
-; CHECK-NEXT:    fsub z0.h, p0/m, z0.h, #0.5
+; CHECK-NEXT:    fmov z1.h, #-0.50000000
+; CHECK-NEXT:    fadd z0.h, z0.h, z1.h
 ; CHECK-NEXT:    ret
   %out = fsub <vscale x 8 x half> %a, splat(half 0.500000e+00)
   ret <vscale x 8 x half> %out
@@ -763,8 +763,8 @@ define <vscale x 8 x half> @fsub_h_immhalf(<vscale x 8 x half> %a) #0 {
 define <vscale x 8 x half> @fsub_h_immone(<vscale x 8 x half> %a) #0 {
 ; CHECK-LABEL: fsub_h_immone:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.h
-; CHECK-NEXT:    fsub z0.h, p0/m, z0.h, #1.0
+; CHECK-NEXT:    fmov z1.h, #-1.00000000
+; CHECK-NEXT:    fadd z0.h, z0.h, z1.h
 ; CHECK-NEXT:    ret
   %out = fsub <vscale x 8 x half> %a, splat(half 1.000000e+00)
   ret <vscale x 8 x half> %out
@@ -773,8 +773,9 @@ define <vscale x 8 x half> @fsub_h_immone(<vscale x 8 x half> %a) #0 {
 define <vscale x 4 x half> @fsub_4h_immhalf(<vscale x 4 x half> %a) #0 {
 ; CHECK-LABEL: fsub_4h_immhalf:
 ; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov z1.h, #-0.50000000
 ; CHECK-NEXT:    ptrue p0.s
-; CHECK-NEXT:    fsub z0.h, p0/m, z0.h, #0.5
+; CHECK-NEXT:    fadd z0.h, p0/m, z0.h, z1.h
 ; CHECK-NEXT:    ret
   %out = fsub <vscale x 4 x half> %a, splat(half 0.500000e+00)
   ret <vscale x 4 x half> %out
```
Here, the cost is set to NegatibleCost::Neutral, and AArch64 experiences some regressions. So, I'm wondering if it should be implemented under RISCV using TLI.getNegatedExpression() for splat_vector. If this logic benefits other architectures, then I can abandon this idea.

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


More information about the llvm-commits mailing list