Commit 948a1fd9 by Marc Glisse Committed by Marc Glisse

fold-const.c (negate_expr_p): Handle VECTOR_CST.

2013-06-13  Marc Glisse  <marc.glisse@inria.fr>

gcc/
	* fold-const.c (negate_expr_p): Handle VECTOR_CST.
	(fold_negate_expr): Likewise.
	(fold_real_zero_addition_p): Handle vectors.
	(fold_binary_loc) <PLUS_EXPR, MINUS_EXPR>: Likewise.

gcc/testsuite/
	* gcc.dg/fold-minus-1.c: New testcase.

From-SVN: r200073
parent 0597fb9c
2013-06-13 Marc Glisse <marc.glisse@inria.fr>
* fold-const.c (negate_expr_p): Handle VECTOR_CST.
(fold_negate_expr): Likewise.
(fold_real_zero_addition_p): Handle vectors.
(fold_binary_loc) <PLUS_EXPR, MINUS_EXPR>: Likewise.
2013-06-14 Alan Modra <amodra@gmail.com> 2013-06-14 Alan Modra <amodra@gmail.com>
* varasm.c (force_const_mem): Revert 2013-06-07 change. * varasm.c (force_const_mem): Revert 2013-06-07 change.
......
...@@ -421,6 +421,20 @@ negate_expr_p (tree t) ...@@ -421,6 +421,20 @@ negate_expr_p (tree t)
return negate_expr_p (TREE_REALPART (t)) return negate_expr_p (TREE_REALPART (t))
&& negate_expr_p (TREE_IMAGPART (t)); && negate_expr_p (TREE_IMAGPART (t));
case VECTOR_CST:
{
if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
return true;
int count = TYPE_VECTOR_SUBPARTS (type), i;
for (i = 0; i < count; i++)
if (!negate_expr_p (VECTOR_CST_ELT (t, i)))
return false;
return true;
}
case COMPLEX_EXPR: case COMPLEX_EXPR:
return negate_expr_p (TREE_OPERAND (t, 0)) return negate_expr_p (TREE_OPERAND (t, 0))
&& negate_expr_p (TREE_OPERAND (t, 1)); && negate_expr_p (TREE_OPERAND (t, 1));
...@@ -560,6 +574,21 @@ fold_negate_expr (location_t loc, tree t) ...@@ -560,6 +574,21 @@ fold_negate_expr (location_t loc, tree t)
} }
break; break;
case VECTOR_CST:
{
int count = TYPE_VECTOR_SUBPARTS (type), i;
tree *elts = XALLOCAVEC (tree, count);
for (i = 0; i < count; i++)
{
elts[i] = fold_negate_expr (loc, VECTOR_CST_ELT (t, i));
if (elts[i] == NULL_TREE)
return NULL_TREE;
}
return build_vector (type, elts);
}
case COMPLEX_EXPR: case COMPLEX_EXPR:
if (negate_expr_p (t)) if (negate_expr_p (t))
return fold_build2_loc (loc, COMPLEX_EXPR, type, return fold_build2_loc (loc, COMPLEX_EXPR, type,
...@@ -6168,9 +6197,12 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) ...@@ -6168,9 +6197,12 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))) if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
return true; return true;
/* In a vector or complex, we would need to check the sign of all zeros. */
if (TREE_CODE (addend) != REAL_CST)
return false;
/* Treat x + -0 as x - 0 and x - -0 as x + 0. */ /* Treat x + -0 as x - 0 and x - -0 as x + 0. */
if (TREE_CODE (addend) == REAL_CST if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
&& REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
negate = !negate; negate = !negate;
/* The mode has signed zeros, and we have to honor their sign. /* The mode has signed zeros, and we have to honor their sign.
...@@ -10161,7 +10193,7 @@ fold_binary_loc (location_t loc, ...@@ -10161,7 +10193,7 @@ fold_binary_loc (location_t loc,
fold_convert_loc (loc, type, fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0))); TREE_OPERAND (arg0, 0)));
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
{ {
/* Convert ~A + 1 to -A. */ /* Convert ~A + 1 to -A. */
if (TREE_CODE (arg0) == BIT_NOT_EXPR if (TREE_CODE (arg0) == BIT_NOT_EXPR
...@@ -10179,7 +10211,7 @@ fold_binary_loc (location_t loc, ...@@ -10179,7 +10211,7 @@ fold_binary_loc (location_t loc,
STRIP_NOPS (tem); STRIP_NOPS (tem);
if (operand_equal_p (tem, arg1, 0)) if (operand_equal_p (tem, arg1, 0))
{ {
t1 = build_minus_one_cst (type); t1 = build_all_ones_cst (type);
return omit_one_operand_loc (loc, type, t1, arg1); return omit_one_operand_loc (loc, type, t1, arg1);
} }
} }
...@@ -10193,7 +10225,7 @@ fold_binary_loc (location_t loc, ...@@ -10193,7 +10225,7 @@ fold_binary_loc (location_t loc,
STRIP_NOPS (tem); STRIP_NOPS (tem);
if (operand_equal_p (arg0, tem, 0)) if (operand_equal_p (arg0, tem, 0))
{ {
t1 = build_minus_one_cst (type); t1 = build_all_ones_cst (type);
return omit_one_operand_loc (loc, type, t1, arg0); return omit_one_operand_loc (loc, type, t1, arg0);
} }
} }
...@@ -10674,8 +10706,6 @@ fold_binary_loc (location_t loc, ...@@ -10674,8 +10706,6 @@ fold_binary_loc (location_t loc,
TREE_OPERAND (arg1, 0))); TREE_OPERAND (arg1, 0)));
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR if (TREE_CODE (arg0) == NEGATE_EXPR
&& (FLOAT_TYPE_P (type)
|| INTEGRAL_TYPE_P (type))
&& negate_expr_p (arg1) && negate_expr_p (arg1)
&& reorder_operands_p (arg0, arg1)) && reorder_operands_p (arg0, arg1))
return fold_build2_loc (loc, MINUS_EXPR, type, return fold_build2_loc (loc, MINUS_EXPR, type,
...@@ -10684,7 +10714,7 @@ fold_binary_loc (location_t loc, ...@@ -10684,7 +10714,7 @@ fold_binary_loc (location_t loc,
fold_convert_loc (loc, type, fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0))); TREE_OPERAND (arg0, 0)));
/* Convert -A - 1 to ~A. */ /* Convert -A - 1 to ~A. */
if (INTEGRAL_TYPE_P (type) if (TREE_CODE (type) != COMPLEX_TYPE
&& TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg0) == NEGATE_EXPR
&& integer_onep (arg1) && integer_onep (arg1)
&& !TYPE_OVERFLOW_TRAPS (type)) && !TYPE_OVERFLOW_TRAPS (type))
...@@ -10693,13 +10723,13 @@ fold_binary_loc (location_t loc, ...@@ -10693,13 +10723,13 @@ fold_binary_loc (location_t loc,
TREE_OPERAND (arg0, 0))); TREE_OPERAND (arg0, 0)));
/* Convert -1 - A to ~A. */ /* Convert -1 - A to ~A. */
if (INTEGRAL_TYPE_P (type) if (TREE_CODE (type) != COMPLEX_TYPE
&& integer_all_onesp (arg0)) && integer_all_onesp (arg0))
return fold_build1_loc (loc, BIT_NOT_EXPR, type, op1); return fold_build1_loc (loc, BIT_NOT_EXPR, type, op1);
/* X - (X / CST) * CST is X % CST. */ /* X - (X / Y) * Y is X % Y. */
if (INTEGRAL_TYPE_P (type) if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
&& TREE_CODE (arg1) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR
&& TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
&& operand_equal_p (arg0, && operand_equal_p (arg0,
......
2013-06-13 Marc Glisse <marc.glisse@inria.fr>
* gcc.dg/fold-minus-1.c: New testcase.
2013-06-13 Mikael Morin <mikael@gcc.gnu.org> 2013-06-13 Mikael Morin <mikael@gcc.gnu.org>
PR fortran/49074 PR fortran/49074
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-gimple" } */
typedef int vec __attribute__((vector_size(2*sizeof(int))));
void f(vec*x,vec*y){
*x -= *x / *y * *y;
}
void g(vec*x,vec*y,vec*z){
*x = -1 - *x;
*y = -*y - 1;
*z = -*z - 13;
}
/* { dg-final { scan-tree-dump-times "%" 1 "gimple"} } */
/* { dg-final { scan-tree-dump-times "~" 2 "gimple"} } */
/* { dg-final { scan-tree-dump-not "/" "gimple"} } */
/* { dg-final { scan-tree-dump-not "\\\+" "gimple"} } */
/* { dg-final { scan-tree-dump "{ -13, -13 }" "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment