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

Reply via email to