[llvm] [GlobalISel] Add constant folding support for G_FMA/G_FMAD in the combiner. (PR #65659)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 7 12:56:24 PDT 2023


================
@@ -4621,6 +4622,43 @@ bool CombinerHelper::matchConstantFoldFPBinOp(MachineInstr &MI, ConstantFP* &Mat
   return true;
 }
 
+bool CombinerHelper::matchConstantFoldFMA(MachineInstr &MI,
+                                          ConstantFP *&MatchInfo) {
+  unsigned Opc = MI.getOpcode();
+  auto [_, Op1, Op2, Op3] = MI.getFirst4Regs();
+
+  const ConstantFP *Op3Cst = getConstantFPVRegVal(Op3, MRI);
+  if (!Op3Cst)
+    return false;
+
+  const ConstantFP *Op2Cst = getConstantFPVRegVal(Op2, MRI);
+  if (!Op2Cst)
+    return false;
+
+  const ConstantFP *Op1Cst = getConstantFPVRegVal(Op1, MRI);
+  if (!Op1Cst)
+    return false;
+
+  APFloat Op1F = Op1Cst->getValueAPF();
+  APFloat Op2F = Op2Cst->getValueAPF();
+  APFloat Op3F = Op3Cst->getValueAPF();
+
+  switch (Opc) {
+  case TargetOpcode::G_FMA:
+    Op1F.fusedMultiplyAdd(Op2F, Op3F, APFloat::rmNearestTiesToEven);
+    MatchInfo = ConstantFP::get(MI.getMF()->getFunction().getContext(), Op1F);
+    break;
+  case TargetOpcode::G_FMAD: {
+    APFloat Res = (Op1F * Op2F) + Op3F;
----------------
arsenm wrote:

Should just fold the same as FMA, that's what the IR does for fmuladd. This is also making this host dependent on compiler choice to contract 

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


More information about the llvm-commits mailing list