tree.c (element_mode, [...]): New functions.
authorMarc Glisse <marc.glisse@inria.fr>
Tue, 18 Nov 2014 10:26:31 +0000 (11:26 +0100)
committerMarc Glisse <glisse@gcc.gnu.org>
Tue, 18 Nov 2014 10:26:31 +0000 (10:26 +0000)
2014-11-18  Marc Glisse  <marc.glisse@inria.fr>

* tree.c (element_mode, integer_truep): New functions.
* tree.h (element_mode, integer_truep): Declare them.
* fold-const.c (negate_expr_p, fold_negate_expr, combine_comparisons,
fold_cond_expr_with_comparison, fold_real_zero_addition_p,
fold_comparison, fold_ternary_loc, tree_call_nonnegative_warnv_p,
fold_strip_sign_ops): Use element_mode.
(fold_binary_loc): Use element_mode and element_precision.
* match.pd: Use integer_truep, element_mode, element_precision,
VECTOR_TYPE_P and build_one_cst. Extend some transformations to
vectors. Simplify A/-A.

From-SVN: r217702

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd
gcc/tree.c
gcc/tree.h

index 52fa23be23b4f0f5cca8e5473010b11464609b80..78ed17c69e0479914adaad8884d7c7afae893525 100644 (file)
@@ -1,3 +1,16 @@
+2014-11-18  Marc Glisse  <marc.glisse@inria.fr>
+
+       * tree.c (element_mode, integer_truep): New functions.
+       * tree.h (element_mode, integer_truep): Declare them.
+       * fold-const.c (negate_expr_p, fold_negate_expr, combine_comparisons,
+       fold_cond_expr_with_comparison, fold_real_zero_addition_p,
+       fold_comparison, fold_ternary_loc, tree_call_nonnegative_warnv_p,
+       fold_strip_sign_ops): Use element_mode.
+       (fold_binary_loc): Use element_mode and element_precision.
+       * match.pd: Use integer_truep, element_mode, element_precision,
+       VECTOR_TYPE_P and build_one_cst. Extend some transformations to
+       vectors. Simplify A/-A.
+
 2014-11-18  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm.md (unaligned_loaddi): Use std::swap instead of
index 7dbbadd859b30daa2ea910eedbad47fc7fd3ae8d..f6fb8af8084d875b108754bba37febb1342bedea 100644 (file)
@@ -442,8 +442,8 @@ negate_expr_p (tree t)
       return negate_expr_p (TREE_OPERAND (t, 0));
 
     case PLUS_EXPR:
-      if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
-         || HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
+      if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
+         || HONOR_SIGNED_ZEROS (element_mode (type)))
        return false;
       /* -(A + B) -> (-B) - A.  */
       if (negate_expr_p (TREE_OPERAND (t, 1))
@@ -455,8 +455,8 @@ negate_expr_p (tree t)
 
     case MINUS_EXPR:
       /* We can't turn -(A-B) into B-A when we honor signed zeros.  */
-      return !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
-            && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+      return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
+            && !HONOR_SIGNED_ZEROS (element_mode (type))
             && reorder_operands_p (TREE_OPERAND (t, 0),
                                    TREE_OPERAND (t, 1));
 
@@ -467,7 +467,7 @@ negate_expr_p (tree t)
       /* Fall through.  */
 
     case RDIV_EXPR:
-      if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
+      if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (TREE_TYPE (t))))
        return negate_expr_p (TREE_OPERAND (t, 1))
               || negate_expr_p (TREE_OPERAND (t, 0));
       break;
@@ -617,8 +617,8 @@ fold_negate_expr (location_t loc, tree t)
       break;
 
     case PLUS_EXPR:
