OSDN Git Service

2014-04-04 Richard Biener <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / simplify-rtx.c
index 1301616..a0c4395 100644 (file)
@@ -1,7 +1,7 @@
 /* RTL simplification functions for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011  Free Software Foundation, Inc.
+   2011, 2012  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -244,7 +244,8 @@ avoid_constant_pool_reference (rtx x)
       /* If we're accessing the constant in a different mode than it was
          originally stored, attempt to fix that up via subreg simplifications.
          If that fails we have no choice but to return the original memory.  */
-      if (offset != 0 || cmode != GET_MODE (x))
+      if ((offset != 0 || cmode != GET_MODE (x))
+         && offset >= 0 && offset < GET_MODE_SIZE (cmode))
         {
           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
           if (tem && CONSTANT_P (tem))
@@ -2239,7 +2240,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
                                    neg_const_int (mode, op1));
 
       /* (x - (x & y)) -> (x & ~y) */
-      if (GET_CODE (op1) == AND)
+      if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
        {
          if (rtx_equal_p (op0, XEXP (op1, 0)))
            {
@@ -2557,6 +2558,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
           HOST_WIDE_INT mask = INTVAL (trueop1) << count;
 
           if (mask >> count == INTVAL (trueop1)
+             && trunc_int_for_mode (mask, mode) == mask
               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
            return simplify_gen_binary (ASHIFTRT, mode,
                                        plus_constant (XEXP (op0, 0), mask),
@@ -2953,7 +2955,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
                }
            }
        }
-      else
+      else if (SCALAR_INT_MODE_P (mode))
        {
          /* 0/x is 0 (or x&0 if x has side-effects).  */
          if (trueop0 == CONST0_RTX (mode)
@@ -3947,7 +3949,7 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
              /* ~a -> (-a - 1) */
              if (n_ops != 7)
                {
-                 ops[n_ops].op = constm1_rtx;
+                 ops[n_ops].op = CONSTM1_RTX (mode);
                  ops[n_ops++].neg = this_neg;
                  ops[i].op = XEXP (this_op, 0);
                  ops[i].neg = !this_neg;
@@ -4352,10 +4354,20 @@ simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
     {
       rtx x = XEXP (op0, 0);
       rtx c = XEXP (op0, 1);
+      enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
+      rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
+
+      /* Detect an infinite recursive condition, where we oscillate at this
+        simplification case between:
+           A + B == C  <--->  C - B == A,
+        where A, B, and C are all constants with non-simplifiable expressions,
+        usually SYMBOL_REFs.  */
+      if (GET_CODE (tem) == invcode
+         && CONSTANT_P (x)
+         && rtx_equal_p (c, XEXP (tem, 1)))
+       return NULL_RTX;
 
-      c = simplify_gen_binary (op0code == PLUS ? MINUS : PLUS,
-                              cmp_mode, op1, c);
-      return simplify_gen_relational (code, mode, cmp_mode, x, c);
+      return simplify_gen_relational (code, mode, cmp_mode, x, tem);
     }
 
   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is