https://gcc.gnu.org/g:b44c5956419377d5203332d9f04a9ea2815ed3b8
commit b44c5956419377d5203332d9f04a9ea2815ed3b8 Author: Michael Meissner <[email protected]> Date: Tue Sep 15 12:10:46 2026 -0400 Limit 16-bit floating point to power9 or later. 2026-09-15 Michael Meissner <[email protected]> gcc/ * config/rs6000/float16.md (FP16_FLOAT_CONVERT): Rename from fp16_float_convert. Restructure code. (extend<FP16_HW:mode><FP16_FLOAT_CONVERT:mode>2): Likewise. (trunc<fp16_float_convert:mode><FP16_HW:mode>2): Likewise. (float<GPR:mode><FP16_HW:mode>2): Restructure code. (floatuns<GPR:mode><FP16_HW:mode>2): Likewise. (fix_trunc<FP16_HW:mode><GPR:mode>2): Likewise. (fixuns_trunc<FP16_HW:mode><GPR:mode>2): Likewise. * config/rs6000/rs6000.cc (rs6000_option_override_internal): Limit 16-bit floating point to power9 or later. (rs6000_scalar_mode_supported_p): Limit 16-bit floating point to -mfloat16. Diff: --- gcc/config/rs6000/float16.md | 73 ++++++++++++++++++++++---------------------- gcc/config/rs6000/rs6000.cc | 30 +++++++++++------- 2 files changed, 55 insertions(+), 48 deletions(-) diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md index 461369b821e6..672effc6d019 100644 --- a/gcc/config/rs6000/float16.md +++ b/gcc/config/rs6000/float16.md @@ -36,7 +36,7 @@ ;; Mode iterator for floating point modes other than SF/DFmode that we ;; convert to/from _Float16 (HFmode) via DFmode. -(define_mode_iterator fp16_float_convert [TF KF IF SD DD TD]) +(define_mode_iterator FP16_FLOAT_CONVERT [TF KF IF SD DD TD]) ;; Mode attribute giving the instruction to convert the even ;; V8HFmode or V8BFmode elements to V4SFmode @@ -595,78 +595,77 @@ ;; types might not have valid RTX expanders. We use DFmode as the ;; intermediate conversion destination. -(define_expand "extend<FP16_HW:mode><fp16_float_convert:mode>2" - [(set (match_operand:fp16_float_convert 0 "vsx_register_operand") - (float_extend:fp16_float_convert - (match_operand:FP16_HW 1 "vsx_register_operand")))] - "" +(define_expand "extend<FP16_HW:mode><FP16_FLOAT_CONVERT:mode>2" + [(use (match_operand:FP16_FLOAT_CONVERT 0 "vsx_register_operand")) + (use (match_operand:FP16_HW 1 "vsx_register_operand"))] + "can_create_pseudo_p ()" { rtx df_tmp = gen_reg_rtx (DFmode); - emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1])); + + convert_move (df_tmp, operands[1], 0); convert_move (operands[0], df_tmp, 0); DONE; }) -(define_expand "trunc<fp16_float_convert:mode><FP16_HW:mode>2" - [(set (match_operand:FP16_HW 0 "vsx_register_operand") - (float_truncate:FP16_HW - (match_operand:fp16_float_convert 1 "vsx_register_operand")))] - "" +(define_expand "trunc<FP16_FLOAT_CONVERT:mode><FP16_HW:mode>2" + [(use (match_operand:FP16_HW 0 "vsx_register_operand")) + (use (match_operand:FP16_FLOAT_CONVERT 1 "vsx_register_operand"))] + "can_create_pseudo_p ()" { rtx df_tmp = gen_reg_rtx (DFmode); convert_move (df_tmp, operands[1], 0); - emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp)); + 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" - [(set (match_operand:FP16_HW 0 "vsx_register_operand") - (float:FP16_HW - (match_operand:GPR 1 "vsx_register_operand")))] - "" + [(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); - emit_insn (gen_float<GPR:mode>df2 (df_tmp, operands[1])); - emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp)); + + convert_move (df_tmp, operands[1], 0); + convert_move (operands[0], df_tmp, 0); DONE; }) (define_expand "floatuns<GPR:mode><FP16_HW:mode>2" - [(set (match_operand:FP16_HW 0 "vsx_register_operand") - (unsigned_float:FP16_HW - (match_operand:GPR 1 "vsx_register_operand")))] - "" + [(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); - emit_insn (gen_floatuns<GPR:mode>df2 (df_tmp, operands[1])); - emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp)); + + 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" - [(set (match_operand:GPR 0 "vsx_register_operand") - (fix:GPR - (match_operand:FP16_HW 1 "vsx_register_operand")))] - "" + [(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); - emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1])); - emit_insn (gen_fix_truncdf<GPR:mode>2 (operands[0], df_tmp)); + + 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" - [(set (match_operand:GPR 0 "vsx_register_operand") - (unsigned_fix:GPR - (match_operand:FP16_HW 1 "vsx_register_operand")))] - "" + [(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); - emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1])); - emit_insn (gen_fixuns_truncdf<GPR:mode>2 (operands[0], df_tmp)); + + convert_move (df_tmp, operands[1], 0); + convert_move (operands[0], df_tmp, 1); DONE; }) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 8df2333d5b3a..917cb401f718 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -3994,17 +3994,25 @@ rs6000_option_override_internal (bool global_init_p) } } - /* 16-bit floating point needs 64-bit power8 at a minimum in order to load up - 16-bit values into vector registers via loads/stores from GPRs and then - using direct moves. Don't allow 16-bit float on big endian systems at the - current time. */ - if (TARGET_FLOAT16 && (!TARGET_DIRECT_MOVE_64BIT || BYTES_BIG_ENDIAN)) + /* Limit 16-bit floating point to power9 or later in order to load up + 16-bit values into vector registers via loads/stores from GPRs and + then using direct moves. Don't allow 16-bit float on big endian + systems at the current time. */ + if (TARGET_FLOAT16) { - rs6000_isa_flags &= ~OPTION_MASK_FLOAT16; - if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16) - error ("%qs is only available on 64-bit little endian systems " - "that use at least %qs", - "-mfloat16", "-mcpu=power8"); + if (!TARGET_P9_VECTOR) + { + rs6000_isa_flags &= ~OPTION_MASK_FLOAT16; + if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16) + error ("%qs needs at least %qs", "-mfloat16", "-mcpu=power9"); + } + else if (BYTES_BIG_ENDIAN || !TARGET_POWERPC64) + { + rs6000_isa_flags &= ~OPTION_MASK_FLOAT16; + if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16) + error ("%qs is only available on 64-bit little endian systems", + "-mfloat16"); + } } /* If hard-float/altivec/vsx were explicitly turned off then don't allow @@ -24781,7 +24789,7 @@ rs6000_scalar_mode_supported_p (scalar_mode mode) else if (TARGET_FLOAT128_TYPE && (mode == KFmode || mode == IFmode)) return true; else if (FP16_SCALAR_MODE_P (mode)) - return true; + return TARGET_FLOAT16; else return default_scalar_mode_supported_p (mode); }
