Make more use of paradoxical_subreg_p
authorRichard Sandiford <richard.sandiford@linaro.org>
Tue, 22 Aug 2017 16:14:48 +0000 (16:14 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 22 Aug 2017 16:14:48 +0000 (16:14 +0000)
This patch makes more use of the existing paradoxical_subreg_p
predicate and also adds a version that operates on outer and
inner modes.

Some of the affected tests were based on GET_MODE_SIZE rather than
GET_MODE_PRECISION and so the patch could change the result for modes
that have the same size but different precisions.  I think in each
case the change should be a no-op or more correct, since a mode with
precision N bits can't be expected to hold all of a mode with precision
M>N bits.

The patch changes the branch taken in simplify_subreg for modes with
equal precision, but the new form matches the commentary more closely.
Both branches should be equally good in that situation.

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

gcc/
* rtl.h (paradoxical_subreg_p): Define inline, and add a version
that takes the outer and inner modes.
* doc/rtl.texi: Use paradoxical_subreg_p instead of a GET_MODE_SIZE
comparison as the canonical test for a paradoxical subreg.
* combine.c (simplify_set): Use paradoxical_subreg_p.
(make_extraction): Likewise.
(force_to_mode): Likewise.
(rtx_equal_for_field_assignment_p): Likewise.
(gen_lowpart_for_combine): Likewise.
(simplify_comparison): Likewise.
* cse.c (equiv_constant): Likewise.
* expmed.c (store_bit_field_1): Likewise.
* final.c (alter_subreg): Likewise.
* fwprop.c (propagate_rtx): Likewise.
(forward_propagate_subreg): Likewise.
* ira-conflicts.c (ira_build_conflicts): Likewise.
* lower-subreg.c (simplify_gen_subreg_concatn): Likewise.
* lra-constraints.c (curr_insn_transform): Likewise.
(split_reg): Likewise.
* lra-eliminations.c (move_plus_up): Likewise.
(lra_eliminate_regs_1): Likewise.
* recog.c (general_operand): Likewise.
* ree.c (combine_reaching_defs): Likewise.
* reload.c (push_reload): Likewise.
(find_reloads): Likewise.
* reload1.c (elimination_effects): Likewise.
(compute_reload_subreg_offset): Likewise.
(choose_reload_regs): Likewise.
* rtlanal.c (subreg_lsb_1): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
(simplify_subreg): Likewise.
* var-tracking.c (track_loc_p): Likewise.
* emit-rtl.c (byte_lowpart_offset): Likewise.
(paradoxical_subreg_p): Delete out-of-line definition.

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

20 files changed:
gcc/ChangeLog
gcc/combine.c
gcc/cse.c
gcc/doc/rtl.texi
gcc/emit-rtl.c
gcc/expmed.c
gcc/final.c
gcc/fwprop.c
gcc/ira-conflicts.c
gcc/lower-subreg.c
gcc/lra-constraints.c
gcc/lra-eliminations.c
gcc/recog.c
gcc/ree.c
gcc/reload.c
gcc/reload1.c
gcc/rtl.h
gcc/rtlanal.c
gcc/simplify-rtx.c
gcc/var-tracking.c

index 9b941af74c69efbb362b1fa3defc6cef3f5f6c61..6153bd965167df06726c597f433701f66f5e6b33 100644 (file)
@@ -1,3 +1,42 @@
+2017-08-22  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * rtl.h (paradoxical_subreg_p): Define inline, and add a version
+       that takes the outer and inner modes.
+       * doc/rtl.texi: Use paradoxical_subreg_p instead of a GET_MODE_SIZE
+       comparison as the canonical test for a paradoxical subreg.
+       * combine.c (simplify_set): Use paradoxical_subreg_p.
+       (make_extraction): Likewise.
+       (force_to_mode): Likewise.
+       (rtx_equal_for_field_assignment_p): Likewise.
+       (gen_lowpart_for_combine): Likewise.
+       (simplify_comparison): Likewise.
+       * cse.c (equiv_constant): Likewise.
+       * expmed.c (store_bit_field_1): Likewise.
+       * final.c (alter_subreg): Likewise.
+       * fwprop.c (propagate_rtx): Likewise.
+       (forward_propagate_subreg): Likewise.
+       * ira-conflicts.c (ira_build_conflicts): Likewise.
+       * lower-subreg.c (simplify_gen_subreg_concatn): Likewise.
+       * lra-constraints.c (curr_insn_transform): Likewise.
+       (split_reg): Likewise.
+       * lra-eliminations.c (move_plus_up): Likewise.
+       (lra_eliminate_regs_1): Likewise.
+       * recog.c (general_operand): Likewise.
+       * ree.c (combine_reaching_defs): Likewise.
+       * reload.c (push_reload): Likewise.
+       (find_reloads): Likewise.
+       * reload1.c (elimination_effects): Likewise.
+       (compute_reload_subreg_offset): Likewise.
+       (choose_reload_regs): Likewise.
+       * rtlanal.c (subreg_lsb_1): Likewise.
+       * simplify-rtx.c (simplify_unary_operation_1): Likewise.
+       (simplify_subreg): Likewise.
+       * var-tracking.c (track_loc_p): Likewise.
+       * emit-rtl.c (byte_lowpart_offset): Likewise.
+       (paradoxical_subreg_p): Delete out-of-line definition.
+
 2017-08-22  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/81741
index 8dc62b57266ba29a5e917d966a6d3166ea12f539..7aa0a359f489bc8d9ccb6227b852cfe90f20e98c 100644 (file)
@@ -6809,9 +6809,7 @@ simplify_set (rtx x)
           / UNITS_PER_WORD)
          == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
               + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
