[58/77] Use scalar_int_mode in a try_combine optimisation
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 30 Aug 2017 11:18:29 +0000 (11:18 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Aug 2017 11:18:29 +0000 (11:18 +0000)
This patch uses scalar_int_modes for:

  /* If I2 is setting a pseudo to a constant and I3 is setting some
     sub-part of it to another constant, merge them by making a new
     constant.  */

This was already implicit, but the danger with checking only
CONST_SCALAR_INT_P is that it can include CC values too.

2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* combine.c (try_combine): Use is_a <scalar_int_mode> when
trying to combine a full-register integer set with a subreg
integer set.

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

gcc/ChangeLog
gcc/combine.c

index 51f6f374546fac22cb63a5e99fc1da68a19019b6..3fb54e6c82fba79e5d670d15e422f9fb2b7ef09b 100644 (file)
@@ -1,3 +1,11 @@
+2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * combine.c (try_combine): Use is_a <scalar_int_mode> when
+       trying to combine a full-register integer set with a subreg
+       integer set.
+
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 85a2f50bca6254938ad33741737d9e406acfd05a..022a5b5f15c4c77949961bfbe880a6507c176c2f 100644 (file)
@@ -2645,6 +2645,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
   rtx other_pat = 0;
   rtx new_other_notes;
   int i;
+  scalar_int_mode dest_mode, temp_mode;
 
   /* Immediately return if any of I0,I1,I2 are the same insn (I3 can
      never be).  */
@@ -2847,33 +2848,40 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
      constant.  */
   if (i1 == 0
       && (temp_expr = single_set (i2)) != 0
+      && is_a <scalar_int_mode> (GET_MODE (SET_DEST (temp_expr)), &temp_mode)
       && CONST_SCALAR_INT_P (SET_SRC (temp_expr))
       && GET_CODE (PATTERN (i3)) == SET
       && CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))
       && reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp_expr)))
     {
       rtx dest = SET_DEST (PATTERN (i3));
+      rtx temp_dest = SET_DEST (temp_expr);
       int offset = -1;
       int width = 0;
-      
+
       if (GET_CODE (dest) == ZERO_EXTRACT)
        {
          if (CONST_INT_P (XEXP (dest, 1))
-             && CONST_INT_P (XEXP (dest, 2)))
+             && CONST_INT_P (XEXP (dest, 2))
+             && is_a <scalar_int_mode> (GET_MODE (XEXP (dest, 0)),
+                                        &dest_mode))
            {
              width = INTVAL (XEXP (dest, 1));
              offset = INTVAL (XEXP (dest, 2));
              dest = XEXP (dest, 0);
              if (BITS_BIG_ENDIAN)
-               offset = GET_MODE_PRECISION (GET_MODE (dest)) - width - offset;
+               offset = GET_MODE_PRECISION (dest_mode) - width - offset;
            }
        }
       else
        {
          if (GET_CODE (dest) == STRICT_LOW_PART)
            dest = XEXP (dest, 0);
-         width = GET_MODE_PRECISION (GET_MODE (dest));
-         offset = 0;
+         if (is_a <scalar_int_mode> (GET_MODE (dest), &dest_mode))
+           {
+             width = GET_MODE_PRECISION (dest_mode);
+             offset = 0;
+           }
        }
 
       if (offset >= 0)
@@ -2882,9 +2890,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
          if (subreg_lowpart_p (dest))
            ;
          /* Handle the case where inner is twice the size of outer.  */
-         else if (GET_MODE_PRECISION (GET_MODE (SET_DEST (temp_expr)))
-                  == 2 * GET_MODE_PRECISION (GET_MODE (dest)))
-           offset += GET_MODE_PRECISION (GET_MODE (dest));
+         else if (GET_MODE_PRECISION (temp_mode)
+                  == 2 * GET_MODE_PRECISION (dest_mode))
+           offset += GET_MODE_PRECISION (dest_mode);
          /* Otherwise give up for now.  */
          else
            offset = -1;
@@ -2895,23 +2903,22 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
          rtx inner = SET_SRC (PATTERN (i3));
          rtx outer = SET_SRC (temp_expr);
 
-         wide_int o
-           = wi::insert (rtx_mode_t (outer, GET_MODE (SET_DEST (temp_expr))),
-                         rtx_mode_t (inner, GET_MODE (dest)),
-                         offset, width);
+         wide_int o = wi::insert (rtx_mode_t (outer, temp_mode),
+                                  rtx_mode_t (inner, dest_mode),
+                                  offset, width);
 
          combine_merges++;
          subst_insn = i3;
          subst_low_luid = DF_INSN_LUID (i2);
          added_sets_2 = added_sets_1 = added_sets_0 = 0;
-         i2dest = SET_DEST (temp_expr);
+         i2dest = temp_dest;
          i2dest_killed = dead_or_set_p (i2, i2dest);
 
          /* Replace the source in I2 with the new constant and make the
             resulting insn the new pattern for I3.  Then skip to where we
             validate the pattern.  Everything was set up above.  */
          SUBST (SET_SRC (temp_expr),
-                immed_wide_int_const (o, GET_MODE (SET_DEST (temp_expr))));
+                immed_wide_int_const (o, temp_mode));
 
          newpat = PATTERN (i2);