Hi Kishan,

Please find the comments below.

On Wed, 2026-09-23 at 11:54 +0530, Kishan Parmar wrote:
> Hi All,
> 
> Below patch is bootstrapped and regtested on power64le-linux.
> 
> Thank you,
> Kishan
> 
> The rs6000 built-in infrastructure previously supported only a single
> gating predicate per built-in stanza.  This caused problems when a
> built-in required multiple conditions simultaneously.  For example,
> __builtin_vsx_xvtlsbb_all_ones requires both Power10 ISA support
> (-mcpu=power10) and VSX support (-mvsx), but was gated only on
> [power10], causing compiler crashes when compiled with -mcpu=power10
> -mno-vsx.
> 
> This patch extends the built-in infrastructure to support up to four
> comma-separated gating predicates in stanza headers, e.g.:
> 
>   [power10, vsx]
> 
> All predicates are combined with AND logic all must be satisfied for
> the built-in to be enabled. existing single-predicate stanzas are
> parsed
> as before.
> 
> The stanza keywords that hard-coded multi-predicate combinations
> (power6-64, power7-64, power8-vector, power9-64, power9-vector,
> power10-64, future-altivec, future-vsx) are removed and replaced by
> explicit comma-separated forms (e.g. [power9, vsx] instead of
> [power9-vector]).
> 
> The two new static helpers get_enable_string() and
> check_single_enable()
> consolidate all predicate-to-string and predicate-to-target-flag
> mapping
> that was previously duplicated across the two functions.
> 
> Note: only __builtin_vsx_xvtlsbb_all_ones and
> __builtin_vsx_xvtlsbb_all_zeros are moved to an explicit [power10,
> vsx]
> stanza in this patch.  Full rework of rs6000-builtins.def to use
> multi-predicate stanzas throughout is left for a follow-on patch.
Please add test for this. The same test as mentioned in 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125389
> 
> This also fixes diagnostics for built-ins whose availability depends
> on
> both an ISA level and an additional feature.  For example,
> __builtin_dmsetdmrz previously reported only "-mdense-math":
> 
>   error: '__builtin_dmsetdmrz' requires the '-mdense-math' option
> 
> It now correctly reports both required predicates:
> 
>   error: '__builtin_dmsetdmrz' requires the '-mcpu=future' and
>   '-mdense-math' options
> 
> Similarly, MMA built-ins that require both Power10 ISA support and
> MMA
> support now report both missing requirements.  For example,
> __builtin_mma_xxsetaccz previously reported only "-mmma", while it
> now
> reports:
> 
>   error: '__builtin_mma_xxsetaccz' requires the '-mcpu=power10' and
>   '-mmma' options
> 
> This ensures diagnostics accurately reflect all gating predicates
> required
> by a built-in.
> 
> gcc/ChangeLog:
>       PR target/125389
>       * config/rs6000/rs6000-builtin.cc (get_enable_string): New
> static
>       helper. map a single bif_enable to its option-string
> representation.
>       (check_single_enable): New static helper. return true when a
> single
>       bif_enable predicate is satisfied by the current target.
>       (rs6000_invalid_builtin): Rewrite.  Loop over enables[].
> track
>       ENB_M64 and ENB_IEEE128_HW separately for special diagnostic
> wording.
>       emit a single error naming every predicate the built-in
> requires.
>       (rs6000_builtin_is_supported): Rewrite.  Loop over enables[]
> calling
>       check_single_enable. return false on the first unsatisfied
> predicate.
>       * config/rs6000/rs6000-builtins.def: Update file-header
> comment to
>       document multi-predicate syntax.  Replace composite stanza
> keywords
>       with explicit comma-separated forms: [power6-64] -> [power6,
> m64],
>       [power7-64] -> [power7, m64], [power8-vector] -> [power8,
> vsx],
>       [power9-vector] -> [power9, vsx], [power9-64] -> [power9,
> m64],
>       [power10-64] -> [power10, m64], [future-altivec] -> [future,
> altivec],
>       [future-vsx] -> [future, vsx].  Move
> __builtin_vsx_xvtlsbb_all_ones
>       and __builtin_vsx_xvtlsbb_all_zeros from the [power10]
> stanza to a
>       new [power10, vsx] stanza.
>       * config/rs6000/rs6000-gen-builtins.cc: Update file-header
> comment
>       to document multi-predicate stanza syntax.
>       (enum bif_stanza): Remove stanzas BSTZ_P6_64, BSTZ_P7_64,
> BSTZ_P8V,
>       BSTZ_P9_64, BSTZ_P9V, BSTZ_P10_64, BSTZ_FUTURE_ALTIVEC,
>       BSTZ_FUTURE_VSX.  Add BSTZ_M64.
>       (MAXBIFPREDICATES): New macro. maximum predicates per
> stanza.
>       (curr_bif_num_predicates): New file-scope variable.
>       (curr_bif_predicates): New file-scope array.
>       (stanza_map): Remove composite entries. add "m64" ->
> BSTZ_M64.
>       (enable_string): Remove composite ENB_* entries. add
> ENB_M64.
>       (struct bifdata): Add fields num_predicates and
> predicates[].
>       (parse_bif_stanza_predicates): New function. parse comma-
> separated
>       predicates from a stanza header string.
>       (parse_bif_entry): Store num_predicates and predicates[]
> into bifdata.
>       (parse_bif_stanza): Call parse_bif_stanza_predicates instead
> of
>       stanza_name_to_stanza directly.
>       (write_decls): Emit ENB_M64. remove composite ENB_* values.
> emit
>       PPC_MAXBIFPREDICATES macro. change bifdata::enable field to
>       num_enables and enables[PPC_MAXBIFPREDICATES].
>       (write_bif_static_init): Emit num_enables and enables[]
> initializer
>       instead of single enable value.
> 
> gcc/testsuite/ChangeLog:
>       PR target/125389
>       * gcc.target/powerpc/pr96125.c:  Update expected error
> messages to
>       include the '-mcpu=power10' requirement for MMA built-ins.
> ---
>  gcc/config/rs6000/rs6000-builtin.cc        | 209 ++++++++++++-------
> --
>  gcc/config/rs6000/rs6000-builtins.def      |  48 +++--
>  gcc/config/rs6000/rs6000-gen-builtins.cc   | 143 ++++++++++----
>  gcc/testsuite/gcc.target/powerpc/pr96125.c |   4 +-
>  4 files changed, 250 insertions(+), 154 deletions(-)
> 
> diff --git a/gcc/config/rs6000/rs6000-builtin.cc
> b/gcc/config/rs6000/rs6000-builtin.cc
> index ad6f1fc09f4..9af2edca38c 100644
> --- a/gcc/config/rs6000/rs6000-builtin.cc
> +++ b/gcc/config/rs6000/rs6000-builtin.cc
> @@ -62,136 +62,75 @@ tree altivec_builtin_mask_for_load;
>  
>  /* **** General support functions **** */
>  
> -/* Raise an error message for a builtin function that is called
> without the
> -   appropriate target options being set.  */
> +/* Helper function to get the option string for a single enable
> predicate.  */
>  
> -void
> -rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
> +static const char *
> +get_enable_string (bif_enable enable)
>  {
> -  size_t j = (size_t) fncode;
> -  const char *name = rs6000_builtin_info[j].bifname;
> -
> -  switch (rs6000_builtin_info[j].enable)
> +  switch (enable)
>      {
>      case ENB_P5:
> -      error ("%qs requires the %qs option", name, "-mcpu=power5");
> -      break;
> +      return "-mcpu=power5";
>      case ENB_P6:
> -      error ("%qs requires the %qs option", name, "-mcpu=power6");
> -      break;
> -    case ENB_P6_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs
> option",
> -          name, "-mcpu=power6", "-m64", "-mpowerpc64");
> -      break;
> +      return "-mcpu=power6";
>      case ENB_ALTIVEC:
> -      error ("%qs requires the %qs option", name, "-maltivec");
> -      break;
> +      return "-maltivec";
>      case ENB_CELL:
> -      error ("%qs requires the %qs option", name, "-mcpu=cell");
> -      break;
> +      return "-mcpu=cell";
>      case ENB_VSX:
> -      error ("%qs requires the %qs option", name, "-mvsx");
> -      break;
> +      return "-mvsx";
>      case ENB_P7:
> -      error ("%qs requires the %qs option", name, "-mcpu=power7");
> -      break;
> -    case ENB_P7_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs
> option",
> -          name, "-mcpu=power7", "-m64", "-mpowerpc64");
> -      break;
> +      return "-mcpu=power7";
>      case ENB_P8:
> -      error ("%qs requires the %qs option", name, "-mcpu=power8");
> -      break;
> -    case ENB_P8V:
> -      error ("%qs requires the %qs and %qs options", name, "-
> mcpu=power8",
> -          "-mvsx");
> -      break;
> +      return "-mcpu=power8";
>      case ENB_P9:
> -      error ("%qs requires the %qs option", name, "-mcpu=power9");
> -      break;
> -    case ENB_P9_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs
> option",
> -          name, "-mcpu=power9", "-m64", "-mpowerpc64");
> -      break;
> -    case ENB_P9V:
> -      error ("%qs requires the %qs and %qs options", name, "-
> mcpu=power9",
> -          "-mvsx");
> -      break;
> -    case ENB_IEEE128_HW:
> -      error ("%qs requires quad-precision floating-point
> arithmetic", name);
> -      break;
> +      return "-mcpu=power9";
>      case ENB_DFP:
> -      error ("%qs requires the %qs option", name, "-mhard-dfp");
> -      break;
> +      return "-mhard-dfp";
>      case ENB_CRYPTO:
> -      error ("%qs requires the %qs option", name, "-mcrypto");
> -      break;
> +      return "-mcrypto";
>      case ENB_HTM:
> -      error ("%qs requires the %qs option", name, "-mhtm");
> -      break;
> +      return "-mhtm";
>      case ENB_P10:
> -      error ("%qs requires the %qs option", name, "-mcpu=power10");
> -      break;
> -    case ENB_P10_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs
> option",
> -          name, "-mcpu=power10", "-m64", "-mpowerpc64");
> -      break;
> +      return "-mcpu=power10";
>      case ENB_MMA:
> -      error ("%qs requires the %qs option", name, "-mmma");
> -      break;
> +      return "-mmma";
>      case ENB_FUTURE:
> -      error ("%qs requires the %qs option", name, "-mcpu=future");
> -      break;
> -    case ENB_FUTURE_ALTIVEC:
> -      error ("%qs requires the %qs and %qs options", name, "-
> mcpu=future",
> -          "-maltivec");
> -      break;
> -    case ENB_FUTURE_VSX:
> -      error ("%qs requires the %qs and %qs options", name, "-
> mcpu=future",
> -          "-mvsx");
> -      break;
> +      return "-mcpu=future";
>      case ENB_DM:
> -      error ("%qs requires the %qs option", name, "-mdense-math");
> -      break;
> +      return "-mdense-math";
>      default:
>      case ENB_ALWAYS:
> +    case ENB_M64:
> +    case ENB_IEEE128_HW:
>        gcc_unreachable ();
>      }
> +  gcc_unreachable ();
>  }
>  
> -/* Check whether a builtin function is supported in this target
> -   configuration.  */
> -bool
> -rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
> +/* Helper function to check if a single enable predicate is
> satisfied.  */
> +
> +static bool
> +check_single_enable (bif_enable enable)
>  {
> -  switch (rs6000_builtin_info[(size_t) fncode].enable)
> +  switch (enable)
>      {
>      case ENB_ALWAYS:
>        return true;
> +    case ENB_M64:
> +      return TARGET_POWERPC64;
>      case ENB_P5:
>        return TARGET_POPCNTB;
>      case ENB_P6:
>        return TARGET_CMPB;
> -    case ENB_P6_64:
> -      return TARGET_CMPB && TARGET_POWERPC64;
>      case ENB_P7:
>        return TARGET_POPCNTD;
> -    case ENB_P7_64:
> -      return TARGET_POPCNTD && TARGET_POWERPC64;
>      case ENB_P8:
>        return TARGET_POWER8;
> -    case ENB_P8V:
> -      return TARGET_P8_VECTOR;
>      case ENB_P9:
>        return TARGET_MODULO;
> -    case ENB_P9_64:
> -      return TARGET_MODULO && TARGET_POWERPC64;
> -    case ENB_P9V:
> -      return TARGET_P9_VECTOR;
>      case ENB_P10:
>        return TARGET_POWER10;
> -    case ENB_P10_64:
> -      return TARGET_POWER10 && TARGET_POWERPC64;
>      case ENB_ALTIVEC:
>        return TARGET_ALTIVEC;
>      case ENB_VSX:
> @@ -210,10 +149,6 @@ rs6000_builtin_is_supported (enum
> rs6000_gen_builtins fncode)
>        return TARGET_MMA;
>      case ENB_FUTURE:
>        return TARGET_FUTURE;
> -    case ENB_FUTURE_ALTIVEC:
> -      return TARGET_FUTURE && TARGET_ALTIVEC;
> -    case ENB_FUTURE_VSX:
> -      return TARGET_FUTURE && TARGET_VSX;
>      case ENB_DM:
>        return TARGET_DMF;
>      default:
> @@ -222,6 +157,92 @@ rs6000_builtin_is_supported (enum
> rs6000_gen_builtins fncode)
>    gcc_unreachable ();
>  }
>  
> +/* Raise an error message for a builtin function that is called
> without the
> +   appropriate target options being set.  All predicates the builtin
> requires
> +   are reported so the user can see the full set at once.  */
> +
> +void
> +rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
> +{
> +  size_t j = (size_t) fncode;
> +  const char *name = rs6000_builtin_info[j].bifname;
> +  int num_enables = rs6000_builtin_info[j].num_enables;
> +
> +  if (num_enables == 1
> +      && rs6000_builtin_info[j].enables[0] == ENB_IEEE128_HW)
> +    {
> +      error ("%qs requires quad-precision floating-point
> arithmetic", name);
> +      return;
> +    }
> +
> +  /* Collect all predicates the builtin requires.  */
> +  const char *req[PPC_MAXBIFPREDICATES];
> +  int num_req = 0;
> +  bool has_m64 = false;
> +
> +  for (int i = 0; i < num_enables; i++)
> +    {
> +      bif_enable enb = rs6000_builtin_info[j].enables[i];
> +      if (enb == ENB_M64)
> +     has_m64 = true;
> +      else
> +     req[num_req++] = get_enable_string (enb);
> +    }
> +
> +  /* ENB_M64 has two equivalent spellings; append its wording last
> so
> +     that all plain option names come first in the message.  */
> +  if (has_m64)
> +    {
> +      if (num_req == 0)
> +     error ("%qs requires either the %qs or %qs option",
> +            name, "-m64", "-mpowerpc64");
> +      else if (num_req == 1)
> +     error ("%qs requires the %qs option and either the %qs or
> %qs option",
> +            name, req[0], "-m64", "-mpowerpc64");
> +      else if (num_req == 2)
> +     error ("%qs requires the %qs and %qs options"
> +            " and either the %qs or %qs option",
> +            name, req[0], req[1], "-m64", "-mpowerpc64");
> +      else if (num_req == 3)
> +     error ("%qs requires the %qs, %qs, and %qs options"
> +            " and either the %qs or %qs option",
> +            name, req[0], req[1], req[2], "-m64", "-mpowerpc64");
> +      return;
> +    }
> +
> +  /* Report all required options.  */
> +  if (num_req == 1)
> +    error ("%qs requires the %qs option", name, req[0]);
> +  else if (num_req == 2)
> +    error ("%qs requires the %qs and %qs options",
> +        name, req[0], req[1]);
> +  else if (num_req == 3)
> +    error ("%qs requires the %qs, %qs, and %qs options",
> +        name, req[0], req[1], req[2]);
> +  else if (num_req == 4)
> +    error ("%qs requires the %qs, %qs, %qs, and %qs options",
> +        name, req[0], req[1], req[2], req[3]);
> +}
> +
> +/* Check whether a builtin function is supported in this target
> +   configuration.  For functions with multiple gating predicates,
> +   ALL predicates must be satisfied (AND logic).  */
> +
> +bool
> +rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
> +{
> +  size_t j = (size_t) fncode;
> +  int num_enables = rs6000_builtin_info[j].num_enables;
> +
> +  for (int i = 0; i < num_enables; i++)
> +    {
> +      if (!check_single_enable (rs6000_builtin_info[j].enables[i]))
> +     return false;
> +    }
> +
> +  return true;
> +}
> +
>  /* Target hook for early folding of built-ins, shamelessly stolen
>     from ia64.cc.  */
>  
> diff --git a/gcc/config/rs6000/rs6000-builtins.def
> b/gcc/config/rs6000/rs6000-builtins.def
> index 4b7d21cdb81..bbd8a2d4b79 100644
> --- a/gcc/config/rs6000/rs6000-builtins.def
> +++ b/gcc/config/rs6000/rs6000-builtins.def
> @@ -31,7 +31,15 @@
>  ;
>  ;     [power9]
>  ;
> -; The bracketed gating predicate is the only information allowed on
> +; Multiple gating predicates can be specified using comma-separated
> values.
> +; When multiple predicates are specified, ALL predicates must be
> satisfied
> +; (AND logic) for the built-in to be enabled.  For example:
> +;
> +;     [power10,vsx]
> +;
> +; This means the built-in requires both -mcpu=power10 AND -mvsx
> options.
> +;
> +; The bracketed gating predicate(s) are the only information allowed
> on
>  ; the stanza header line, other than whitespace.
>  ;
>  ; Following the stanza header are two lines for each function: the
> @@ -286,7 +294,7 @@
>  
>  
>  ; Power6 builtins requiring 64-bit GPRs (even with 32-bit
> addressing).
> -[power6-64]
> +[power6, m64]
>    const signed long __builtin_p6_cmpb (signed long, signed long);
>      CMPB cmpbdi3 {no32bit}
>  
> @@ -1861,7 +1869,7 @@
>  
>  
>  ; Power7 builtins requiring 64-bit GPRs (even with 32-bit
> addressing).
> -[power7-64]
> +[power7, m64]
>    const signed long long __builtin_divde (signed long long, signed
> long long);
>      DIVDE dive_di {}
>  
> @@ -1871,7 +1879,7 @@
>  
>  
>  ; Power8 vector built-ins.
> -[power8-vector]
> +[power8, vsx]
>    const vsll __builtin_altivec_abs_v2di (vsll);
>      ABS_V2DI absv2di2 {}
>  
> @@ -2312,7 +2320,7 @@
>  
>  
>  ; Power9 vector builtins.
> -[power9-vector]
> +[power9, vsx]
>    const vss __builtin_altivec_convert_4f32_8f16 (vf, vf);
>      CONVERT_4F32_8F16 convert_4f32_8f16 {}
>  
> @@ -2659,7 +2667,7 @@
>    const signed int  __builtin_vsx_scalar_extract_exp (double);
>      VSEEDP xsxexpdp_si {}
>  
> -[power9-64]
> +[power9, m64]
>    void __builtin_altivec_xst_len_r (vsc, void *, long);
>      XST_LEN_R xst_len_r {}
>  
> @@ -3335,12 +3343,6 @@
>    const vuq __builtin_vsx_vmsumcud (vull, vull, vuq);
>      VMSUMCUD vmsumcud {}
>  
> -  const signed int __builtin_vsx_xvtlsbb_all_ones (vsc);
> -    XVTLSBB_ONES xvtlsbbo {}
> -
> -  const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc);
> -    XVTLSBB_ZEROS xvtlsbbz {}
> -
>    const vf __builtin_vsx_vxxsplti32dx_v4sf (vf, const int<1>,
> float);
>      VXXSPLTI32DX_V4SF xxsplti32dx_v4sf {}
>  
> @@ -3442,7 +3444,16 @@
>      ZE_LXVRDX vsx_lxvrdx {lxvrze}
>  
>  
> -[power10-64]
> +; Power10 builtins that requires -mvsx.
> +[power10, vsx]
> +  const signed int __builtin_vsx_xvtlsbb_all_ones (vsc);
> +    XVTLSBB_ONES xvtlsbbo {}
> +
> +  const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc);
> +    XVTLSBB_ZEROS xvtlsbbz {}
> +
> +
> +[power10, m64]
>    const unsigned long long __builtin_cfuged (unsigned long long, \
>                                               unsigned long long);
>      CFUGED cfuged {}
> @@ -3463,8 +3474,8 @@
>                                              unsigned long long);
>      PEXTD pextd {}
>  
> -
> -[mma]
> +; Power10 built-ins that requires -mmma
> +[power10, mma]
>    void __builtin_mma_assemble_acc (v512 *, vuc, vuc, vuc, vuc);
>      ASSEMBLE_ACC nothing {mma,mmaint}
>  
> @@ -3942,7 +3953,7 @@
>    void __builtin_vsx_stxvp (v256, unsigned long, const v256 *);
>      STXVP nothing {mma,pair}
>  
> -[future-vsx]
> +[future, vsx]
>    const vus __builtin_vsx_xvmulhuh (vus, vus);
>      XVMULHUH umulv8hi3_highpart {}
>  
> @@ -4071,7 +4082,7 @@
>    const vuc __builtin_galois_field_mult_xts (vuc, vuc);
>      XXGFMUL128XTS xxgfmul128xts {}
>  
> -[future-altivec]
> +[future, altivec]
>    const vus __builtin_altivec_uncompresshn (vuc, vui);
>      VUCMPRHN altivec_vucmprhn {}
>  
> @@ -4096,7 +4107,8 @@
>    const vf __builtin_altivec_unpack_int8_to_fp32 (vui, const
> int<2>);
>      VUPKINT8TOFP32 altivec_vupkint8tofp32 {}
>  
> -[dm]
> +; future built-ins that requires -mdense-math
> +[future, dm]
>    void __builtin_dmsetdmrz (dmr1024 *);
>      DMSETDMRZ nothing {dm,dmint}
>  
> diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc
> b/gcc/config/rs6000/rs6000-gen-builtins.cc
> index 08068ba78fd..c97c246df32 100644
> --- a/gcc/config/rs6000/rs6000-gen-builtins.cc
> +++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
> @@ -39,7 +39,15 @@ along with GCC; see the file COPYING3.  If not see
>  
>       [power9]
>  
> -   The bracketed gating predicate is the only information allowed on
> +   Multiple gating predicates can be specified using comma-separated
> +   values.  When multiple predicates are specified, ALL predicates
> must
> +   be satisfied (AND logic) for the built-in to be enabled.  For
> example:
> +
> +     [power10,vsx]
> +
> +   This means the built-in requires both -mcpu=power10 AND -mvsx
> options.
> +
> +   The bracketed gating predicate(s) are the only information
> allowed on
>     the stanza header line, other than whitespace.
>  
>     Following the stanza header are two lines for each function: the
> @@ -215,34 +223,33 @@ enum void_status
>  enum bif_stanza
>  {
>   BSTZ_ALWAYS,
> + BSTZ_M64,
>   BSTZ_P5,
>   BSTZ_P6,
> - BSTZ_P6_64,
>   BSTZ_ALTIVEC,
>   BSTZ_CELL,
>   BSTZ_VSX,
>   BSTZ_P7,
> - BSTZ_P7_64,
>   BSTZ_P8,
> - BSTZ_P8V,
>   BSTZ_P9,
> - BSTZ_P9_64,
> - BSTZ_P9V,
>   BSTZ_IEEE128_HW,
>   BSTZ_DFP,
>   BSTZ_CRYPTO,
>   BSTZ_HTM,
>   BSTZ_P10,
> - BSTZ_P10_64,
>   BSTZ_MMA,
>   BSTZ_FUTURE,
> - BSTZ_FUTURE_ALTIVEC,
> - BSTZ_FUTURE_VSX,
>   BSTZ_DM,
>   NUMBIFSTANZAS
>  };
>  
> +/* Maximum number of predicates that can be specified for a single
> +   stanza.  */
> +#define MAXBIFPREDICATES 4
> +
>  static bif_stanza curr_bif_stanza;
> +static int curr_bif_num_predicates = 0;
> +static bif_stanza curr_bif_predicates[MAXBIFPREDICATES];
>  
>  struct stanza_entry
>  {
> @@ -253,58 +260,44 @@ struct stanza_entry
>  static stanza_entry stanza_map[NUMBIFSTANZAS] =
>    {
>      { "always",              BSTZ_ALWAYS     },
> +    { "m64",         BSTZ_M64        },
>      { "power5",              BSTZ_P5         },
>      { "power6",              BSTZ_P6         },
> -    { "power6-64",   BSTZ_P6_64      },
>      { "altivec",     BSTZ_ALTIVEC    },
>      { "cell",                BSTZ_CELL       },
>      { "vsx",         BSTZ_VSX        },
>      { "power7",              BSTZ_P7         },
> -    { "power7-64",   BSTZ_P7_64      },
>      { "power8",              BSTZ_P8         },
> -    { "power8-vector",       BSTZ_P8V        },
>      { "power9",              BSTZ_P9         },
> -    { "power9-64",   BSTZ_P9_64      },
> -    { "power9-vector",       BSTZ_P9V        },
>      { "ieee128-hw",  BSTZ_IEEE128_HW },
>      { "dfp",         BSTZ_DFP        },
>      { "crypto",              BSTZ_CRYPTO     },
>      { "htm",         BSTZ_HTM        },
>      { "power10",     BSTZ_P10        },
> -    { "power10-64",  BSTZ_P10_64     },
>      { "mma",         BSTZ_MMA        },
>      { "future",      BSTZ_FUTURE     },
> -    { "future-altivec", BSTZ_FUTURE_ALTIVEC },
> -    { "future-vsx",  BSTZ_FUTURE_VSX },
>      { "dm",          BSTZ_DM         }
>    };
>  
>  static const char *enable_string[NUMBIFSTANZAS] =
>    {
>      "ENB_ALWAYS",
> +    "ENB_M64",
>      "ENB_P5",
>      "ENB_P6",
> -    "ENB_P6_64",
>      "ENB_ALTIVEC",
>      "ENB_CELL",
>      "ENB_VSX",
>      "ENB_P7",
> -    "ENB_P7_64",
>      "ENB_P8",
> -    "ENB_P8V",
>      "ENB_P9",
> -    "ENB_P9_64",
> -    "ENB_P9V",
>      "ENB_IEEE128_HW",
>      "ENB_DFP",
>      "ENB_CRYPTO",
>      "ENB_HTM",
>      "ENB_P10",
> -    "ENB_P10_64",
>      "ENB_MMA",
>      "ENB_FUTURE",
> -    "ENB_FUTURE_ALTIVEC",
> -    "ENB_FUTURE_VSX",
>      "ENB_DM"
>    };
>  
> @@ -432,6 +425,8 @@ struct prototype
>  struct bifdata
>  {
>    int stanza;
> +  int num_predicates;
> +  int predicates[MAXBIFPREDICATES];
>    fnkinds kind;
>    prototype proto;
>    char *idname;
> @@ -837,6 +832,56 @@ stanza_name_to_stanza (const char *stanza_name)
>    return BSTZ_ALWAYS;
>  }
>  
> +/* Parse comma-separated gating predicates from a stanza header and
> populate
> +   the predicates array.  Each predicate is specified by a stanza
> name (e.g.,
> +   "power10", "vsx") that represents a gating condition that must be
> satisfied
> +   for the built-in to be enabled.  Multiple predicates are combined
> with AND
> +   logic.  Returns the number of predicates parsed.  */
> +
> +static int
> +parse_bif_stanza_predicates (char *predicates_str, bif_stanza
> *predicates)
> +{
> +  int num_predicates = 0;
> +  char *predicate_name = predicates_str;
> +  char *comma_pos;
> +
> +  while (predicate_name && num_predicates < MAXBIFPREDICATES)
> +    {
> +      /* Find the next comma or end of string.  */
> +      comma_pos = strchr (predicate_name, ',');
> +      if (comma_pos)
> +     *comma_pos = '\0';
> +
> +      /* Trim leading and trailing whitespace from predicate name. 
> */
> +      while (*predicate_name == ' ' || *predicate_name == '\t')
> +     predicate_name++;
> +
> +      char *end = predicate_name + strlen (predicate_name) - 1;
> +      while (end > predicate_name && (*end == ' ' || *end == '\t'))
> +     {
> +       *end = '\0';
> +       end--;
> +     }
> +
> +      if (*predicate_name != '\0')
> +     {
> +       /* Convert predicate name (stanza name) to stanza enum. 
> */
> +       predicates[num_predicates] = stanza_name_to_stanza
> (predicate_name);
> +       num_predicates++;
> +     }
> +
> +      if (comma_pos)
> +     predicate_name = comma_pos + 1;
> +      else
> +     break;
> +    }
> +
> +  if (num_predicates >= MAXBIFPREDICATES && strchr (predicate_name,
> ','))
Can you please check this logic? I think there might be an issue.
Example
[power10, vsx, m64, dm, future]
There are 5 predicates, expected thing is to abort. But since you are
checking strchr (predicate_name, ',') after parsing till dm, the
predicate_name ptr will be here
[power10, vsx, m64, dm, future]
                       ^ 
So this strchr (predicate_name, ',') will return NULL, and the abort
code will not fire as it should.

You could instead skip whitespaces and check that there are no other
additional characters at the end, then you will get proper abort
message if exactly 5 predicates are used.

Also could you please check if this test passes?
pr103627-3.c, as it runs on be 32 bit. It would be good to regtest on
le and be(64 and 32bit).

One another issue is from the test pragma_misc9.c (i have removed the
pragmas for testing)

#include <altivec.h>
vector bool int
test2 (vector signed int a, vector signed int b)
{
  return vec_cmpnez (a, b);
}

I use the correct flags with an addition of mno-module and get this:

-mcpu=power9 -mvsx -mno-modulo
/home/avinashd/cross/gcc-powerpc64le/gcc-
src/gcc/testsuite/gcc.target/powerpc/pragma_misc9.c: In function
‘test2’:
/home/avinashd/cross/gcc-powerpc64le/gcc-
src/gcc/testsuite/gcc.target/powerpc/pragma_misc9.c:16:3: error:
‘__builtin_altivec_vcmpnezw’ requires the ‘-mcpu=power9’ and ‘-mvsx’
options
   16 |   return vec_cmpnez (a, b);

But without this patch it compiles fine. Please have a look I think
[power9-vector] and [power9, vsx] are not equivalent.


Thanks,
Avinash Jayakar
> +    fatal ("Too many predicates in stanza header.\n");
> +
> +  return num_predicates;
> +}
> +
>  /* Match one of the allowable base types.  Consumes one token unless
> the
>     token is "long", which must be paired with a second "long". 
> Optionally
>     consumes a following '*' token for pointers.  Return 1 for
> success,
> @@ -1831,6 +1876,9 @@ parse_bif_entry (void)
>  
>    curr_bif = num_bifs++;
>    bifs[curr_bif].stanza = curr_bif_stanza;
> +  bifs[curr_bif].num_predicates = curr_bif_num_predicates;
> +  for (int i = 0; i < curr_bif_num_predicates; i++)
> +    bifs[curr_bif].predicates[i] = curr_bif_predicates[i];
>  
>    /* Read the first token and see if it is a function modifier.  */
>    consume_whitespace ();
> @@ -1936,14 +1984,25 @@ parse_bif_stanza (void)
>      }
>    safe_inc_pos ();
>  
> -  const char *stanza_name = match_to_right_bracket ();
> -  if (!stanza_name)
> +  const char *stanza_name_const = match_to_right_bracket ();
> +  if (!stanza_name_const)
>      {
>        diag (pos, "no expression found in stanza header.\n");
>        return PC_PARSEFAIL;
>      }
>  
> -  curr_bif_stanza = stanza_name_to_stanza (stanza_name);
> +  /* Make a mutable copy since parse_bif_stanza_predicates modifies
> the
> +     string.  */
> +  char *stanza_name = strdup (stanza_name_const);
> +
> +  curr_bif_num_predicates = parse_bif_stanza_predicates
> (stanza_name,
> +                                                     
> curr_bif_predicates);
> +
> +  free (stanza_name);
> +
> +  /* Store the primary (first) stanza in curr_bif_stanza for
> +     backward compatibility.  */
> +  curr_bif_stanza = curr_bif_predicates[0];
>  
>    if (linebuf[pos] != ']')
>      {
> @@ -2270,37 +2329,32 @@ write_decls (void)
>  
>    fprintf (header_file, "enum bif_enable {\n");
>    fprintf (header_file, "  ENB_ALWAYS,\n");
> +  fprintf (header_file, "  ENB_M64,\n");
>    fprintf (header_file, "  ENB_P5,\n");
>    fprintf (header_file, "  ENB_P6,\n");
> -  fprintf (header_file, "  ENB_P6_64,\n");
>    fprintf (header_file, "  ENB_ALTIVEC,\n");
>    fprintf (header_file, "  ENB_CELL,\n");
>    fprintf (header_file, "  ENB_VSX,\n");
>    fprintf (header_file, "  ENB_P7,\n");
> -  fprintf (header_file, "  ENB_P7_64,\n");
>    fprintf (header_file, "  ENB_P8,\n");
> -  fprintf (header_file, "  ENB_P8V,\n");
>    fprintf (header_file, "  ENB_P9,\n");
> -  fprintf (header_file, "  ENB_P9_64,\n");
> -  fprintf (header_file, "  ENB_P9V,\n");
>    fprintf (header_file, "  ENB_IEEE128_HW,\n");
>    fprintf (header_file, "  ENB_DFP,\n");
>    fprintf (header_file, "  ENB_CRYPTO,\n");
>    fprintf (header_file, "  ENB_HTM,\n");
>    fprintf (header_file, "  ENB_P10,\n");
> -  fprintf (header_file, "  ENB_P10_64,\n");
>    fprintf (header_file, "  ENB_MMA,\n");
>    fprintf (header_file, "  ENB_FUTURE,\n");
> -  fprintf (header_file, "  ENB_FUTURE_ALTIVEC,\n");
> -  fprintf (header_file, "  ENB_FUTURE_VSX,\n");
>    fprintf (header_file, "  ENB_DM\n");
>    fprintf (header_file, "};\n\n");
>  
>    fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
> +  fprintf (header_file, "#define PPC_MAXBIFPREDICATES 4\n");
>    fprintf (header_file, "struct bifdata\n");
>    fprintf (header_file, "{\n");
>    fprintf (header_file, "  const char *bifname;\n");
> -  fprintf (header_file, "  bif_enable enable;\n");
> +  fprintf (header_file, "  int num_enables;\n");
> +  fprintf (header_file, "  bif_enable
> enables[PPC_MAXBIFPREDICATES];\n");
>    fprintf (header_file, "  insn_code icode;\n");
>    fprintf (header_file, "  int nargs;\n");
>    fprintf (header_file, "  int bifattrs;\n");
> @@ -2527,7 +2581,7 @@ write_bif_static_init (void)
>    fprintf (init_file, "bifdata rs6000_builtin_info[RS6000_BIF_MAX]
> =\n");
>    fprintf (init_file, "  {\n");
>    fprintf (init_file, "    { /* RS6000_BIF_NONE: */\n");
> -  fprintf (init_file, "      \"\", ENB_ALWAYS, CODE_FOR_nothing,
> 0,\n");
> +  fprintf (init_file, "      \"\", 0, {ENB_ALWAYS},
> CODE_FOR_nothing, 0,\n");
>    fprintf (init_file, "      0, {0, 0, 0}, {RES_NONE, RES_NONE,
> RES_NONE},\n");
>    fprintf (init_file, "      {0, 0, 0}, {0, 0, 0}, \"\",
> RS6000_BIF_NONE\n");
>    fprintf (init_file, "    },\n");
> @@ -2537,8 +2591,17 @@ write_bif_static_init (void)
>        fprintf (init_file, "    { /* RS6000_BIF_%s: */\n", bifp-
> >idname);
>        fprintf (init_file, "      /* bifname */\t\"%s\",\n",
>              bifp->proto.bifname);
> -      fprintf (init_file, "      /* enable*/\t%s,\n",
> -            enable_string[bifp->stanza]);
> +      /* Output num_enables and enables array.  */
> +      fprintf (init_file, "      /* num_enables */\t%d,\n",
> +            bifp->num_predicates);
> +      fprintf (init_file, "      /* enables */\t{");
> +      for (int j = 0; j < bifp->num_predicates; j++)
> +     {
> +       if (j > 0)
> +         fprintf (init_file, ", ");
> +       fprintf (init_file, "%s", enable_string[bifp-
> >predicates[j]]);
> +     }
> +      fprintf (init_file, "},\n");
>        fprintf (init_file, "      /* icode */\tCODE_FOR_%s,\n",
>              bifp->patname);
>        fprintf (init_file, "      /* nargs */\t%d,\n",
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr96125.c
> b/gcc/testsuite/gcc.target/powerpc/pr96125.c
> index a4bb0d55786..29711cac796 100644
> --- a/gcc/testsuite/gcc.target/powerpc/pr96125.c
> +++ b/gcc/testsuite/gcc.target/powerpc/pr96125.c
> @@ -15,7 +15,7 @@ void
>  test1 (__vector_quad *dst)
>  {
>    __vector_quad acc;
> -  __builtin_mma_xxsetaccz (&acc); /* { dg-error
> "'__builtin_mma_xxsetaccz' requires the '-mmma' option" } */
> +  __builtin_mma_xxsetaccz (&acc); /* { dg-error
> "'__builtin_mma_xxsetaccz' requires the '-mcpu=power10' and '-mmma'
> options" } */
>    *dst = acc;
>  }
>  
> @@ -41,7 +41,7 @@ void
>  test4 (__vector_quad *dst)
>  {
>    __vector_quad acc;
> -  __builtin_mma_xxmfacc (&acc); /* { dg-error
> "'__builtin_mma_xxmfacc' requires the '-mmma' option" } */
> +  __builtin_mma_xxmfacc (&acc); /* { dg-error
> "'__builtin_mma_xxmfacc' requires the '-mcpu=power10' and '-mmma'
> options" } */
>    *dst = acc;
>  }
>  

Reply via email to