Tests gcc.dg/asm-hard-reg-error-{4,5}.c ICE on sparc*-sun-solaris2.11 since in tm-preds.h we have
#define CONSTRAINT_LEN(c_,s_) 1 and, therefore, do not parse hard register constraints correctly. Hard register constraints are non-single character constraints and require insn_constraint_len() in order to determine the length. In write_tm_preds_h() from genpreds.cc, previously variable constraint_max_namelen was used in order to decide whether we have single or non-single character constraints: if (constraint_max_namelen > 1) { write_insn_constraint_len (); puts ("#define CONSTRAINT_LEN(c_,s_) " "insn_constraint_len (c_,s_)\n"); } else puts ("#define CONSTRAINT_LEN(c_,s_) 1\n"); The distinction shouldn't be done anymore and we always must call into insn_constraint_len(). Skimming over the remaining uses of constraint_max_namelen, the variable was also used in order to decide whether we have any constraint at all. My understanding is that, coming from common.md, every target has at least a register constraint (among other constraints coming from common.md) which means constraint_max_namelen > 0 should be always true. Or in other words, if that wouldn't be true, then CONSTRAINT_LEN wouldn't be defined which would result in compile errors. At least I didn't find another spot were it is defined. I might have overlooked something which is why I kept the old behaviour but reduced it to a boolean instead of a counting variable. Would be great if someone could have a second look. If constraint_max_namelen > 0 is indeed useless we could remove the check entirely. gcc/ChangeLog: * genpreds.cc (add_constraint): Don't track the maximal constraint length but rather whether we have any at all. (write_tm_preds_h): Always write insn_constraint_len() and define CONSTRAINT_LEN to it. --- gcc/genpreds.cc | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/gcc/genpreds.cc b/gcc/genpreds.cc index 4f8beeb0514..4ed6dcdd81c 100644 --- a/gcc/genpreds.cc +++ b/gcc/genpreds.cc @@ -719,7 +719,7 @@ static const char const_dbl_constraints[] = "GH"; /* Summary data used to decide whether to output various functions and macro definitions. */ -static unsigned int constraint_max_namelen; +static bool have_constraints; static bool have_register_constraints; static bool have_memory_constraints; static bool have_special_memory_constraints; @@ -942,7 +942,7 @@ add_constraint (const char *name, const char *regclass, *last_constraint_ptr = c; last_constraint_ptr = &c->next_textual; - constraint_max_namelen = MAX (constraint_max_namelen, strlen (name)); + have_constraints = true; have_register_constraints |= c->is_register; have_const_int_constraints |= c->is_const_int; have_extra_constraints |= c->is_extra; @@ -1563,7 +1563,7 @@ write_tm_preds_h (void) "#endif\n" "\n"); - if (constraint_max_namelen > 0) + if (have_constraints) { write_enum_constraint_num (); puts ("extern enum constraint_num lookup_constraint_1 (const char *);\n" @@ -1616,14 +1616,8 @@ write_tm_preds_h (void) address_start, address_end); write_allows_reg_mem_function (); - if (constraint_max_namelen > 1) - { - write_insn_constraint_len (); - puts ("#define CONSTRAINT_LEN(c_,s_) " - "insn_constraint_len (c_,s_)\n"); - } - else - puts ("#define CONSTRAINT_LEN(c_,s_) 1\n"); + write_insn_constraint_len (); + puts ("#define CONSTRAINT_LEN(c_,s_) insn_constraint_len (c_,s_)\n"); if (have_register_constraints) puts ("extern enum reg_class reg_class_for_constraint_1 " "(enum constraint_num);\n" @@ -1750,7 +1744,7 @@ write_insn_preds_c (void) FOR_ALL_PREDICATES (p) write_one_predicate_function (p); - if (constraint_max_namelen > 0) + if (have_constraints) { write_lookup_constraint_1 (); write_lookup_constraint_array (); -- 2.49.0