https://gcc.gnu.org/g:aa8dd49c88ea0150478c2ab0597c151f4fbd4b4a

commit aa8dd49c88ea0150478c2ab0597c151f4fbd4b4a
Author: Michael Meissner <[email protected]>
Date:   Tue Sep 15 18:51:25 2026 -0400

    Do BF to SF converts on p9; Remove int conversions; Add BF debug switches.
    
    2026-09-15  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (extendbf<mode>2): On power9, convert 
BFmode
            to SFmode or DFmode by shifting.
            (extendbf<mode>2_p1): Likewise.
            (extendbf<mode>2_not_p10): Likewise.
            (extendbfsf2_memory): Rename from convert_bf_to_sf_store.
            (float<GPR:mode><FP16_HW:mode>2): Delete integer conversion insns.
            (floatuns<GPR:mode><FP16_HW:mode>2): Likewise.
            (fix_trunc<FP16_HW:mode><GPR:mode): Likewise.
            (fixuns_trunc<FP16_HW:mode><GPR:mode>2): Likewise.
            * config/rs6000/rs6000.h (TARGET_BFLOAT16_CVT): New macro.
            * config/rs6000/rs6000.opt (-mbfloat16-convert): New debug switch.
            (mbfloat16-p10-convert): Likewise.

Diff:
---
 gcc/config/rs6000/float16.md | 124 +++++++++++++++++++++++--------------------
 gcc/config/rs6000/rs6000.h   |   6 +++
 gcc/config/rs6000/rs6000.opt |   8 +++
 3 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index 672effc6d019..e16853292735 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -233,16 +233,40 @@
   [(set_attr "type" "fpsimple")])
 
 ;; Convert BFmode to SFmode/DFmode.
-;; 3 instructions are generated:
+;; 3 instructions are generated on power10:
 ;;     XXSPLTW         -- duplicate BFmode into all even elements
 ;;     XVCVBF16SPN     -- convert even BFmode elements to SFmode
 ;;     XSCVSPNDP       -- convert memory format of SFmode to DFmode.
-(define_insn_and_split "extendbf<mode>2"
+;;
+;; 3 instructions are generated on power8/power9
+;;     SLDI            -- shift left 48 bits
+;;     MTVSRD          -- move to VSX register
+;;     XSCVSPNDP       -- convert memory format of SFmode to DFmode.
+;;
+;; We have 2 variants for testing.  One that uses the xvcvbf16spn
+;; instruction on power10, and one that does not.
+
+(define_expand "extendbf<mode>2"
+  [(set (match_operand:SFDF 0 "vsx_register_operand")
+       (float_extend:SFDF
+        (match_operand:BF 1 "gpc_reg_operand")))]
+  "TARGET_BFLOAT16_CVT"
+{
+  if (TARGET_BFLOAT16_HW && TARGET_BFLOAT16_P10_CONVERT)
+    emit_insn (gen_extendbf<mode>2_p10 (operands[0], operands[1]));
+  else
+    emit_insn (gen_extendbf<mode>2_not_p10 (operands[0], operands[1]));
+
+  DONE;
+})
+
+(define_insn_and_split "extendbf<mode>2_p10"
   [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
        (float_extend:SFDF
-        (match_operand:BF 1 "vsx_register_operand" "v")))
+        (match_operand:BF 1 "vsx_register_operand" "wa")))
    (clobber (match_scratch:V4SF 2 "=wa"))]
-  "TARGET_BFLOAT16_HW"
+  "TARGET_BFLOAT16_HW && TARGET_BFLOAT16_CONVERT
+   && TARGET_BFLOAT16_P10_CONVERT"
   "#"
   "&& 1"
   [(pc)]
@@ -254,8 +278,9 @@
   if (GET_CODE (op2) == SCRATCH)
     op2 = gen_reg_rtx (V4SFmode);
 
-  /* XXSPLTW -- duplicate BFmode element into all of the even elements.  We
-     can use splat words because we won't be using the odd elements  */
+  /* XXSPLTW -- duplicate BFmode element into all of the even elements.
+     We can use splat words because we won't be using the odd
+     elements.  */
   emit_insn (gen_xxspltw_bf (op2, op1));
 
   /* XVCVBF16SPN -- convert even V8BFmode elements to V4SFmode.  */
@@ -272,6 +297,41 @@
   [(set_attr "type" "fpsimple")
    (set_attr "length" "12")])
 