-      if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
-         && !HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
+      if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
+         && !HONOR_SIGNED_ZEROS (element_mode (type)))
        {
          /* -(A + B) -> (-B) - A.  */
          if (negate_expr_p (TREE_OPERAND (t, 1))
@@ -642,8 +642,8 @@ fold_negate_expr (location_t loc, tree t)
 
     case MINUS_EXPR:
       /* - (A - B) -> B - A  */
-      if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
-         && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+      if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
+         && !HONOR_SIGNED_ZEROS (element_mode (type))
          && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
        return fold_build2_loc (loc, MINUS_EXPR, type,
                            TREE_OPERAND (t, 1), TREE_OPERAND (t, 0));
@@ -656,7 +656,7 @@ fold_negate_expr (location_t loc, tree t)
       /* Fall through.  */
 
     case RDIV_EXPR:
-      if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)))
+      if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)))
        {
          tem = TREE_OPERAND (t, 1);
          if (negate_expr_p (tem))
@@ -2315,7 +2315,7 @@ combine_comparisons (location_t loc,
                     enum tree_code rcode, tree truth_type,
                     tree ll_arg, tree lr_arg)
 {
-  bool honor_nans = HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg)));
+  bool honor_nans = HONOR_NANS (element_mode (ll_arg));
   enum comparison_code lcompcode = comparison_to_compcode (lcode);
   enum comparison_code rcompcode = comparison_to_compcode (rcode);
   int compcode;
@@ -4581,7 +4581,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
 
      Note that all these transformations are correct if A is
      NaN, since the two alternatives (A and -A) are also NaNs.  */
-  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+  if (!HONOR_SIGNED_ZEROS (element_mode (type))
       && (FLOAT_TYPE_P (TREE_TYPE (arg01))
          ? real_zerop (arg01)
          : integer_zerop (arg01))
@@ -4639,7 +4639,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
      both transformations are correct when A is NaN: A != 0
      is then true, and A == 0 is false.  */
 
-  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+  if (!HONOR_SIGNED_ZEROS (element_mode (type))
       && integer_zerop (arg01) && integer_zerop (arg2))
     {
       if (comp_code == NE_EXPR)
@@ -4674,7 +4674,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
      a number and A is not.  The conditions in the original
      expressions will be false, so all four give B.  The min()
      and max() versions would give a NaN instead.  */
-  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+  if (!HONOR_SIGNED_ZEROS (element_mode (type))
       && operand_equal_for_comparison_p (arg01, arg2, arg00)
       /* Avoid these transformations if the COND_EXPR may be used
         as an lvalue in the C++ front-end.  PR c++/19199.  */
@@ -4711,7 +4711,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
             operand which will be used if they are equal first
             so that we can convert this back to the
             corresponding COND_EXPR.  */
-         if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
+         if (!HONOR_NANS (element_mode (arg1)))
            {
              comp_op0 = fold_convert_loc (loc, comp_type, comp_op0);
              comp_op1 = fold_convert_loc (loc, comp_type, comp_op1);
@@ -4727,7 +4727,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
        case GT_EXPR:
        case UNGE_EXPR:
        case UNGT_EXPR:
-         if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
+         if (!HONOR_NANS (element_mode (arg1)))
            {
              comp_op0 = fold_convert_loc (loc, comp_type, comp_op0);
              comp_op1 = fold_convert_loc (loc, comp_type, comp_op1);
@@ -4740,12 +4740,12 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
            }
          break;
        case UNEQ_EXPR:
-         if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
+         if (!HONOR_NANS (element_mode (arg1)))
            return pedantic_non_lvalue_loc (loc,
                                        fold_convert_loc (loc, type, arg2));
          break;
        case LTGT_EXPR:
-         if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
+         if (!HONOR_NANS (element_mode (arg1)))
            return pedantic_non_lvalue_loc (loc,
                                        fold_convert_loc (loc, type, arg1));
          break;
@@ -6090,11 +6090,11 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
     return false;
 
   /* Don't allow the fold with -fsignaling-nans.  */
-  if (HONOR_SNANS (TYPE_MODE (type)))
+  if (HONOR_SNANS (element_mode (type)))
     return false;
 
   /* Allow the fold if zeros aren't signed, or their sign isn't important.  */
-  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
+  if (!HONOR_SIGNED_ZEROS (element_mode (type)))
     return true;
 
   /* In a vector or complex, we would need to check the sign of all zeros.  */
@@ -6109,7 +6109,7 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
      In this situation, there is only one case we can return true for.
      X - 0 is the same as X unless rounding towards -infinity is
      supported.  */
-  return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type));
+  return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type));
 }
 
 /* Subroutine of fold() that checks comparisons of built-in math
@@ -9080,14 +9080,14 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
        {
        case EQ_EXPR:
          if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
-             || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
+             || ! HONOR_NANS (element_mode (arg0)))
            return constant_boolean_node (1, type);
          break;
 
        case GE_EXPR:
        case LE_EXPR:
          if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
-             || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
+             || ! HONOR_NANS (element_mode (arg0)))
            return constant_boolean_node (1, type);
          return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg1);
 
@@ -9095,7 +9095,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
          /* For NE, we can only do this simplification if integer
             or we don't honor IEEE floating point NaNs.  */
          if (FLOAT_TYPE_P (TREE_TYPE (arg0))
-             && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
+             && HONOR_NANS (element_mode (arg0)))
            break;
          /* ... fall through ...  */
        case GT_EXPR:
