[llvm] [AMDGPU][DAGCombiner][GlobalISel] Prevent FMA contraction when multiply cannot be eliminated (PR #169735)

Christudasan Devadasan via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 23:15:22 PST 2025


================
@@ -6208,6 +6208,114 @@ static bool hasMoreUses(const MachineInstr &MI0, const MachineInstr &MI1,
                        MRI.use_instr_nodbg_end());
 }
 
+// Check if all uses of a multiply can be contracted into FMA operations.
+// Returns true if all uses of the multiply are contractable, meaning the
+// multiply can potentially be eliminated through FMA contraction.
+// Returns false if any use cannot be contracted, which would mean contracting
+// would duplicate the multiply without reducing the total number of operations.
+//
+// This uses a simple, non-recursive check for the following patterns:
+//   - fmul → fadd/fsub: Direct contraction
+//   - fmul → fneg → fsub: FNEG folds into FMA with negated operand
+//   - fmul → fpext → {fadd, fsub, fma}: FPEXT folds if it can be folded
+//   - fmul → fma: Assume FMA contraction will handle it (to avoid complexity)
+static bool allMulUsesCanBeContracted(const MachineInstr &MulMI,
+                                      const MachineRegisterInfo &MRI,
+                                      const unsigned PreferredFusedOpcode) {
+  const auto &TLI = *MulMI.getMF()->getSubtarget().getTargetLowering();
+  Register MulReg = MulMI.getOperand(0).getReg();
+
+  // Check all uses of the multiply result
+  for (const MachineInstr &UseMI : MRI.use_nodbg_instructions(MulReg)) {
+    unsigned Opcode = UseMI.getOpcode();
+
+    // Direct FADD/FSUB uses
+    if (Opcode == TargetOpcode::G_FADD || Opcode == TargetOpcode::G_FSUB) {
+      continue;
+    }
+
+    // FNEG → FSUB pattern
+    // Also handles FNEG → FPEXT → FSUB
+    if (Opcode == TargetOpcode::G_FNEG) {
+      Register FNegReg = UseMI.getOperand(0).getReg();
+      // ALL users of the FNEG must be contractable FSUBs or FPEXTs leading to
+      // FSUBs
+      for (const MachineInstr &FNegUseMI :
+           MRI.use_nodbg_instructions(FNegReg)) {
+        unsigned FNegUseOpcode = FNegUseMI.getOpcode();
+
+        if (FNegUseOpcode == TargetOpcode::G_FSUB) {
+          continue;
+        }
----------------
cdevadas wrote:

```suggestion
        if (FNegUseOpcode == TargetOpcode::G_FSUB)
          continue;
```

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


More information about the llvm-commits mailing list