+(define_insn_and_split "extendbf<mode>2_not_p10"
+  [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
+       (float_extend:SFDF
+        (match_operand:BF 1 "int_reg_operand" "r")))
+   (clobber (match_scratch:V4SF 2 "=wa"))
+   (clobber (match_scratch:DI 3 "=r"))]
+  "TARGET_BFLOAT16_CVT
+   && (!TARGET_BFLOAT16_HW || !TARGET_BFLOAT16_P10_CONVERT)"
+  "#"
+  "&& reload_completed"
+  [(pc)]
+{
+  rtx op0 = operands[0];
+  rtx op1 = operands[1];
+  rtx op2 = operands[2];
+  rtx op3 = operands[3];
+  rtx op1_di = gen_rtx_REG (DImode, reg_or_subregno (op1));
+  rtx op2_di = gen_rtx_REG (DImode, reg_or_subregno (op2));
+
+  /* The shift left of 48 combines a shift left of 16 bits to
+     convert a BFmode to a SFmode with shift left of 32 bits
+     to do the xscvspdpn instruction.  */
+  emit_insn (gen_ashldi3 (op3, op1_di, GEN_INT (48)));
+  emit_move_insn (op2_di, op3);
+
+  /* XSCVSPNDP -- convert single V4SFmode element to DFmode.  */
+  emit_insn (GET_MODE (op0) == SFmode
+            ? gen_xscvspdpn_sf (op0, op2)
+            : gen_vsx_xscvspdpn (op0, op2));
+
+  DONE;
+}
+  [(set_attr "type" "fpsimple")
+   (set_attr "length" "12")])
+
 ;; Convert a SFmode scalar represented as DFmode to elements 0 and 1 of
 ;; V4SFmode.
 (define_insn "xscvdpspn_sf"
@@ -294,7 +354,7 @@
 
 ;; Optimize storing the conversion of BFmode to SFmode by shifting the
 ;; BFmode left 16 bits.
-(define_insn_and_split "*convert_bf_to_sf_store"
+(define_insn_and_split "*extendbfsf2_memory"
   [(set (match_operand:SF 0 "memory_operand" "=m")
        (float_extend:SF
         (match_operand:BF 1 "int_reg_operand" "r")))
@@ -618,56 +678,6 @@
   convert_move (operands[0], df_tmp, 0);
   DONE;
 })
-
-;; Convert integers to 16-bit floating point modes.
-(define_expand "float<GPR:mode><FP16_HW:mode>2"
-  [(use (match_operand:FP16_HW 0 "vsx_register_operand"))
-   (use (match_operand:GPR 1 "vsx_register_operand"))]
-  "can_create_pseudo_p ()"
-{
-  rtx df_tmp = gen_reg_rtx (DFmode);
-
-  convert_move (df_tmp, operands[1], 0);
-  convert_move (operands[0], df_tmp, 0);
-  DONE;
-})
-
-(define_expand "floatuns<GPR:mode><FP16_HW:mode>2"
-  [(use (match_operand:FP16_HW 0 "vsx_register_operand"))
-   (use (match_operand:GPR 1 "vsx_register_operand"))]
-  "can_create_pseudo_p ()"
-{
-  rtx df_tmp = gen_reg_rtx (DFmode);
-
-  convert_move (df_tmp, operands[1], 1);
-  convert_move (operands[0], df_tmp, 0);
-  DONE;
-})
-
-;; Convert 16-bit floating point modes to integers
-(define_expand "fix_trunc<FP16_HW:mode><GPR:mode>2"
-  [(use (match_operand:GPR 0 "vsx_register_operand"))
-   (use (match_operand:FP16_HW 1 "vsx_register_operand"))]
-  "can_create_pseudo_p ()"
-{
-  rtx df_tmp = gen_reg_rtx (DFmode);
-
-  convert_move (df_tmp, operands[1], 0);
-  convert_move (operands[0], df_tmp, 0);
-  DONE;
-})
-
-(define_expand "fixuns_trunc<FP16_HW:mode><GPR:mode>2"
-  [(use (match_operand:GPR 0 "vsx_register_operand"))
-   (use (match_operand:FP16_HW 1 "vsx_register_operand"))]
-  "can_create_pseudo_p ()"
-{
-  rtx df_tmp = gen_reg_rtx (DFmode);
-
-  convert_move (df_tmp, operands[1], 0);
-  convert_move (operands[0], df_tmp, 1);
-  DONE;
-})
 
 ;; Negate 16-bit floating point by XOR with -0.0.
 
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 1d88e0a46df3..d91b2a564998 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -355,6 +355,12 @@ extern const char *host_detect_local_cpu (int argc, const 
char **argv);
 #define TARGET_BFLOAT16_HW     (TARGET_FLOAT16 && TARGET_POWER10)
 #define TARGET_FLOAT16_HW      (TARGET_FLOAT16 && TARGET_P9_VECTOR)
 
+/* Mode iterator for conversions from 16-bit floating point.  Unlike
+   TARGET_BFLOAT16_HW, this specifically allows converting from BFmode even if
+   we don't have the bfloat16 conversion.  We do this conversion  */
+#define TARGET_BFLOAT16_CVT                                            \
+  (TARGET_FLOAT16 && TARGET_BFLOAT16_CONVERT && TARGET_P9_VECTOR)
+
 /* Do we have conversion support in hardware for the 16-bit floating point and
    also enable the 16-bit floating point vector optimizations?  */
 #define TARGET_BFLOAT16_HW_VECTOR                                      \
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 231a5121f9e9..f28dd3e6f1f1 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -646,6 +646,14 @@ mfloat16
 Target Mask(FLOAT16) Var(rs6000_isa_flags)
 Enable or disable 16-bit floating point.
 
+mbfloat16-convert
+Target Undocumented Var(TARGET_BFLOAT16_CONVERT) Init(1) Save
+Generate (do not generate) __bf16 to float/double conversions.
+
+mbfloat16-p10-convert
+Target Undocumented Var(TARGET_BFLOAT16_P10_CONVERT) Init(1) Save
+Generate (do not generate) xvcvbf16spn to do __bf16 to float/double 
conversions.
+
 mfloat16-convert-in-gprs
 Target Undocumented Var(TARGET_FLOAT16_CONVERT_IN_GPRS) Init(0) Save
 Pass/return (do not pass/return) 16-it float conversions in GPR registers.

Reply via email to