@@ -9968,8 +9968,8 @@ fold_binary_loc (location_t loc,
          /* Fold __complex__ ( x, 0 ) + __complex__ ( 0, y )
             to __complex__ ( x, y ).  This is not the same for SNaNs or
             if signed zeros are involved.  */
-         if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
-              && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
+         if (!HONOR_SNANS (element_mode (arg0))
+              && !HONOR_SIGNED_ZEROS (element_mode (arg0))
              && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
            {
              tree rtype = TREE_TYPE (TREE_TYPE (arg0));
@@ -10405,8 +10405,8 @@ fold_binary_loc (location_t loc,
       /* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to
         __complex__ ( x, -y ).  This is not the same for SNaNs or if
         signed zeros are involved.  */
-      if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
-         && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
+      if (!HONOR_SNANS (element_mode (arg0))
+         && !HONOR_SIGNED_ZEROS (element_mode (arg0))
          && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
         {
          tree rtype = TREE_TYPE (TREE_TYPE (arg0));
@@ -10609,8 +10609,8 @@ fold_binary_loc (location_t loc,
          /* Fold z * +-I to __complex__ (-+__imag z, +-__real z).
             This is not the same for NaNs or if signed zeros are
             involved.  */
-         if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
-              && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
+         if (!HONOR_NANS (element_mode (arg0))
+              && !HONOR_SIGNED_ZEROS (element_mode (arg0))
              && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))
              && TREE_CODE (arg1) == COMPLEX_CST
              && real_zerop (TREE_REALPART (arg1)))
@@ -10657,7 +10657,7 @@ fold_binary_loc (location_t loc,
                  /* Optimize sqrt(x)*sqrt(x) as x.  */
                  if (BUILTIN_SQRT_P (fcode0)
                      && operand_equal_p (arg00, arg10, 0)
-                     && ! HONOR_SNANS (TYPE_MODE (type)))
+                     && ! HONOR_SNANS (element_mode (type)))
                    return arg00;
 
                  /* Optimize root(x)*root(y) as root(x*y).  */
@@ -11305,7 +11305,7 @@ fold_binary_loc (location_t loc,
       if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
          && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
        {
-         prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
+         prec = element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0)));
 
          wide_int mask = wide_int::from (arg1, prec, UNSIGNED);
          if (mask == -1)
@@ -11541,8 +11541,8 @@ fold_binary_loc (location_t loc,
              tree arg00 = CALL_EXPR_ARG (arg0, 0);
              tree arg01 = CALL_EXPR_ARG (arg1, 0);
 
-             if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00)))
-                 && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00)))
+             if (! HONOR_NANS (element_mode (arg00))
+                 && ! HONOR_INFINITIES (element_mode (arg00))
                  && operand_equal_p (arg00, arg01, 0))
                {
                  tree cosfn = mathfn_built_in (type, BUILT_IN_COS);
@@ -11561,8 +11561,8 @@ fold_binary_loc (location_t loc,
              tree arg00 = CALL_EXPR_ARG (arg0, 0);
              tree arg01 = CALL_EXPR_ARG (arg1, 0);
 
-             if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00)))
-                 && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00)))
+             if (! HONOR_NANS (element_mode (arg00))
+                 && ! HONOR_INFINITIES (element_mode (arg00))
                  && operand_equal_p (arg00, arg01, 0))
                {
                  tree cosfn = mathfn_built_in (type, BUILT_IN_COS);
@@ -12935,7 +12935,7 @@ fold_binary_loc (location_t loc,
       strict_overflow_p = false;
       if (code == GE_EXPR
          && (integer_zerop (arg1)
-             || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
+             || (! HONOR_NANS (element_mode (arg0))
                  && real_zerop (arg1)))
          && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p))
        {
@@ -12987,11 +12987,11 @@ fold_binary_loc (location_t loc,
          && TYPE_UNSIGNED (TREE_TYPE (arg0))
          && CONVERT_EXPR_P (arg1)
          && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
-         && (TYPE_PRECISION (TREE_TYPE (arg1))
-             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0))))
+         && (element_precision (TREE_TYPE (arg1))
+             >= element_precision (TREE_TYPE (TREE_OPERAND (arg1, 0))))
          && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0)))
