diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2013-05-10 13:15:14 +0200 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2013-05-10 11:15:14 +0000 |
commit | a5e0cd1d9bd6fbcff37a6545d8e60b36ff6ea7a7 (patch) | |
tree | 28b2392d93f8ced83cd8e4d51d5232f6883088da /gcc/fold-const.c | |
parent | cb2558bc95658155c76e1468ed4db64359452dc2 (diff) | |
download | gcc-a5e0cd1d9bd6fbcff37a6545d8e60b36ff6ea7a7.zip gcc-a5e0cd1d9bd6fbcff37a6545d8e60b36ff6ea7a7.tar.gz gcc-a5e0cd1d9bd6fbcff37a6545d8e60b36ff6ea7a7.tar.bz2 |
stor-layout.c (element_precision): New function.
2013-05-10 Marc Glisse <marc.glisse@inria.fr>
gcc/
* stor-layout.c (element_precision): New function.
* machmode.h (element_precision): Declare it.
* tree.c (build_minus_one_cst): New function.
(element_precision): Likewise.
* tree.h (build_minus_one_cst): Declare new function.
(element_precision): Likewise.
* fold-const.c (operand_equal_p): Use element_precision.
(fold_binary_loc): Handle vector types.
* convert.c (convert_to_integer): Use element_precision.
* gimple.c (iterative_hash_canonical_type): Handle complex and vectors
separately.
gcc/c-family/
* c-common.c (vector_types_convertible_p): No TYPE_PRECISION for
vectors.
gcc/testsuite/
* gcc.dg/vector-shift.c: New testcase.
From-SVN: r198772
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 74b451e..bfe9e07 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2445,7 +2445,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) /* If both types don't have the same precision, then it is not safe to strip NOPs. */ - if (TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION (TREE_TYPE (arg1))) + if (element_precision (TREE_TYPE (arg0)) + != element_precision (TREE_TYPE (arg1))) return 0; STRIP_NOPS (arg0); @@ -9877,6 +9878,7 @@ fold_binary_loc (location_t loc, tree arg0, arg1, tem; tree t1 = NULL_TREE; bool strict_overflow_p; + unsigned int prec; gcc_assert (IS_EXPR_CODE_CLASS (kind) && TREE_CODE_LENGTH (code) == 2 @@ -10147,7 +10149,7 @@ fold_binary_loc (location_t loc, STRIP_NOPS (tem); if (operand_equal_p (tem, arg1, 0)) { - t1 = build_int_cst_type (type, -1); + t1 = build_minus_one_cst (type); return omit_one_operand_loc (loc, type, t1, arg1); } } @@ -10161,7 +10163,7 @@ fold_binary_loc (location_t loc, STRIP_NOPS (tem); if (operand_equal_p (arg0, tem, 0)) { - t1 = build_int_cst_type (type, -1); + t1 = build_minus_one_cst (type); return omit_one_operand_loc (loc, type, t1, arg0); } } @@ -10387,7 +10389,8 @@ fold_binary_loc (location_t loc, TYPE_UNSIGNED (rtype)) /* Only create rotates in complete modes. Other cases are not expanded properly. */ - && TYPE_PRECISION (rtype) == GET_MODE_PRECISION (TYPE_MODE (rtype))) + && (element_precision (rtype) + == element_precision (TYPE_MODE (rtype)))) { tree tree01, tree11; enum tree_code code01, code11; @@ -10403,7 +10406,7 @@ fold_binary_loc (location_t loc, && TREE_INT_CST_HIGH (tree01) == 0 && TREE_INT_CST_HIGH (tree11) == 0 && ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))))) + == element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0))))) { tem = build2_loc (loc, LROTATE_EXPR, TREE_TYPE (TREE_OPERAND (arg0, 0)), @@ -10420,7 +10423,7 @@ fold_binary_loc (location_t loc, STRIP_NOPS (tree111); if (TREE_CODE (tree110) == INTEGER_CST && 0 == compare_tree_int (tree110, - TYPE_PRECISION + element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0)))) && operand_equal_p (tree01, tree111, 0)) @@ -10441,7 +10444,7 @@ fold_binary_loc (location_t loc, STRIP_NOPS (tree011); if (TREE_CODE (tree010) == INTEGER_CST && 0 == compare_tree_int (tree010, - TYPE_PRECISION + element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0)))) && operand_equal_p (tree11, tree011, 0)) @@ -11757,8 +11760,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)))) { - unsigned int prec - = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))); + prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))); if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT && (~TREE_INT_CST_LOW (arg1) @@ -11826,7 +11828,7 @@ fold_binary_loc (location_t loc, && TYPE_PRECISION (TREE_TYPE (arg0)) == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg0)))) { - unsigned int prec = TYPE_PRECISION (TREE_TYPE (arg0)); + prec = TYPE_PRECISION (TREE_TYPE (arg0)); tree arg00 = TREE_OPERAND (arg0, 0); /* See if more bits can be proven as zero because of zero extension. */ @@ -11869,8 +11871,6 @@ fold_binary_loc (location_t loc, newmask = mask | zerobits; if (newmask != mask && (newmask & (newmask + 1)) == 0) { - unsigned int prec; - /* Only do the transformation if NEWMASK is some integer mode's mask. */ for (prec = BITS_PER_UNIT; @@ -12414,30 +12414,32 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0) return NULL_TREE; + prec = element_precision (type); + /* Turn (a OP c1) OP c2 into a OP (c1+c2). */ if (TREE_CODE (op0) == code && host_integerp (arg1, false) - && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type) + && TREE_INT_CST_LOW (arg1) < prec && host_integerp (TREE_OPERAND (arg0, 1), false) - && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type)) + && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < prec) { HOST_WIDE_INT low = (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) + TREE_INT_CST_LOW (arg1)); /* Deal with a OP (c1 + c2) being undefined but (a OP c1) OP c2 being well defined. */ - if (low >= TYPE_PRECISION (type)) + if (low >= prec) { if (code == LROTATE_EXPR || code == RROTATE_EXPR) - low = low % TYPE_PRECISION (type); + low = low % prec; else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR) - return omit_one_operand_loc (loc, type, build_int_cst (type, 0), + return omit_one_operand_loc (loc, type, build_zero_cst (type), TREE_OPERAND (arg0, 0)); else - low = TYPE_PRECISION (type) - 1; + low = prec - 1; } return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - build_int_cst (type, low)); + build_int_cst (TREE_TYPE (arg1), low)); } /* Transform (x >> c) << c into x & (-1<<c), or transform (x << c) >> c @@ -12446,9 +12448,9 @@ fold_binary_loc (location_t loc, || (TYPE_UNSIGNED (type) && code == RSHIFT_EXPR && TREE_CODE (arg0) == LSHIFT_EXPR)) && host_integerp (arg1, false) - && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type) + && TREE_INT_CST_LOW (arg1) < prec && host_integerp (TREE_OPERAND (arg0, 1), false) - && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type)) + && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < prec) { HOST_WIDE_INT low0 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)); HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1); @@ -12459,8 +12461,8 @@ fold_binary_loc (location_t loc, { arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); - lshift = build_int_cst (type, -1); - lshift = int_const_binop (code, lshift, arg1); + lshift = build_minus_one_cst (type); + lshift = const_binop (code, lshift, arg1); return fold_build2_loc (loc, BIT_AND_EXPR, type, arg00, lshift); } @@ -12470,8 +12472,7 @@ fold_binary_loc (location_t loc, RROTATE_EXPR by a new constant. */ if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST) { - tree tem = build_int_cst (TREE_TYPE (arg1), - TYPE_PRECISION (type)); + tree tem = build_int_cst (TREE_TYPE (arg1), prec); tem = const_binop (MINUS_EXPR, tem, arg1); return fold_build2_loc (loc, RROTATE_EXPR, type, op0, tem); } @@ -12499,7 +12500,7 @@ fold_binary_loc (location_t loc, && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0 && ((TREE_INT_CST_LOW (arg1) + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))) - == (unsigned int) TYPE_PRECISION (type))) + == prec)) return TREE_OPERAND (arg0, 0); /* Fold (X & C2) << C1 into (X << C1) & (C2 << C1) @@ -12912,8 +12913,8 @@ fold_binary_loc (location_t loc, && integer_zerop (arg1)) { tree itype = TREE_TYPE (arg0); - unsigned HOST_WIDE_INT prec = TYPE_PRECISION (itype); tree arg001 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1); + prec = TYPE_PRECISION (itype); /* Check for a valid shift count. */ if (TREE_INT_CST_HIGH (arg001) == 0 |