]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/57439 (FAIL: gcc.c-torture/execute/920501-6.c execution, ...
authorJoern Rennecke <joern.rennecke@embecosm.com>
Thu, 30 May 2013 11:07:05 +0000 (11:07 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Thu, 30 May 2013 11:07:05 +0000 (12:07 +0100)
        PR rtl-optimization/57439
        * postreload.c (move2add_valid_value_p): Check that we have
        a zero subreg_regno_offset when accessing the register in
        the requested mode.

From-SVN: r199449

gcc/ChangeLog
gcc/postreload.c

index 8b27ecc44c7bd9bd7b46e921444d1dec575d50ac..f08cd613cfc9b9ffa8263f8beb5c9a14b845c77f 100644 (file)
@@ -1,3 +1,10 @@
+2013-05-30  Joern Rennecke <joern.rennecke@embecosm.com>
+
+       PR rtl-optimization/57439
+       * postreload.c (move2add_valid_value_p): Check that we have
+       a zero subreg_regno_offset when accessing the register in
+       the requested mode.
+
 2013-05-30  Yuri Rumyantsev  <yuri.s.rumyantsev@intel.com>
            Igor Zamyatin  <igor.zamyatin@intel.com>
 
index 558ab8b867ea21715c6834f44d9c028c7e40f785..f340503f69c23765d2c8d0b23e5fb4f82726f67a 100644 (file)
@@ -1726,10 +1726,27 @@ move2add_record_sym_value (rtx reg, rtx sym, rtx off)
 static bool
 move2add_valid_value_p (int regno, enum machine_mode mode)
 {
-  if (reg_set_luid[regno] <= move2add_last_label_luid
-      || !MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno]))
+  if (reg_set_luid[regno] <= move2add_last_label_luid)
     return false;
 
+  if (mode != reg_mode[regno])
+    {
+      if (!MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno]))
+       return false;
+      /* The value loaded into regno in reg_mode[regno] is also valid in
+        mode after truncation only if (REG:mode regno) is the lowpart of
+        (REG:reg_mode[regno] regno).  Now, for big endian, the starting
+        regno of the lowpart might be different.  */
+      int s_off = subreg_lowpart_offset (mode, reg_mode[regno]);
+      s_off = subreg_regno_offset (regno, reg_mode[regno], s_off, mode);
+      if (s_off != 0)
+       /* We could in principle adjust regno, check reg_mode[regno] to be
+          BLKmode, and return s_off to the caller (vs. -1 for failure),
+          but we currently have no callers that could make use of this
+          information.  */
+       return false;
+    }
+
   for (int i = hard_regno_nregs[regno][mode] - 1; i > 0; i--)
     if (reg_mode[regno + i] != BLKmode)
       return false;