-             || (TYPE_PRECISION (TREE_TYPE (arg1))
-                 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))))
+             || (element_precision (TREE_TYPE (arg1))
+                 == element_precision (TREE_TYPE (TREE_OPERAND (arg1, 0)))))
          && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
        {
          tem = build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
@@ -13322,7 +13322,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
       if (COMPARISON_CLASS_P (arg0)
          && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
                                             arg1, TREE_OPERAND (arg0, 1))
-         && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
+         && !HONOR_SIGNED_ZEROS (element_mode (arg1)))
        {
          tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
          if (tem)
@@ -13333,7 +13333,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
          && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
                                             op2,
                                             TREE_OPERAND (arg0, 1))
-         && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
+         && !HONOR_SIGNED_ZEROS (element_mode (op2)))
        {
          location_t loc0 = expr_location_or (arg0, loc);
          tem = fold_invert_truthvalue (loc0, arg0);
@@ -14834,7 +14834,7 @@ tree_call_nonnegative_warnv_p (tree type, tree fndecl,
 
        CASE_FLT_FN (BUILT_IN_SQRT):
        /* sqrt(-0.0) is -0.0.  */
-       if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
+       if (!HONOR_SIGNED_ZEROS (element_mode (type)))
          return true;
        return tree_expr_nonnegative_warnv_p (arg0,
                                              strict_overflow_p);
@@ -16100,7 +16100,7 @@ fold_strip_sign_ops (tree exp)
 
     case MULT_EXPR:
     case RDIV_EXPR:
-      if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (exp))))
+      if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (exp)))
        return NULL_TREE;
       arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
       arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 1));
index da6599c750d29e047b7a8586b14c8438c4440014..1f204716d1cda47115eb566bef40ba331fd7633f 100644 (file)
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 /* Generic tree predicates we inherit.  */
 (define_predicates
    integer_onep integer_zerop integer_all_onesp integer_minus_onep
-   integer_each_onep
+   integer_each_onep integer_truep
    real_zerop real_onep real_minus_onep
    CONSTANT_CLASS_P
    tree_expr_nonnegative_p)