-      && (WORD_REGISTER_OPERATIONS
-         || (GET_MODE_SIZE (GET_MODE (src))
-             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
+      && (WORD_REGISTER_OPERATIONS || !paradoxical_subreg_p (src))
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
            && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
@@ -7456,7 +7454,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
                     : BITS_PER_UNIT)) == 0
              /* We can't do this if we are widening INNER_MODE (it
                 may not be aligned, for one thing).  */
-             && GET_MODE_PRECISION (inner_mode) >= GET_MODE_PRECISION (tmode)
+             && !paradoxical_subreg_p (tmode, inner_mode)
              && (inner_mode == tmode
                  || (! mode_dependent_address_p (XEXP (inner, 0),
                                                  MEM_ADDR_SPACE (inner))
@@ -7669,7 +7667,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
       /* If bytes are big endian and we had a paradoxical SUBREG, we must
         adjust OFFSET to compensate.  */
       if (BYTES_BIG_ENDIAN
-         && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
+         && paradoxical_subreg_p (is_mode, inner_mode))
        offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
 
       /* We can now move to the desired byte.  */
@@ -8529,7 +8527,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
 
   /* If X is narrower than MODE and we want all the bits in X's mode, just
      get X in the proper mode.  */
-  if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
+  if (paradoxical_subreg_p (mode, GET_MODE (x))
       && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
     return gen_lowpart (mode, x);
 
@@ -9408,7 +9406,7 @@ rtx_equal_for_field_assignment_p (rtx x, rtx y, bool widen_x)
 {
   if (widen_x && GET_MODE (x) != GET_MODE (y))
     {
-      if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (y)))
+      if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (y)))
        return 0;
       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
        return 0;
@@ -11488,7 +11486,7 @@ gen_lowpart_for_combine (machine_mode omode, rtx x)
       /* If we want to refer to something bigger than the original memref,
         generate a paradoxical subreg instead.  That will force a reload
         of the original memref X.  */
-      if (isize < osize)
+      if (paradoxical_subreg_p (omode, imode))
        return gen_rtx_SUBREG (omode, x, 0);
 
       if (WORDS_BIG_ENDIAN)
@@ -12145,8 +12143,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
 
          /* If the inner mode is narrower and we are extracting the low part,
             we can treat the SUBREG as if it were a ZERO_EXTEND.  */
-         if (subreg_lowpart_p (op0)
-             && GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op0))) < mode_width)
+         if (paradoxical_subreg_p (op0))
            ;
          else if (subreg_lowpart_p (op0)
                   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
index 6a968d1978832c25cda2a0726203f73c9ed37741..dfcebbfbc02a18390243e60c3098da74a5556608 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -3802,7 +3802,7 @@ equiv_constant (rtx x)
         the subreg.  Note that the upper bits of paradoxical subregs
         are undefined, so they cannot be said to equal anything.  */
       if (REG_P (SUBREG_REG (x))
-         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (imode)
+         && !paradoxical_subreg_p (x)
          && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
         return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));
 
