This patch corrects an error introduced with commit 241314. That patch introduced several new built-in functions to support Power9 string instructions. The error that was found subsequent to the trunk commit is that initialization of the built-in function tables encounters an internal compiler error if the assembler that is used with gcc lacks support for Power9 instructions.
This patch disables initialization of built-in functions which depend on assembler capabilities that are not supported by the associated tool chain. This patch has been booted and regression tested on powerpcle-unknown-linux, trunk revision 241406. (I was not able to regression test on the most current trunk because that trunk does not boot.) I have also successfully boot-strapped this patch on a Power7 system for which the assembler lacks support for Power9. (I could not regression test on that platform because that platform could not bootstrap without this patch.) It is planned that a subsequent enhancement to this patch will make the following improvements: 1. Fail with an assertion error instead of an internal compiler error if built-in functions are ever defined for which the corresponding instruction pattern is not supported by the current compiler configuration. 2. Issue a warning message whenever a command-line -mcpu=XXX request seeks to configure support for a CPU version which is not supported by the accompanying assembler. I am submitting the patch as is in order to expedite integration since the error has broken the trunk for certain system configurations. Is this patch ok for trunk? gcc/ChangeLog: 2016-10-25 Kelvin Nilsen <kel...@gcc.gnu.org> PR target/78056 * config/rs6000/rs6000.c (spe_init_builtins): Modify loops to not define builtin functions from the bdesc_spe_predicates or bdesc_spe_evsel arrays if the builtin mask is not compatible with the current compiler configuration. (paired_init_builtins): Modify loop to not define define builtin functions from the bdesc_paried_preds array if the builtin mask is not compatible with the current compiler configuration. (altivec_init_builtins): Modify loops to not define the __builtin_altivec_stxvl function nor the builtin functions from the bdesc_dst or bdesc_altivec_preds, bdesc_abs gcc/testsuite/ChangeLog: 2016-10-25 Kelvin Nilsen <kel...@gcc.gnu.org> PR target/78056 * gcc.target/powerpc/vsu/vec-any-eqz-7.c (test_any_equal): Change expected error message. * gcc.target/powerpc/vsu/vec-xst-len-12.c (store_data): Change expected error message. * gcc.target/powerpc/vsu/vec-all-nez-7.c (test_all_not_equal_and_not_zero): Change expected error message. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 241406) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -16923,6 +16923,7 @@ spe_init_builtins (void) tree pushort_type_node = build_pointer_type (short_unsigned_type_node); const struct builtin_description *d; size_t i; + HOST_WIDE_INT builtin_mask = rs6000_builtin_mask; tree v2si_ftype_4_v2si = build_function_type_list (opaque_V2SI_type_node, @@ -17063,7 +17064,16 @@ spe_init_builtins (void) for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++) { tree type; + HOST_WIDE_INT mask = d->mask; + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "spe_init_builtins, skip predicate %s\n", + d->name); + continue; + } + switch (insn_data[d->icode].operand[1].mode) { case V2SImode: @@ -17084,7 +17094,16 @@ spe_init_builtins (void) for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++) { tree type; + HOST_WIDE_INT mask = d->mask; + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "spe_init_builtins, skip evsel %s\n", + d->name); + continue; + } + switch (insn_data[d->icode].operand[1].mode) { case V2SImode: @@ -17106,6 +17125,7 @@ paired_init_builtins (void) { const struct builtin_description *d; size_t i; + HOST_WIDE_INT builtin_mask = rs6000_builtin_mask; tree int_ftype_int_v2sf_v2sf = build_function_type_list (integer_type_node, @@ -17141,7 +17161,16 @@ paired_init_builtins (void) for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++) { tree type; + HOST_WIDE_INT mask = d->mask; + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "paired_init_builtins, skip predicate %s\n", + d->name); + continue; + } + if (TARGET_DEBUG_BUILTIN) fprintf (stderr, "paired pred #%d, insn = %s [%d], mode = %s\n", (int)i, get_insn_name (d->icode), (int)d->icode, @@ -17167,6 +17196,7 @@ altivec_init_builtins (void) size_t i; tree ftype; tree decl; + HOST_WIDE_INT builtin_mask = rs6000_builtin_mask; tree pvoid_type_node = build_pointer_type (void_type_node); @@ -17500,14 +17530,26 @@ altivec_init_builtins (void) def_builtin ("__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX); def_builtin ("__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL); - def_builtin ("__builtin_altivec_stxvl", void_ftype_v16qi_pvoid_long, - P9V_BUILTIN_STXVL); + if (TARGET_P9_VECTOR) + def_builtin ("__builtin_altivec_stxvl", void_ftype_v16qi_pvoid_long, + P9V_BUILTIN_STXVL); /* Add the DST variants. */ d = bdesc_dst; for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++) - def_builtin (d->name, void_ftype_pcvoid_int_int, d->code); + { + HOST_WIDE_INT mask = d->mask; + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "altivec_init_builtins, skip dst %s\n", + d->name); + continue; + } + def_builtin (d->name, void_ftype_pcvoid_int_int, d->code); + } + /* Initialize the predicates. */ d = bdesc_altivec_preds; for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++) @@ -17514,7 +17556,16 @@ altivec_init_builtins (void) { machine_mode mode1; tree type; + HOST_WIDE_INT mask = d->mask; + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "altivec_init_builtins, skip predicate %s\n", + d->name); + continue; + } + if (rs6000_overloaded_builtin_p (d->code)) mode1 = VOIDmode; else @@ -17556,7 +17607,16 @@ altivec_init_builtins (void) { machine_mode mode0; tree type; + HOST_WIDE_INT mask = d->mask; + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "altivec_init_builtins, skip abs %s\n", + d->name); + continue; + } + mode0 = insn_data[d->icode].operand[0].mode; switch (mode0) Index: gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c (revision 241406) +++ gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c (working copy) @@ -12,5 +12,5 @@ test_all_not_equal_and_not_zero (vector unsigned s vector unsigned short arg_1 = *arg1_p; vector unsigned short arg_2 = *arg2_p; - return __builtin_vec_vcmpnez_p (__CR6_LT, arg_1, arg_2); /* { dg-error "Builtin function __builtin_altivec_vcmpnezh_p requires" } */ + return __builtin_vec_vcmpnez_p (__CR6_LT, arg_1, arg_2); /* { dg-error "Builtin function __builtin_vec_vcmpnez_p not supported in this compiler configuration" } */ } Index: gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c (revision 241406) +++ gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c (working copy) @@ -14,5 +14,5 @@ store_data (vector double *datap, double *address, { vector double data = *datap; - __builtin_vec_stxvl (data, address, length); /* { dg-error "Builtin function __builtin_altivec_stxvl requires" } */ + __builtin_vec_stxvl (data, address, length); /* { dg-error "Builtin function __builtin_vec_stxvl not supported in this compiler configuration" } */ } Index: gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c (revision 241406) +++ gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c (working copy) @@ -11,5 +11,5 @@ test_any_equal (vector unsigned int *arg1_p, vecto vector unsigned int arg_1 = *arg1_p; vector unsigned int arg_2 = *arg2_p; - return __builtin_vec_vcmpnez_p (__CR6_LT_REV, arg_1, arg_2); /* { dg-error "Builtin function __builtin_altivec_vcmpnezw_p requires" } */ + return __builtin_vec_vcmpnez_p (__CR6_LT_REV, arg_1, arg_2); /* { dg-error "Builtin function __builtin_vec_vcmpnez_p not supported in this compiler configuration" } */ }