@@ -73,7 +73,7 @@ along with GCC; see the file COPYING3.  If not see
    is volatile.  */
 (simplify
  (minus @0 @0)
- (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (TYPE_MODE (type)))
+ (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (element_mode (type)))
   { build_zero_cst (type); }))
 
 (simplify
@@ -86,24 +86,24 @@ along with GCC; see the file COPYING3.  If not see
    negative value by 0 gives -0, not +0.  */
 (simplify
  (mult @0 real_zerop@1)
- (if (!HONOR_NANS (TYPE_MODE (type))
-      && !HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
+ (if (!HONOR_NANS (element_mode (type))
+      && !HONOR_SIGNED_ZEROS (element_mode (type)))
   @1))
 
 /* In IEEE floating point, x*1 is not equivalent to x for snans.
    Likewise for complex arithmetic with signed zeros.  */
 (simplify
  (mult @0 real_onep)
- (if (!HONOR_SNANS (TYPE_MODE (type))
-      && (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+ (if (!HONOR_SNANS (element_mode (type))
+      && (!HONOR_SIGNED_ZEROS (element_mode (type))
           || !COMPLEX_FLOAT_TYPE_P (type)))
   (non_lvalue @0)))
 
 /* Transform x * -1.0 into -x.  */
 (simplify
  (mult @0 real_minus_onep)
-  (if (!HONOR_SNANS (TYPE_MODE (type))
-       && (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+  (if (!HONOR_SNANS (element_mode (type))
+       && (!HONOR_SIGNED_ZEROS (element_mode (type))
            || !COMPLEX_FLOAT_TYPE_P (type)))
    (negate @0)))
 
@@ -117,44 +117,46 @@ along with GCC; see the file COPYING3.  If not see
 /* X / -1 is -X.  */
 (for div (trunc_div ceil_div floor_div round_div exact_div)
  (simplify
-   (div @0 INTEGER_CST@1)
-   (if (!TYPE_UNSIGNED (type)
-        && wi::eq_p (@1, -1))
+   (div @0 integer_minus_onep@1)
+   (if (!TYPE_UNSIGNED (type))
     (negate @0))))
 
 /* For unsigned integral types, FLOOR_DIV_EXPR is the same as
    TRUNC_DIV_EXPR.  Rewrite into the latter in this case.  */
 (simplify
  (floor_div @0 @1)
- (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
+ (if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
+      && TYPE_UNSIGNED (type))
   (trunc_div @0 @1)))
 
 /* Optimize A / A to 1.0 if we don't care about
-   NaNs or Infinities.  Skip the transformation
-   for non-real operands.  */
+   NaNs or Infinities.  */
 (simplify
  (rdiv @0 @0)
- (if (SCALAR_FLOAT_TYPE_P (type)
-      && ! HONOR_NANS (TYPE_MODE (type))
-      && ! HONOR_INFINITIES (TYPE_MODE (type)))
-  { build_real (type, dconst1); })
- /* The complex version of the above A / A optimization.  */
- (if (COMPLEX_FLOAT_TYPE_P (type)
-      && ! HONOR_NANS (TYPE_MODE (TREE_TYPE (type)))
-      && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
-  { build_complex (type, build_real (TREE_TYPE (type), dconst1),
-                  build_real (TREE_TYPE (type), dconst0)); }))
+ (if (FLOAT_TYPE_P (type)
+      && ! HONOR_NANS (element_mode (type))
+      && ! HONOR_INFINITIES (element_mode (type)))
+  { build_one_cst (type); }))
+
+/* Optimize -A / A to -1.0 if we don't care about
+   NaNs or Infinities.  */
+(simplify
+ (rdiv:c @0 (negate @0))
+ (if (FLOAT_TYPE_P (type)
+      && ! HONOR_NANS (element_mode (type))
+      && ! HONOR_INFINITIES (element_mode (type)))
+  { build_minus_one_cst (type); }))
 
 /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
 (simplify
  (rdiv @0 real_onep)
- (if (!HONOR_SNANS (TYPE_MODE (type)))
+ (if (!HONOR_SNANS (element_mode (type)))
   (non_lvalue @0)))
 
 /* In IEEE floating point, x/-1 is not equivalent to -x for snans.  */
 (simplify
  (rdiv @0 real_minus_onep)
- (if (!HONOR_SNANS (TYPE_MODE (type)))
+ (if (!HONOR_SNANS (element_mode (type)))
   (negate @0)))
 
 /* If ARG1 is a constant, we can convert this to a multiply by the
@@ -192,9 +194,8 @@ along with GCC; see the file COPYING3.  If not see
   { build_zero_cst (type); })
  /* X % -1 is zero.  */
  (simplify
-  (mod @0 INTEGER_CST@1)
-  (if (!TYPE_UNSIGNED (type)
-       && wi::eq_p (@1, -1))
+  (mod @0 integer_minus_onep@1)
+  (if (!TYPE_UNSIGNED (type))
    { build_zero_cst (type); })))
 
 /* X % -C is the same as X % C.  */
@@ -309,14 +310,11 @@ along with GCC; see the file COPYING3.  If not see
 (match (logical_inverted_value @0)
  (bit_not truth_valued_p@0))
 (match (logical_inverted_value @0)
- (eq @0 integer_zerop)
- (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))))
+ (eq @0 integer_zerop))
 (match (logical_inverted_value @0)
- (ne truth_valued_p@0 integer_onep)
- (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))))
+ (ne truth_valued_p@0 integer_truep))
 (match (logical_inverted_value @0)
- (bit_xor truth_valued_p@0 integer_onep)
- (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))))
+ (bit_xor truth_valued_p@0 integer_truep))
 
 /* X & !X -> 0.  */
 (simplify
@@ -493,7 +491,7 @@ along with GCC; see the file COPYING3.  If not see
    (simplify
     (minus (convert (add @0 @1))
      (convert @0))
-    (if (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@1))
+    (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For integer types, if A has a smaller type
            than T the result depends on the possible
            overflow in P + A.
@@ -626,19 +624,19 @@ along with GCC; see the file COPYING3.  If not see
       int inside_int = INTEGRAL_TYPE_P (inside_type);
       int inside_ptr = POINTER_TYPE_P (inside_type);
       int inside_float = FLOAT_TYPE_P (inside_type);
-      int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
+      int inside_vec = VECTOR_TYPE_P (inside_type);
       unsigned int inside_prec = TYPE_PRECISION (inside_type);
       int inside_unsignedp = TYPE_UNSIGNED (inside_type);
       int inter_int = INTEGRAL_TYPE_P (inter_type);
       int inter_ptr = POINTER_TYPE_P (inter_type);
       int inter_float = FLOAT_TYPE_P (inter_type);
-      int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
+      int inter_vec = VECTOR_TYPE_P (inter_type);
       unsigned int inter_prec = TYPE_PRECISION (inter_type);
       int inter_unsignedp = TYPE_UNSIGNED (inter_type);
       int final_int = INTEGRAL_TYPE_P (type);
       int final_ptr = POINTER_TYPE_P (type);
       int final_float = FLOAT_TYPE_P (type);
-      int final_vec = TREE_CODE (type) == VECTOR_TYPE;
+      int final_vec = VECTOR_TYPE_P (type);
       unsigned int final_prec = TYPE_PRECISION (type);
       int final_unsignedp = TYPE_UNSIGNED (type);
     }
@@ -666,8 +664,8 @@ along with GCC; see the file COPYING3.  If not see
        && inter_prec >= inside_prec
        && (inter_float || inter_vec
            || inter_unsignedp == inside_unsignedp)
-       && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
-             && TYPE_MODE (type) == TYPE_MODE (inter_type))
+       && ! (final_prec != GET_MODE_PRECISION (element_mode (type))
+             && element_mode (type) == element_mode (inter_type))
        && ! final_ptr
        && (! final_vec || inter_prec == inside_prec))
     (ocvt @0))
@@ -845,12 +843,12 @@ along with GCC; see the file COPYING3.  If not see
  /* A ? B : B -> B.  */
  (simplify
   (cnd @0 @1 @1)
-  @1))
+  @1)
 
