[llvm] [AMDGPU] Handle negated f16 and fp conversion DAG combines (PR #213202)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 1 13:21:10 PDT 2026


================
@@ -940,6 +942,40 @@ SDValue AMDGPUTargetLowering::getNegatedExpression(
       return SDValue();
     break;
   }
+  case ISD::FP16_TO_FP: {
+    // If the Users of the Op can handle the negation, defer it for that Op
+    // and do not handle the conversion
+    if (allUsesHaveSourceMods(Op.getNode()))
+      return SDValue();
+
+    SDValue Src = Op.getOperand(0);
+    EVT VT = Op.getValueType();
+    EVT SrcVT = Src.getValueType();
+    SDLoc SL(Op);
+    Cost = NegatibleCost::Neutral;
+    SDValue Negated = DAG.getNode(ISD::XOR, SL, SrcVT, Src,
+                                  DAG.getConstant(0x8000, SL, SrcVT));
+    return DAG.getNode(ISD::FP16_TO_FP, SL, VT, Negated);
+  }
+  case ISD::FP_TO_FP16: {
+    if (allUsesHaveSourceMods(Op.getNode()))
+      return SDValue();
+
+    SDValue Src = Op.getOperand(0);
+    EVT VT = Op.getValueType();
+    EVT SrcVT = Src.getValueType();
+    SDLoc SL(Op);
+
+    if (Src->getOpcode() == ISD::FNEG) {
+      Cost = NegatibleCost::Cheaper;
+      // Negative of Negative is the Source Operand itself
+      // -(FP_TO_FP16(FNEG(X)) = FP_TO_FP16(X)
+      return DAG.getNode(ISD::FP_TO_FP16, SL, VT, Src->getOperand(0));
+    }
+    Cost = NegatibleCost::Neutral;
----------------
HalfBloodPrince010 wrote:

For ordinary `fptrunc` patterns, `getNegatedExpression` is invoked while the conversion is still represented as `FP_ROUND`. 

However I was able to reach the `FP_TO_FP16` switch case with another pattern, but `allUsesHaveSourceMods()` returned true and the guard prevented the negation from being pushed into the source. 

If you have any pointers on an IR pattern that produces FP_TO_FP16 path past this guard, I can try it.

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


More information about the llvm-commits mailing list