https://gcc.gnu.org/g:1d118f7d205907d48d855d12bf2234676d05b069

commit 1d118f7d205907d48d855d12bf2234676d05b069
Author: Michael Meissner <[email protected]>
Date:   Thu Sep 17 18:16:20 2026 -0400

    Optimize bfloat16 a + b + c
    
    2026-09-17  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (peephole2 for bfloat16): Add a 
peephole2 to
            optimize bfloat16 a + b + c to not convert a + b intro scalar and 
back
            into vector.

Diff:
---
 gcc/config/rs6000/float16.md | 79 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index abe88c4ab632..9c88bb10d331 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -1450,3 +1450,82 @@
                              operands[3], FP16_NFMS);
   DONE;
 })
+
+;; Eliminate converts from SF to DF and back to SF done within V4SF
+;; that shows up in optimizing BFmode to use V4SFmode.
+;;
+;; For example:
+;;     __bf16 a, b, c, d;
+;;     // ...
+;;     a = b + c + d;
+;;
+;; would generate:
+;;     (set (reg:SF temp1)
+;;          (plus:SF (float_extend:SF (reg:BF b))
+;;                   (float_extend:SF (reg:BF c))))
+;;
+;;     (set (reg:SF temp2)
+;;          (plus:SF (reg:SF temp1)
+;;                   (float_extend:SF (reg:BF d))))
+;;
+;;     (set (reg:BF a)
+;;          (float_truncte:BF
+;;           (reg:SF temp2)))
+;;
+;; After split1 this would become:
+;;     (set (reg:V4SF temp3)
+;;          (unspec:V4SF [(reg:BF b)] UNSPEC_XXSPLTW_FP16))
+;;
+;;     (set (reg:V4SF temp4)
+;;          (unspec:V4SF [(reg:V4SF temp3)] UNSPEC_XXSPLTW_FP16))
+;;
+;;     (set (reg:V4SF temp5)
+;;          (unspec:V4SF [(reg:BF c)] UNSPEC_XXSPLTW_FP16))
+;;
+;;     (set (reg:V4SF temp6)
+;;          (unspec:V4SF [(reg:V4SF temp5)] UNSPEC_XXSPLTW_FP16))
+;;
+;;     (set (reg:V4SF temp7)
+;;          (unspec:V4SF [(reg:BF d)] UNSPEC_XXSPLTW_FP16))
+;;
+;;     (set (reg:V4SF temp8)
+;;          (unspec:V4SF [(reg:V4SF temp7)] UNSPEC_XXSPLTW_FP16))
+;;
+;;     (set (reg:V4SF temp9)
+;;          (plus:V4SF (reg:V4SF temp4)
+;;                     (reg:V4SF temp6)))
+;;
+;;     (set (reg:SF temp10)
+;;          (unspec:SF [(reg:V4SF temp9)] UNSPEC_VSX_CVSPDP))
+;;
+;;     (set (reg:V4SF temp11)
+;;          (unspec:V4SF [(reg:SF temp10)] UNSPEC_VSX_CVDPSPN))
+;;
+;;     (set (reg:V4SF temp12)
+;;          (unspec:V4SF [(reg:V4SF temp1)
+;;                        (const_int 0)] UNSPEC_VSX_XXSPLTW))
+;;
+;;     (set (reg:V4SF temp13)
+;;          (plus:V4SF (reg:V4SF temp8)
+;;                     (reg:V4SF temp12)))
+;;
+;;     (set (reg:BF a)
+;;          (unspec:BF [(reg:V4SF temp13)] UNSPEC_XVCVSPBF16_BF))
+
+(define_peephole2
+  [(set (match_operand:SF 0 "vsx_register_operand")
+       (unspec:SF [(match_operand:V4SF 1 "vsx_register_operand")]
+                  UNSPEC_VSX_CVSPDP))
+   (set (match_operand:V4SF 2 "vsx_register_operand")
+       (unspec:V4SF [(match_dup 0)]
+                    UNSPEC_VSX_CVDPSPN))
+   (set (match_operand:V4SF 3 "vsx_register_operand")
+       (unspec:V4SF [(match_dup 2)
+                     (const_int 0)] UNSPEC_VSX_XXSPLTW))]
+  "((REGNO (operands[0]) == REGNO (operands[2]))
+    || peep2_reg_dead_p (2, operands[0]))
+   && (REGNO (operands[2]) == REGNO (operands[3])
+    || peep2_reg_dead_p (3, operands[2]))"
+  [(set (match_dup 3) (match_dup 1))]
+{
+})

Reply via email to