-/* !A ? B : C -> A ? C : B.  */
-(simplify
(cond (logical_inverted_value truth_valued_p@0) @1 @2)
(cond @0 @2 @1))
+ /* !A ? B : C -> A ? C : B.  */
+ (simplify
 (cnd (logical_inverted_value truth_valued_p@0) @1 @2)
 (cnd @0 @2 @1)))
 
 
 /* Simplifications of comparisons.  */
@@ -876,17 +874,16 @@ along with GCC; see the file COPYING3.  If not see
       a computed operator in the replacement tree thus we have
       to play the trick below.  */
    (with { enum tree_code ic = invert_tree_comparison
-             (cmp, HONOR_NANS (TYPE_MODE (TREE_TYPE (@0)))); }
+             (cmp, HONOR_NANS (element_mode (@0))); }
     (if (ic == icmp)
      (icmp @0 @1))
     (if (ic == ncmp)
      (ncmp @0 @1)))))
  (simplify
-  (bit_xor (cmp @0 @1) integer_onep)
-  (if (INTEGRAL_TYPE_P (type))
-   (with { enum tree_code ic = invert_tree_comparison
-             (cmp, HONOR_NANS (TYPE_MODE (TREE_TYPE (@0)))); }
-    (if (ic == icmp)
-     (icmp @0 @1))
-    (if (ic == ncmp)
-     (ncmp @0 @1))))))
+  (bit_xor (cmp @0 @1) integer_truep)
+  (with { enum tree_code ic = invert_tree_comparison
+            (cmp, HONOR_NANS (element_mode (@0))); }
+   (if (ic == icmp)
+    (icmp @0 @1))
+   (if (ic == ncmp)
+    (ncmp @0 @1)))))
index 3d1d6370fb0fd3cba2cc0874c4f89a83f11c2cea..3f801af53441f0cd835cda2da9c85659ac78c88b 100644 (file)
@@ -2275,6 +2275,20 @@ integer_nonzerop (const_tree expr)
                  || integer_nonzerop (TREE_IMAGPART (expr)))));
 }
 
