https://gcc.gnu.org/g:fe88850abc61b9d07de6e80eb4fc8a8c26f3a501
commit fe88850abc61b9d07de6e80eb4fc8a8c26f3a501 Author: Michael Meissner <[email protected]> Date: Sat Oct 25 01:36:43 2025 -0400 Just use VSLD to convert bfloat16 to SF/DF. 2025-10-25 Michael Meissner <[email protected]> gcc/ * config/rs6000/float16.md (UNSPEC_FP16_SHIFT_LEFT_32BIT): Delete. (UNSPEC_VSLD_BF): New unspec. (extendbf<mode>2): Rewrite to avoid doing xscvspdpnp. (extendbf<mode>2_internal): Likewise. (xscvdpspn_sf): Likewise. (shift_left_bf): Likewise. (xscvspdpn_<mode>): Likewise. ("<fp16_vector8>_shift_left_32bit): Likewise. (xscvdpspn_sf): Likewise. * config/rs6000/rs6000.md (-mbfloat16-combine): Default to 0. Diff: --- gcc/config/rs6000/float16.md | 89 ++++++++++++++++++++++---------------------- gcc/config/rs6000/rs6000.opt | 2 +- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md index 1365086f5751..040e1bc89f5d 100644 --- a/gcc/config/rs6000/float16.md +++ b/gcc/config/rs6000/float16.md @@ -81,7 +81,7 @@ ;; UNSPEC constants (define_c_enum "unspec" - [UNSPEC_FP16_SHIFT_LEFT_32BIT + [UNSPEC_VSLD_BF UNSPEC_CVT_FP16_TO_V4SF UNSPEC_XXSPLTW_FP16 UNSPEC_XVCVSPBF16_BF @@ -298,14 +298,27 @@ ;; Convert BFmode to SFmode/DFmode. ;; 3 instructions are generated: -;; VSPLTH -- duplicate BFmode into all elements -;; XVCVBF16SPN -- convert even BFmode elements to SFmode +;; PLXSD -- load up shift amount +;; VSLD -- shift BF left 48 bits ;; XSCVSPNDP -- convert memory format of SFmode to DFmode. -(define_insn_and_split "extendbf<mode>2" + +(define_expand "extendbf<mode>2" + [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa") + (float_extend:SFDF + (match_operand:BF 1 "altivec_register_operand" "v"))) + (use (match_dup 2)) + (clobber (match_scratch:DI 3 "=&v"))])] + "TARGET_BFLOAT16_HW" +{ + operands[2] = force_reg (DImode, GEN_INT (48)); +}) + +(define_insn_and_split "*extendbf<mode>2_internal" [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa") (float_extend:SFDF - (match_operand:BF 1 "vsx_register_operand" "v"))) - (clobber (match_scratch:V8BF 2 "=v"))] + (match_operand:BF 1 "altivec_register_operand" "v"))) + (use (match_operand:DI 2 "altivec_register_operand" "v")) + (clobber (match_scratch:DI 3 "=&v"))] "TARGET_BFLOAT16_HW" "#" "&& 1" @@ -313,60 +326,48 @@ { rtx op0 = operands[0]; rtx op1 = operands[1]; - rtx op2_v8bf = operands[2]; - - if (GET_CODE (op2_v8bf) == SCRATCH) - op2_v8bf = gen_reg_rtx (V8BFmode); + rtx op2 = operands[2]; + rtx op3 = operands[2]; - rtx op2_v4sf = gen_lowpart (V4SFmode, op2_v8bf); + if (GET_CODE (op3) == SCRATCH) + op3 = gen_reg_rtx (DImode); - /* XXSLDWI -- shift BFmode element into the upper 32 bits. */ - emit_insn (gen_v8bf_shift_left_32bit (op2_v8bf, op1)); + /* Shift BFmode into the upper 16 bits. */ + emit_insn (gen_shift_left_bf (op3, op1, op2)); - /* XVCVBF16SPN -- convert even V8BFmode elements to V4SFmode. */ - emit_insn (gen_cvt_fp16_to_v4sf_v8bf (op2_v4sf, op2_v8bf)); + /* XXSLDWI -- shift BFmode element into the upper 16 bits. */ + emit_insn (gen_shift_left_bf (op3, op1, op2)); - /* XSCVSPNDP -- convert single V4SFmode element to DFmode. */ + /* XSCVSPDPN -- convert single V4SFmode element to DFmode. */ emit_insn (GET_MODE (op0) == SFmode - ? gen_xscvspdpn_sf (op0, op2_v4sf) - : gen_vsx_xscvspdpn (op0, op2_v4sf)); + ? gen_xscvspdpn_sf (op0, op3) + : gen_xscvspdpn_df (op0, op3)); 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" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") - (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (SFmode)" - "xscvdpspn %x0,%x1" - [(set_attr "type" "fp")]) +;; Shift BFmode left +(define_insn "shift_left_bf" + [(set (match_operand:DI 0 "altivec_register_operand" "=v") + (unspec:DI [(match_operand:BF 1 "altivec_register_operand" "v") + (match_operand:DI 2 "altivec_register_operand" "v")] + UNSPEC_VSLD_BF))] + "TARGET_BFLOAT16" + "vsld %0,%1,%2" + [(set_attr "type" "vecsimple")]) ;; Convert element 0 of a V4SFmode to scalar SFmode (which on the ;; PowerPC uses the DFmode encoding). -(define_insn "xscvspdpn_sf" - [(set (match_operand:SF 0 "vsx_register_operand" "=wa") - (unspec:SF [(match_operand:V4SF 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVSPDPN))] - "TARGET_XSCVSPDPN" +(define_insn "xscvspdpn_<mode>" + [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa") + (unspec:SFDF [(match_operand:DI 1 "vsx_register_operand" "wa")] + UNSPEC_VSX_CVSPDPN))] + "TARGET_BFLOAT16" "xscvspdpn %x0,%x1" [(set_attr "type" "fp")]) -;; Vector shift left by 32 bits to get the 16-bit floating point value -;; into the upper 32 bits for the conversion. -(define_insn "<fp16_vector8>_shift_left_32bit" - [(set (match_operand:<FP16_VECTOR8> 0 "vsx_register_operand" "=wa") - (unspec:<FP16_VECTOR8> - [(match_operand:FP16_HW 1 "vsx_register_operand" "wa")] - UNSPEC_FP16_SHIFT_LEFT_32BIT))] - "" - "xxsldwi %x0,%x1,%x1,1" - [(set_attr "type" "vecperm")]) - ;; Convert SFmode/DFmode to BFmode. ;; 2 instructions are generated: ;; XSCVDPSPN -- convert SFmode/DFmode scalar to V4SFmode @@ -398,7 +399,7 @@ } [(set_attr "type" "fpsimple")]) -(define_insn "vsx_xscvdpspn_sf" +(define_insn "xscvdpspn_sf" [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "wa")] UNSPEC_VSX_CVDPSPN))] diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 053183b004c6..7bae64f2405d 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -655,7 +655,7 @@ Target Mask(BFLOAT16) Var(rs6000_isa_flags) Enable or disable __bfloat16 support. mbfloat16-combine -Target Undocumented Var(TARGET_BFLOAT16_COMBINE) Init(1) Save +Target Undocumented Var(TARGET_BFLOAT16_COMBINE) Init(0) Save Enable or disable __bfloat16 combine optimizations mbfloat16-pack