index 6e2799a1ce95d96d34ce9741e1ef34969ee4b3ea..12355c2fbad72c9b3820ad90449372638b618487 100644 (file)
@@ -1872,7 +1872,7 @@ expression is called @dfn{paradoxical}.  The canonical test for this
 class of @code{subreg} is:
 
 @smallexample
-GET_MODE_SIZE (@var{m1}) > GET_MODE_SIZE (@var{m2})
+paradoxical_subreg_p (@var{m1}, @var{m2})
 @end smallexample
 
 Paradoxical @code{subreg}s can be used as both lvalues and rvalues.
index 6951f61703b3452aed7f596cbb1d53b38f7b00dd..c1438d66cb38af3bc829684b987acae74c252350 100644 (file)
@@ -1008,10 +1008,10 @@ int
 byte_lowpart_offset (machine_mode outer_mode,
                     machine_mode inner_mode)
 {
-  if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode))
-    return subreg_lowpart_offset (outer_mode, inner_mode);
-  else
+  if (paradoxical_subreg_p (outer_mode, inner_mode))
     return -subreg_lowpart_offset (inner_mode, outer_mode);
+  else
+    return subreg_lowpart_offset (outer_mode, inner_mode);
 }
 \f
 /* Generate a REG rtx for a new pseudo register of mode MODE.
@@ -1552,16 +1552,6 @@ subreg_lowpart_p (const_rtx x)
   return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
          == SUBREG_BYTE (x));
 }
-
-/* Return true if X is a paradoxical subreg, false otherwise.  */
-bool
-paradoxical_subreg_p (const_rtx x)
-{
-  if (GET_CODE (x) != SUBREG)
-    return false;
-  return (GET_MODE_PRECISION (GET_MODE (x))
-         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (x))));
-}
 \f
 /* Return subword OFFSET of operand OP.
    The word number, OFFSET, is interpreted as the word number starting
index 8da98f5dc79bc79b2edf1c7fb986a5ea5a2718df..37f2df819fb7adaa4eb4b211d140c79ac2542741 100644 (file)
@@ -736,7 +736,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       int byte_offset = 0;
 
       /* Paradoxical subregs need special handling on big-endian machines.  */
-      if (SUBREG_BYTE (op0) == 0 && inner_mode_size < outer_mode_size)
+      if (paradoxical_subreg_p (op0))
        {
          int difference = inner_mode_size - outer_mode_size;
 
index 5cc0a1ebbc9e8e9dc66fba4e1f559984834eee64..be41d6e10f0f29e3be6e585a1844b9e9ec17968b 100644 (file)
@@ -3204,8 +3204,7 @@ alter_subreg (rtx *xp, bool final_p)
 
       /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
         contains 0 instead of the proper offset.  See simplify_subreg.  */
-      if (offset == 0
-         && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
+      if (paradoxical_subreg_p (x))
         {
           int difference = GET_MODE_SIZE (GET_MODE (y))
                           - GET_MODE_SIZE (GET_MODE (x));
index 0ab25efdb8565fa0110307060916cdc309ccbf11..cab801e5cc75ebeaf99ee1de2bb6306d4fed10e3 100644 (file)
@@ -680,8 +680,7 @@ propagate_rtx (rtx x, machine_mode mode, rtx old_rtx, rtx new_rtx,
       || CONSTANT_P (new_rtx)
       || (GET_CODE (new_rtx) == SUBREG
          && REG_P (SUBREG_REG (new_rtx))
-         && (GET_MODE_SIZE (mode)
-             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (new_rtx))))))
+         && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (new_rtx)))))
     flags |= PR_CAN_APPEAR;
   if (!varying_mem_p (new_rtx))
     flags |= PR_HANDLE_MEM;
@@ -1103,9 +1102,7 @@ forward_propagate_subreg (df_ref use, rtx_insn *def_insn, rtx def_set)
       || !REG_P (SET_DEST (def_set)))
     return false;
 
