poly_int: process_alt_operands
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 3 Jan 2018 07:18:38 +0000 (07:18 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 3 Jan 2018 07:18:38 +0000 (07:18 +0000)
This patch makes process_alt_operands check that the mode sizes
are ordered, so that match_reload can validly treat them as subregs
of one another.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* lra-constraints.c (process_alt_operands): Reject matched
operands whose sizes aren't ordered.
(match_reload): Refer to this check here.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256158

gcc/ChangeLog
gcc/lra-constraints.c

index 2eea29ba5e0a349f7e665b52a6d64e0022afbd23..799be1c22efc674db278e3d621c962b8a1854902 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * lra-constraints.c (process_alt_operands): Reject matched
+       operands whose sizes aren't ordered.
+       (match_reload): Refer to this check here.
+
 2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 73ffba2c75fc2cd85c42e275224013f05d35e337..59daf11062a8e8a5d4ccd8bd4e5b779ae538b97b 100644 (file)
@@ -933,6 +933,8 @@ match_reload (signed char out, signed char *ins, signed char *outs,
   push_to_sequence (*before);
   if (inmode != outmode)
     {
+      /* process_alt_operands has already checked that the mode sizes
+        are ordered.  */
       if (partial_subreg_p (outmode, inmode))
        {
          reg = new_in_reg
@@ -2112,6 +2114,13 @@ process_alt_operands (int only_alternative)
                    len = 0;
                    lra_assert (nop > m);
 
+                   /* Reject matches if we don't know which operand is
+                      bigger.  This situation would arguably be a bug in
+                      an .md pattern, but could also occur in a user asm.  */
+                   if (!ordered_p (GET_MODE_SIZE (biggest_mode[m]),
+                                   GET_MODE_SIZE (biggest_mode[nop])))
+                     break;
+
                    this_alternative_matches = m;
                    m_hregno = get_hard_regno (*curr_id->operand_loc[m], false);
                    /* We are supposed to match a previous operand.