aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2013-05-10 13:15:14 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2013-05-10 11:15:14 +0000
commita5e0cd1d9bd6fbcff37a6545d8e60b36ff6ea7a7 (patch)
tree28b2392d93f8ced83cd8e4d51d5232f6883088da /gcc/fold-const.c
parentcb2558bc95658155c76e1468ed4db64359452dc2 (diff)
downloadgcc-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.c55
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