-  /* If this is a paradoxical SUBREG...  */
-  if (GET_MODE_SIZE (use_mode)
-      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (use_reg))))
+  if (paradoxical_subreg_p (use_reg))
     {
       /* If this is a paradoxical SUBREG, we have no idea what value the
         extra bits would have.  However, if the operand is equivalent to
index 57dba151d8d9beec38166bda6b139c4983596483..e3d479383d631aead71e674f3779396735468d45 100644 (file)
@@ -775,7 +775,7 @@ ira_build_conflicts (void)
             cannot be accessed in the widest mode.  */
          machine_mode outer_mode = ALLOCNO_WMODE (a);
          machine_mode inner_mode = ALLOCNO_MODE (a);
-         if (GET_MODE_SIZE (outer_mode) > GET_MODE_SIZE (inner_mode))
+         if (paradoxical_subreg_p (outer_mode, inner_mode))
            {
              enum reg_class aclass = ALLOCNO_CLASS (a);
              for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
index 1ab1c71211f5bcea98c6718a8532e7f73a078adf..422b4913b4a39c30bcc0ed15ffcd357c8b565a87 100644 (file)
@@ -661,10 +661,8 @@ simplify_gen_subreg_concatn (machine_mode outermode, rtx op,
       if (op2 == NULL_RTX)
        {
          /* We don't handle paradoxical subregs here.  */
-         gcc_assert (GET_MODE_SIZE (outermode)
-                     <= GET_MODE_SIZE (GET_MODE (op)));
-         gcc_assert (GET_MODE_SIZE (GET_MODE (op))
-                     <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))));
+         gcc_assert (!paradoxical_subreg_p (outermode, GET_MODE (op)));
+         gcc_assert (!paradoxical_subreg_p (op));
          op2 = simplify_subreg_concatn (outermode, SUBREG_REG (op),
                                         byte + SUBREG_BYTE (op));
          gcc_assert (op2 != NULL_RTX);
@@ -685,10 +683,7 @@ simplify_gen_subreg_concatn (machine_mode outermode, rtx op,
      resolve_simple_move will ask for the high part of the paradoxical
      subreg, which does not have a value.  Just return a zero.  */
   if (ret == NULL_RTX
-      && GET_CODE (op) == SUBREG
-      && SUBREG_BYTE (op) == 0
-      && (GET_MODE_SIZE (innermode)
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
+      && paradoxical_subreg_p (op))
     return CONST0_RTX (outermode);
 
   gcc_assert (ret != NULL_RTX);
index b1d864fb9742020c0bc7256d47a5add66c2cd1a0..cefa31968da6fbd228267ebcc39b81f77b8e8bf8 100644 (file)
@@ -4225,8 +4225,7 @@ curr_insn_transform (bool check_only_p)
                  /* Strict_low_part requires reload the register not
                     the sub-register.  */
                  && (curr_static_id->operand[i].strict_low
-                     || (GET_MODE_SIZE (mode)
-                         <= GET_MODE_SIZE (GET_MODE (reg))
+                     || (!paradoxical_subreg_p (mode, GET_MODE (reg))
                          && (hard_regno
                              = get_try_hard_regno (REGNO (reg))) >= 0
                          && (simplify_subreg_regno
@@ -5465,7 +5464,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
         mode was larger than a register, just use the reg_rtx.  Otherwise,
         limit the size to that of the biggest access in the function.  */
       if (mode == VOIDmode
-         || GET_MODE_SIZE (mode) > GET_MODE_SIZE (reg_rtx_mode))
+         || paradoxical_subreg_p (mode, reg_rtx_mode))
        {
          original_reg = regno_reg_rtx[hard_regno];
          mode = reg_rtx_mode;
index 900e4d462b9573cc046ca24c5774547775f239f0..24a02ef12088f5c38bbb59adfd419f4ab8897547 100644 (file)
@@ -286,8 +286,8 @@ move_plus_up (rtx x)
   subreg_reg = SUBREG_REG (x);
   x_mode = GET_MODE (x);
   subreg_reg_mode = GET_MODE (subreg_reg);
-  if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
-      && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
+  if (!paradoxical_subreg_p (x)
+      && GET_CODE (subreg_reg) == PLUS
       && CONSTANT_P (XEXP (subreg_reg, 1))
       && GET_MODE_CLASS (x_mode) == MODE_INT
       && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
@@ -605,10 +605,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
 
       if (new_rtx != SUBREG_REG (x))
        {
-         int x_size = GET_MODE_SIZE (GET_MODE (x));
-         int new_size = GET_MODE_SIZE (GET_MODE (new_rtx));
-
-         if (MEM_P (new_rtx) && x_size <= new_size)
+         if (MEM_P (new_rtx) && !paradoxical_subreg_p (x))
            {
              SUBREG_REG (x) = new_rtx;
              alter_subreg (&x, false);
index fd4e46058307b53516c59d3ca5508cdd26a35c00..4467bf73a6fb1daf4969feaae97d119c5171ce2b 100644 (file)
@@ -1002,7 +1002,7 @@ general_operand (rtx op, machine_mode mode)
         However, we must allow them after reload so that they can
         get cleaned up by cleanup_subreg_operands.  */
       if (!reload_completed && MEM_P (sub)
-         && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
+         && paradoxical_subreg_p (op))
        return 0;
 #endif
       /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
@@ -1037,7 +1037,7 @@ general_operand (rtx op, machine_mode mode)
             size of floating point mode can be less than the integer
             mode.  */
          && ! lra_in_progress 
-         && GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
+         && paradoxical_subreg_p (op))
        return 0;
 
       op = sub;
index 40b4041ef874b954bff311982fec6de14a16b867..bffb18b2b0a9416d9fb72d71c1a861d15dceae24 100644 (file)
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -869,7 +869,8 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
            return false;
 
          for (df_link *use = uses; use; use = use->next)
-           if (GET_MODE_PRECISION (GET_MODE (*DF_REF_LOC (use->ref))) > prec)
+           if (paradoxical_subreg_p (GET_MODE (*DF_REF_LOC (use->ref)),
+                                     GET_MODE (SET_DEST (*dest_sub_rtx))))
              return false;
        }
 
index 8074e541cee007ebb8c9ef8a24d6f9c022313101..691c4b9da98840acda10c9463dfbee56035fe10b 100644 (file)
@@ -1062,13 +1062,12 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          || (((REG_P (SUBREG_REG (in))
                && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (in)))
-             && ((GET_MODE_PRECISION (inmode)
-                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
+             && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
                  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
                      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
                          <= UNITS_PER_WORD)
-                     && (GET_MODE_PRECISION (inmode)
-                         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
+                     && paradoxical_subreg_p (inmode,
+                                              GET_MODE (SUBREG_REG (in)))
                      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
                      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
                  || (WORD_REGISTER_OPERATIONS
@@ -1170,8 +1169,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          || (((REG_P (SUBREG_REG (out))
                && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (out)))
-             && ((GET_MODE_PRECISION (outmode)
-                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
+             && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
                  || (WORD_REGISTER_OPERATIONS
                      && (GET_MODE_PRECISION (outmode)
                          < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
@@ -1299,7 +1297,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   if (this_insn_is_asm)
     {
       machine_mode mode;
-      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
+      if (paradoxical_subreg_p (inmode, outmode))
        mode = inmode;
       else
        mode = outmode;
@@ -3137,15 +3135,15 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
                          && (WORD_REGISTER_OPERATIONS
                              || ((GET_MODE_BITSIZE (GET_MODE (operand))
                                   < BIGGEST_ALIGNMENT)
-                                && (GET_MODE_SIZE (operand_mode[i])
-                                    > GET_MODE_SIZE (GET_MODE (operand))))
+                                 && paradoxical_subreg_p (operand_mode[i],
+                                                          GET_MODE (operand)))
                              || BYTES_BIG_ENDIAN
                              || ((GET_MODE_SIZE (operand_mode[i])
                                   <= UNITS_PER_WORD)
                                  && (GET_MODE_SIZE (GET_MODE (operand))
                                      <= UNITS_PER_WORD)
-                                 && (GET_MODE_SIZE (operand_mode[i])
-                                     > GET_MODE_SIZE (GET_MODE (operand)))
+                                 && paradoxical_subreg_p (operand_mode[i],
+                                                          GET_MODE (operand))
                                  && INTEGRAL_MODE_P (GET_MODE (operand))
                                  && LOAD_EXTEND_OP (GET_MODE (operand))
                                     != UNKNOWN)))
index e993749a0000cf66bae14c9d8f6eec6e44555988..6666344a39b1e777f97fae4f4f0d45d8e29742ee 100644 (file)
@@ -3042,8 +3042,7 @@ elimination_effects (rtx x, machine_mode mem_mode)
 
     case SUBREG:
       if (REG_P (SUBREG_REG (x))
-         && (GET_MODE_SIZE (GET_MODE (x))
-             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && !paradoxical_subreg_p (x)
          && reg_equivs
          && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
        return;
@@ -6373,8 +6372,7 @@ compute_reload_subreg_offset (machine_mode outermode,
   /* If SUBREG is paradoxical then return the normal lowpart offset
      for OUTERMODE and INNERMODE.  Our caller has already checked
      that OUTERMODE fits in INNERMODE.  */
-  if (outer_offset == 0
-      && GET_MODE_SIZE (outermode) > GET_MODE_SIZE (middlemode))
+  if (paradoxical_subreg_p (outermode, middlemode))
     return subreg_lowpart_offset (outermode, innermode);
 
   /* SUBREG is normal, but may not be lowpart; return OUTER_OFFSET
@@ -6664,8 +6662,7 @@ choose_reload_regs (struct insn_chain *chain)
                                  && rld[r].out)
                              /* Don't really use the inherited spill reg
                                 if we need it wider than we've got it.  */
-                             || (GET_MODE_SIZE (rld[r].mode)
-                                 > GET_MODE_SIZE (mode))
+                             || paradoxical_subreg_p (rld[r].mode, mode)
                              || bad_for_class
 
                              /* If find_reloads chose reload_out as reload
index 8a68bb152bc980a2d1604141e412459b8e8bc437..a2c339e7e2d5471a10910c77acaceeb3dc966aaf 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2784,10 +2784,28 @@ extern rtx operand_subword (rtx, unsigned int, int, machine_mode);
 
 /* In emit-rtl.c */
 extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
-extern bool paradoxical_subreg_p (const_rtx);
 extern int subreg_lowpart_p (const_rtx);
 extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
 
+/* Return true if a subreg with the given outer and inner modes is
+   paradoxical.  */
+
+inline bool
+paradoxical_subreg_p (machine_mode outermode, machine_mode innermode)
+{
+  return GET_MODE_PRECISION (outermode) > GET_MODE_PRECISION (innermode);
+}
+
+/* Return true if X is a paradoxical subreg, false otherwise.  */
+
+inline bool
+paradoxical_subreg_p (const_rtx x)
+{
+  if (GET_CODE (x) != SUBREG)
+    return false;
+  return paradoxical_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
+}
+
 /* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value.  */
 
 inline unsigned int
index 9bfae8cb9b03d70469cc3b151563284840b3c6d7..0d93b6f416ffe8fbe1f25e503879c9874c72ba61 100644 (file)
@@ -3530,7 +3530,7 @@ subreg_lsb_1 (machine_mode outer_mode,
   unsigned int word;
 
   /* A paradoxical subreg begins at bit position 0.  */
-  if (GET_MODE_PRECISION (outer_mode) > GET_MODE_PRECISION (inner_mode))
+  if (paradoxical_subreg_p (outer_mode, inner_mode))
     return 0;
 
   if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
index ef414797af57ed32e51f22922652954116b88f9f..0133d43bbff4322b5da1d60443c9d723170f86be 100644 (file)
@@ -1465,7 +1465,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
       if (GET_CODE (op) == SUBREG
          && SUBREG_PROMOTED_VAR_P (op)
          && SUBREG_PROMOTED_SIGNED_P (op)
-         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+         && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
        {
          temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
          if (temp)
@@ -1547,7 +1547,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
       if (GET_CODE (op) == SUBREG
          && SUBREG_PROMOTED_VAR_P (op)
          && SUBREG_PROMOTED_UNSIGNED_P (op)
-         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+         && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
        {
          temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
          if (temp)
@@ -6080,7 +6080,7 @@ simplify_subreg (machine_mode outermode, rtx op,
        }
 
       /* See whether resulting subreg will be paradoxical.  */
-      if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
+      if (!paradoxical_subreg_p (outermode, innermostmode))
        {
          /* In nonparadoxical subregs we can't handle negative offsets.  */
          if (final_offset < 0)
index 5c38c1dbd83b43aa0700a59c31c3e854afd57e8e..ef2c6aa4c910b5964d3b6075ea8640bb6d17498f 100644 (file)
@@ -5295,7 +5295,7 @@ track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
       machine_mode pseudo_mode;
 
       pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
-      if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
+      if (paradoxical_subreg_p (mode, pseudo_mode))
        {
          offset += byte_lowpart_offset (pseudo_mode, mode);
          mode = pseudo_mode;
@@ -5309,7 +5309,7 @@ track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
      because the real and imaginary parts are represented as separate
      pseudo registers, even if the whole complex value fits into one
      hard register.  */
-  if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
+  if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
        || (store_reg_p
           && !COMPLEX_MODE_P (DECL_MODE (expr))
           && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))