OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Feb 2008 20:02:09 +0000 (20:02 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Feb 2008 20:02:09 +0000 (20:02 +0000)
* simplify-rtx.c (simplify_unary_operation_1): Extend the handling
of SUBREG_PROMOTED_VAR_P to cope with cases where the extended value
is smaller than the original promoted value.
(simplify_subreg): If OP is a SUBREG, try to preserve its
SUBREG_PROMOTED_VAR_P information.

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

gcc/ChangeLog
gcc/simplify-rtx.c

index 8fd03ae..9b7c0cc 100644 (file)
@@ -1,3 +1,11 @@
+2008-02-28  Richard Sandiford  <rsandifo@nildram.co.uk>
+
+       * simplify-rtx.c (simplify_unary_operation_1): Extend the handling
+       of SUBREG_PROMOTED_VAR_P to cope with cases where the extended value
+       is smaller than the original promoted value.
+       (simplify_subreg): If OP is a SUBREG, try to preserve its
+       SUBREG_PROMOTED_VAR_P information.
+
 2008-02-28  Steven Bosscher  <stevenb.gcc@gmail.com>
 
        * tree-ssa-sccvn (vn_ssa_aux_obstack): New obstack.
index 03fbc75..34392dc 100644 (file)
@@ -859,8 +859,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
       if (GET_CODE (op) == SUBREG
          && SUBREG_PROMOTED_VAR_P (op)
          && ! SUBREG_PROMOTED_UNSIGNED_P (op)
-         && GET_MODE (XEXP (op, 0)) == mode)
-       return XEXP (op, 0);
+         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+       return rtl_hooks.gen_lowpart_no_emit (mode, op);
 
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       if (! POINTERS_EXTEND_UNSIGNED
@@ -881,8 +881,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
       if (GET_CODE (op) == SUBREG
          && SUBREG_PROMOTED_VAR_P (op)
          && SUBREG_PROMOTED_UNSIGNED_P (op) > 0
-         && GET_MODE (XEXP (op, 0)) == mode)
-       return XEXP (op, 0);
+         && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+       return rtl_hooks.gen_lowpart_no_emit (mode, op);
 
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       if (POINTERS_EXTEND_UNSIGNED > 0
@@ -5021,7 +5021,22 @@ simplify_subreg (enum machine_mode outermode, rtx op,
        return newx;
       if (validate_subreg (outermode, innermostmode,
                           SUBREG_REG (op), final_offset))
-        return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+       {
+         newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+         if (SUBREG_PROMOTED_VAR_P (op)
+             && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0
+             && GET_MODE_CLASS (outermode) == MODE_INT
+             && IN_RANGE (GET_MODE_SIZE (outermode),
+                          GET_MODE_SIZE (innermode),
+                          GET_MODE_SIZE (innermostmode))
+             && subreg_lowpart_p (newx))
+           {
+             SUBREG_PROMOTED_VAR_P (newx) = 1;
+             SUBREG_PROMOTED_UNSIGNED_SET
+               (newx, SUBREG_PROMOTED_UNSIGNED_P (op));
+           }
+         return newx;
+       }
       return NULL_RTX;
     }