OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Aug 2009 08:32:24 +0000 (08:32 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Aug 2009 08:32:24 +0000 (08:32 +0000)
* combine.c (gen_lowpart_or_truncate): Exclude CONST_INTs from
mode check.  Do truncations in an integer mode.
(force_to_mode): Handle subregs for all mode types.  Only do
arithmetic simplifications on integer modes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150578 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c

index 3a43fe3..f2e11bc 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-08  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * combine.c (gen_lowpart_or_truncate): Exclude CONST_INTs from
+       mode check.  Do truncations in an integer mode.
+       (force_to_mode): Handle subregs for all mode types.  Only do
+       arithmetic simplifications on integer modes.
+
 2009-08-07  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/40999
index 6a0e6ec..3a2c412 100644 (file)
@@ -7243,13 +7243,20 @@ canon_reg_for_combine (rtx x, rtx reg)
 static rtx
 gen_lowpart_or_truncate (enum machine_mode mode, rtx x)
 {
-  if (GET_MODE_SIZE (GET_MODE (x)) <= GET_MODE_SIZE (mode)
-      || TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
-                               GET_MODE_BITSIZE (GET_MODE (x)))
-      || (REG_P (x) && reg_truncated_to_mode (mode, x)))
-    return gen_lowpart (mode, x);
-  else
-    return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x));
+  if (!CONST_INT_P (x)
+      && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))
+      && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+                                GET_MODE_BITSIZE (GET_MODE (x)))
+      && !(REG_P (x) && reg_truncated_to_mode (mode, x)))
+    {
+      /* Bit-cast X into an integer mode.  */
+      if (!SCALAR_INT_MODE_P (GET_MODE (x)))
+       x = gen_lowpart (int_mode_for_mode (GET_MODE (x)), x);
+      x = simplify_gen_unary (TRUNCATE, int_mode_for_mode (mode),
+                             x, GET_MODE (x));
+    }
+
+  return gen_lowpart (mode, x);
 }
 
 /* See if X can be simplified knowing that we will only refer to it in
@@ -7336,9 +7343,20 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
       && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
     return gen_lowpart (mode, x);
 
-  /* The arithmetic simplifications here do the wrong thing on vector modes.  */
-  if (VECTOR_MODE_P (mode) || VECTOR_MODE_P (GET_MODE (x)))
-      return gen_lowpart (mode, x);
+  /* We can ignore the effect of a SUBREG if it narrows the mode or
+     if the constant masks to zero all the bits the mode doesn't have.  */
+  if (GET_CODE (x) == SUBREG
+      && subreg_lowpart_p (x)
+      && ((GET_MODE_SIZE (GET_MODE (x))
+          < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         || (0 == (mask
+                   & GET_MODE_MASK (GET_MODE (x))
+                   & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
+    return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
+
+  /* The arithmetic simplifications here only work for scalar integer modes.  */
+  if (!SCALAR_INT_MODE_P (mode) || !SCALAR_INT_MODE_P (GET_MODE (x)))
+    return gen_lowpart_or_truncate (mode, x);
 
   switch (code)
     {
@@ -7356,19 +7374,6 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
        return force_to_mode (x, mode, mask, next_select);
       break;
 
-    case SUBREG:
-      if (subreg_lowpart_p (x)
-         /* We can ignore the effect of this SUBREG if it narrows the mode or
-            if the constant masks to zero all the bits the mode doesn't
-            have.  */
-         && ((GET_MODE_SIZE (GET_MODE (x))
-              < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
-             || (0 == (mask
-                       & GET_MODE_MASK (GET_MODE (x))
-                       & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
-       return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
-      break;
-
     case TRUNCATE:
       /* Similarly for a truncate.  */
       return force_to_mode (XEXP (x, 0), mode, mask, next_select);