Fix illegal register substitutions on big-endian during cprop_reg.
authorDavid S. Miller <davem@davemloft.net>
Fri, 28 Oct 2011 05:08:10 +0000 (05:08 +0000)
committerDavid S. Miller <davem@gcc.gnu.org>
Fri, 28 Oct 2011 05:08:10 +0000 (22:08 -0700)
* regcprop.c (copyprop_hardreg_forward_1): Reject the
transformation when we narrow the mode on big endian.

From-SVN: r180600

gcc/ChangeLog
gcc/regcprop.c

index 403fb604d2839825c5301e5ac0b224b8f2c4d0fb..54e059e5197735e47da6de40242330e2692691cb 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-27  David S. Miller  <davem@davemloft.net>
+
+       * regcprop.c (copyprop_hardreg_forward_1): Reject the
+       transformation when we narrow the mode on big endian.
+
 2011-10-27  Jakub Jelinek  <jakub@redhat.com>
 
        * config/i386/sse.md (avx_cvtpd2dq256_2, avx_cvttpd2dq256_2,
index ad92a64cc29873a5cfb60f7d99711a96cb952376..b0f03434b36c82db9ae679737eb803fb56512f55 100644 (file)
@@ -824,6 +824,14 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
              if (hard_regno_nregs[regno][mode]
                  > hard_regno_nregs[regno][vd->e[regno].mode])
                goto no_move_special_case;
+
+             /* And likewise, if we are narrowing on big endian the transformation
+                is also invalid.  */
+             if (hard_regno_nregs[regno][mode]
+                 < hard_regno_nregs[regno][vd->e[regno].mode]
+                 && (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD
+                     ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+               goto no_move_special_case;
            }
 
          /* If the destination is also a register, try to find a source