Tighten condition for converting SUBREG reloads from OP_OUT to OP_INOUT
authorMatthew Fortune <matthew.fortune@imgtec.com>
Mon, 20 Feb 2017 12:07:06 +0000 (12:07 +0000)
committerMatthew Fortune <mpf@gcc.gnu.org>
Mon, 20 Feb 2017 12:07:06 +0000 (12:07 +0000)
gcc/
PR target/78660
* lra-constraints.c (curr_insn_transform): Tighten condition
for converting SUBREG reloads from OP_OUT to OP_INOUT.

From-SVN: r245599

gcc/ChangeLog
gcc/lra-constraints.c

index 9dc6b58a0adf49a95df5055711abb75e9a112ca8..1823049df778374707fb3fee2e580a096b7e21e8 100644 (file)
@@ -1,3 +1,9 @@
+2017-02-20  Matthew Fortune  <matthew.fortune@imgtec.com>
+
+       PR target/78660
+       * lra-constraints.c (curr_insn_transform): Tighten condition
+       for converting SUBREG reloads from OP_OUT to OP_INOUT.
+
 2017-02-20  Matthew Fortune  <matthew.fortune@imgtec.com>
 
        PR target/78660
index 62947e36c97f079be384e21d7f5258a0a3cf778a..18b309658bde2ea13ee7f437b65409832be40d97 100644 (file)
@@ -4140,7 +4140,17 @@ curr_insn_transform (bool check_only_p)
                          < GET_MODE_PRECISION (GET_MODE (reg))
                          && WORD_REGISTER_OPERATIONS)))
                {
-                 if (type == OP_OUT)
+                 /* An OP_INOUT is required when reloading a subreg of a
+                    mode wider than a word to ensure that data beyond the
+                    word being reloaded is preserved.  Also automatically
+                    ensure that strict_low_part reloads are made into
+                    OP_INOUT which should already be true from the backend
+                    constraints.  */
+                 if (type == OP_OUT
+                     && (curr_static_id->operand[i].strict_low
+                         || (GET_MODE_SIZE (GET_MODE (reg)) > UNITS_PER_WORD
+                             && (GET_MODE_SIZE (mode)
+                                 < GET_MODE_SIZE (GET_MODE (reg))))))
                    type = OP_INOUT;
                  loc = &SUBREG_REG (*loc);
                  mode = GET_MODE (*loc);