* fold-const.c (fold_negate_expr): Add ANY_INTEGRAL_TYPE_P check.
(extract_muldiv_1): Likewise.
(maybe_canonicalize_comparison_1): Likewise.
(fold_comparison): Likewise.
(tree_binary_nonnegative_warnv_p): Likewise.
(tree_binary_nonzero_warnv_p): Likewise.
* gimple-ssa-strength-reduction.c (legal_cast_p_1): Likewise.
* tree-scalar-evolution.c (simple_iv): Likewise.
(scev_const_prop): Likewise.
* tree-ssa-loop-niter.c (expand_simple_operations): Likewise.
* tree-vect-generic.c (expand_vector_operation): Likewise.
* tree.h (ANY_INTEGRAL_TYPE_CHECK): Define.
(ANY_INTEGRAL_TYPE_P): Define.
(TYPE_OVERFLOW_WRAPS, TYPE_OVERFLOW_UNDEFINED, TYPE_OVERFLOW_TRAPS):
Add ANY_INTEGRAL_TYPE_CHECK.
(any_integral_type_check): New function.
From-SVN: r218621
+2014-12-11 Marek Polacek <polacek@redhat.com>
+
+ * fold-const.c (fold_negate_expr): Add ANY_INTEGRAL_TYPE_P check.
+ (extract_muldiv_1): Likewise.
+ (maybe_canonicalize_comparison_1): Likewise.
+ (fold_comparison): Likewise.
+ (tree_binary_nonnegative_warnv_p): Likewise.
+ (tree_binary_nonzero_warnv_p): Likewise.
+ * gimple-ssa-strength-reduction.c (legal_cast_p_1): Likewise.
+ * tree-scalar-evolution.c (simple_iv): Likewise.
+ (scev_const_prop): Likewise.
+ * tree-ssa-loop-niter.c (expand_simple_operations): Likewise.
+ * tree-vect-generic.c (expand_vector_operation): Likewise.
+ * tree.h (ANY_INTEGRAL_TYPE_CHECK): Define.
+ (ANY_INTEGRAL_TYPE_P): Define.
+ (TYPE_OVERFLOW_WRAPS, TYPE_OVERFLOW_UNDEFINED, TYPE_OVERFLOW_TRAPS):
+ Add ANY_INTEGRAL_TYPE_CHECK.
+ (any_integral_type_check): New function.
+
2014-12-11 Tobias Burnus <burnus@net-b.de>
Manuel López-Ibáñez <manu@gcc.gnu.org>
case INTEGER_CST:
tem = fold_negate_const (t, type);
if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
- || (!TYPE_OVERFLOW_TRAPS (type)
+ || (ANY_INTEGRAL_TYPE_P (type)
+ && !TYPE_OVERFLOW_TRAPS (type)
&& TYPE_OVERFLOW_WRAPS (type))
|| (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0)
return tem;
|| EXPRESSION_CLASS_P (op0))
/* ... and has wrapping overflow, and its type is smaller
than ctype, then we cannot pass through as widening. */
- && ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0))
+ && (((ANY_INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0)))
&& (TYPE_PRECISION (ctype)
> TYPE_PRECISION (TREE_TYPE (op0))))
/* ... or this is a truncation (t is narrower than op0),
/* ... or has undefined overflow while the converted to
type has not, we cannot do the operation in the inner type
as that would introduce undefined overflow. */
- || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))
+ || ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
&& !TYPE_OVERFLOW_UNDEFINED (type))))
break;
/* Match A +- CST code arg1 and CST code arg1. We can change the
first form only if overflow is undefined. */
- if (!((TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
+ if (!(((ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0)))
/* In principle pointers also have undefined overflow behavior,
but that causes problems elsewhere. */
&& !POINTER_TYPE_P (TREE_TYPE (arg0))
/* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 -+ C1. */
if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
- && (equality_code || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0)))
+ && (equality_code
+ || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))))
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
&& !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
&& TREE_CODE (arg1) == INTEGER_CST
X CMP Y +- C2 +- C1 for signed X, Y. This is valid if
the resulting offset is smaller in absolute value than the
original one and has the same sign. */
- if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
+ if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
&& (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
&& (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
&& !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
signed arithmetic case. That form is created by the compiler
often enough for folding it to be of value. One example is in
computing loop trip counts after Operator Strength Reduction. */
- if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
+ if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
&& TREE_CODE (arg0) == MULT_EXPR
&& (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
&& !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
|| (tree_expr_nonnegative_warnv_p (op0, strict_overflow_p)
&& tree_expr_nonnegative_warnv_p (op1, strict_overflow_p)))
{
- if (TYPE_OVERFLOW_UNDEFINED (type))
+ if (ANY_INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_UNDEFINED (type))
*strict_overflow_p = true;
return true;
}
{
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
- if (TYPE_OVERFLOW_UNDEFINED (type))
+ if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type))
{
/* With the presence of negative values it is hard
to say something. */
rhs_type = TREE_TYPE (rhs);
lhs_size = TYPE_PRECISION (lhs_type);
rhs_size = TYPE_PRECISION (rhs_type);
- lhs_wraps = TYPE_OVERFLOW_WRAPS (lhs_type);
- rhs_wraps = TYPE_OVERFLOW_WRAPS (rhs_type);
+ lhs_wraps = ANY_INTEGRAL_TYPE_P (lhs_type) && TYPE_OVERFLOW_WRAPS (lhs_type);
+ rhs_wraps = ANY_INTEGRAL_TYPE_P (rhs_type) && TYPE_OVERFLOW_WRAPS (rhs_type);
if (lhs_size < rhs_size
|| (rhs_wraps && !lhs_wraps)
if (tree_contains_chrecs (iv->base, NULL))
return false;
- iv->no_overflow = !folded_casts && TYPE_OVERFLOW_UNDEFINED (type);
+ iv->no_overflow = (!folded_casts && ANY_INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_UNDEFINED (type));
return true;
}
/* If def's type has undefined overflow and there were folded
casts, rewrite all stmts added for def into arithmetics
with defined overflow behavior. */
- if (folded_casts && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (def)))
+ if (folded_casts && ANY_INTEGRAL_TYPE_P (TREE_TYPE (def))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (def)))
{
gimple_seq stmts;
gimple_stmt_iterator gsi2;
case PLUS_EXPR:
case MINUS_EXPR:
- if (TYPE_OVERFLOW_TRAPS (TREE_TYPE (expr)))
+ if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (expr))
+ && TYPE_OVERFLOW_TRAPS (TREE_TYPE (expr)))
return expr;
/* Fallthru. */
case POINTER_PLUS_EXPR:
{
case PLUS_EXPR:
case MINUS_EXPR:
- if (!TYPE_OVERFLOW_TRAPS (type))
+ if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_TRAPS (type))
return expand_vector_addition (gsi, do_binop, do_plus_minus, type,
gimple_assign_rhs1 (assign),
gimple_assign_rhs2 (assign), code);
break;
case NEGATE_EXPR:
- if (!TYPE_OVERFLOW_TRAPS (type))
+ if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_TRAPS (type))
return expand_vector_addition (gsi, do_unop, do_negate, type,
gimple_assign_rhs1 (assign),
NULL_TREE, code);
#define NON_TYPE_CHECK(T) \
(non_type_check ((T), __FILE__, __LINE__, __FUNCTION__))
+/* These checks have to be special cased. */
+#define ANY_INTEGRAL_TYPE_CHECK(T) \
+(any_integral_type_check ((T), __FILE__, __LINE__, __FUNCTION__))
+
#define TREE_INT_CST_ELT_CHECK(T, I) \
(*tree_int_cst_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__))
#define OMP_CLAUSE_ELT_CHECK(T, i) ((T)->omp_clause.ops[i])
#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) (T)
#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) (T)
+#define ANY_INTEGRAL_TYPE_CHECK(T) (T)
#define TREE_CHAIN(NODE) ((NODE)->common.chain)
#define TREE_TYPE(NODE) ((NODE)->typed.type)
|| TREE_CODE (TYPE) == BOOLEAN_TYPE \
|| TREE_CODE (TYPE) == INTEGER_TYPE)
+/* Nonzero if TYPE represents an integral type, including complex
+ and vector integer types. */
+
+#define ANY_INTEGRAL_TYPE_P(TYPE) \
+ (INTEGRAL_TYPE_P (TYPE) \
+ || ((TREE_CODE (TYPE) == COMPLEX_TYPE \
+ || VECTOR_TYPE_P (TYPE)) \
+ && INTEGRAL_TYPE_P (TREE_TYPE (TYPE))))
+
/* Nonzero if TYPE represents a non-saturating fixed-point type. */
#define NON_SAT_FIXED_POINT_TYPE_P(TYPE) \
/* True if overflow wraps around for the given integral type. That
is, TYPE_MAX + 1 == TYPE_MIN. */
#define TYPE_OVERFLOW_WRAPS(TYPE) \
- (TYPE_UNSIGNED (TYPE) || flag_wrapv)
+ (ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag || flag_wrapv)
/* True if overflow is undefined for the given integral type. We may
optimize on the assumption that values in the type never overflow.
it will be appropriate to issue the warning immediately, and in
other cases it will be appropriate to simply set a flag and let the
caller decide whether a warning is appropriate or not. */
-#define TYPE_OVERFLOW_UNDEFINED(TYPE) \
- (!TYPE_UNSIGNED (TYPE) && !flag_wrapv && !flag_trapv && flag_strict_overflow)
+#define TYPE_OVERFLOW_UNDEFINED(TYPE) \
+ (!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \
+ && !flag_wrapv && !flag_trapv && flag_strict_overflow)
/* True if overflow for the given integral type should issue a
trap. */
#define TYPE_OVERFLOW_TRAPS(TYPE) \
- (!TYPE_UNSIGNED (TYPE) && flag_trapv)
+ (!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag && flag_trapv)
/* True if an overflow is to be preserved for sanitization. */
#define TYPE_OVERFLOW_SANITIZED(TYPE) \
return &__t->omp_clause.ops[__i];
}
+/* These checks have to be special cased. */
+
+inline tree
+any_integral_type_check (tree __t, const char *__f, int __l, const char *__g)
+{
+ if (!ANY_INTEGRAL_TYPE_P (__t))
+ tree_check_failed (__t, __f, __l, __g, BOOLEAN_TYPE, ENUMERAL_TYPE,
+ INTEGER_TYPE, 0);
+ return __t;
+}
+
inline const_tree
tree_check (const_tree __t, const char *__f, int __l, const char *__g,
tree_code __c)
return CONST_CAST (const_tree *, &__t->omp_clause.ops[__i]);
}
+inline const_tree
+any_integral_type_check (const_tree __t, const char *__f, int __l,
+ const char *__g)
+{
+ if (!ANY_INTEGRAL_TYPE_P (__t))
+ tree_check_failed (__t, __f, __l, __g, BOOLEAN_TYPE, ENUMERAL_TYPE,
+ INTEGER_TYPE, 0);
+ return __t;
+}
+
#endif
/* Compute the number of operands in an expression node NODE. For