+/* Return 1 if EXPR is the integer constant one.  For vector,
+   return 1 if every piece is the integer constant minus one
+   (representing the value TRUE).  */
+
+int
+integer_truep (const_tree expr)
+{
+  STRIP_NOPS (expr);
+
+  if (TREE_CODE (expr) == VECTOR_CST)
+    return integer_all_onesp (expr);
+  return integer_onep (expr);
+}
+
 /* Return 1 if EXPR is the fixed-point constant zero.  */
 
 int
@@ -12310,4 +12324,18 @@ get_base_address (tree t)
   return t;
 }
 
+/* Return the machine mode of T.  For vectors, returns the mode of the
+   inner type.  The main use case is to feed the result to HONOR_NANS,
+   avoiding the BLKmode that a direct TYPE_MODE (T) might return.  */
+
+machine_mode
+element_mode (const_tree t)
+{
+  if (!TYPE_P (t))
+    t = TREE_TYPE (t);
+  if (VECTOR_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE)
+    t = TREE_TYPE (t);
+  return TYPE_MODE (t);
+}
+
 #include "gt-tree.h"
index 108b52dcd686d9f9d7bbcf79bd5b5a0cbbeb3fdf..ed8fecdd8e7115774720c70c36627b860e365273 100644 (file)
@@ -1564,6 +1564,8 @@ extern void protected_set_expr_location (tree, location_t);
 #define SET_TYPE_MODE(NODE, MODE) \
   (TYPE_CHECK (NODE)->type_common.mode = (MODE))
 
+extern machine_mode element_mode (const_tree t);
+
 /* The "canonical" type for this type node, which is used by frontends to
    compare the type for equality with another type.  If two types are
    equal (based on the semantics of the language), then they will have
@@ -3999,6 +4001,11 @@ extern int integer_pow2p (const_tree);
 
 extern int integer_nonzerop (const_tree);
 
+/* integer_truep (tree x) is nonzero if X is an integer constant of value 1 or
+   a vector where each element is an integer constant of value -1.  */
+
+extern int integer_truep (const_tree);
+
 extern bool cst_and_fits_in_hwi (const_tree);
 extern tree num_ending_zeros (const_tree);