Commit 544d960a by Artjoms Sinkarovs Committed by Richard Biener

20011-08-29 Artjoms Sinkarovs <artyom.shinkaroff@gmail.com>

	Richard Guenther  <rguenther@suse.de>

	* tree.h (constant_boolean_node): Adjust prototype.
	* fold-const.c (fold_convert_loc): Move aggregate conversion
	leeway down.
	(constant_boolean_node): Make value parameter boolean, add
	vector type handling.
	(fold_unary_loc): Use constant_boolean_node.
	(fold_binary_loc): Preserve types properly when folding
	COMPLEX_EXPR <__real x, __imag x>.
	* gimplify.c (gimplify_expr): Handle vector comparison.
	* tree.def (EQ_EXPR, ...): Document behavior on vector typed
	comparison.
	* tree-cfg.c (verify_gimple_comparison): Verify vector typed
	comparisons.

From-SVN: r178209
parent 776bebcd
20011-08-29 Artjoms Sinkarovs <artyom.shinkaroff@gmail.com>
Richard Guenther <rguenther@suse.de>
* tree.h (constant_boolean_node): Adjust prototype.
* fold-const.c (fold_convert_loc): Move aggregate conversion
leeway down.
(constant_boolean_node): Make value parameter boolean, add
vector type handling.
(fold_unary_loc): Use constant_boolean_node.
(fold_binary_loc): Preserve types properly when folding
COMPLEX_EXPR <__real x, __imag x>.
* gimplify.c (gimplify_expr): Handle vector comparison.
* tree.def (EQ_EXPR, ...): Document behavior on vector typed
comparison.
* tree-cfg.c (verify_gimple_comparison): Verify vector typed
comparisons.
2011-08-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/48722
......@@ -1867,9 +1867,6 @@ fold_convert_loc (location_t loc, tree type, tree arg)
|| TREE_CODE (orig) == ERROR_MARK)
return error_mark_node;
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
return fold_build1_loc (loc, NOP_EXPR, type, arg);
switch (TREE_CODE (type))
{
case POINTER_TYPE:
......@@ -2017,6 +2014,8 @@ fold_convert_loc (location_t loc, tree type, tree arg)
return fold_build1_loc (loc, NOP_EXPR, type, tem);
default:
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
return fold_build1_loc (loc, NOP_EXPR, type, arg);
gcc_unreachable ();
}
fold_convert_exit:
......@@ -5929,17 +5928,22 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
}
/* Return a node which has the indicated constant VALUE (either 0 or
1), and is of the indicated TYPE. */
1 for scalars or {-1,-1,..} or {0,0,...} for vectors),
and is of the indicated TYPE. */
tree
constant_boolean_node (int value, tree type)
constant_boolean_node (bool value, tree type)
{
if (type == integer_type_node)
return value ? integer_one_node : integer_zero_node;
else if (type == boolean_type_node)
return value ? boolean_true_node : boolean_false_node;
else if (TREE_CODE (type) == VECTOR_TYPE)
return build_vector_from_val (type,
build_int_cst (TREE_TYPE (type),
value ? -1 : 0));
else
return build_int_cst (type, value);
return fold_convert (type, value ? integer_one_node : integer_zero_node);
}
......@@ -7668,8 +7672,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
TREE_OPERAND (op0, 1));
else if (!INTEGRAL_TYPE_P (type))
return build3_loc (loc, COND_EXPR, type, op0,
fold_convert (type, boolean_true_node),
fold_convert (type, boolean_false_node));
constant_boolean_node (true, type),
constant_boolean_node (false, type));
}
/* Handle cases of two conversions in a row. */
......@@ -13202,8 +13206,7 @@ fold_binary_loc (location_t loc,
return build_complex (type, arg0, arg1);
if (TREE_CODE (arg0) == REALPART_EXPR
&& TREE_CODE (arg1) == IMAGPART_EXPR
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg0, 0)))
== TYPE_MAIN_VARIANT (type))
&& TREE_TYPE (TREE_OPERAND (arg0, 0)) == type
&& operand_equal_p (TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg1, 0), 0))
return omit_one_operand_loc (loc, type, TREE_OPERAND (arg0, 0),
......
......@@ -7349,7 +7349,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
{
tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
if (!AGGREGATE_TYPE_P (type))
/* Vector comparisons need no boolification. */
if (TREE_CODE (type) == VECTOR_TYPE)
goto expr_2;
else if (!AGGREGATE_TYPE_P (type))
{
tree org_type = TREE_TYPE (*expr_p);
*expr_p = gimple_boolify (*expr_p);
......
......@@ -3193,25 +3193,55 @@ verify_gimple_comparison (tree type, tree op0, tree op1)
effective type the comparison is carried out in. Instead
we require that either the first operand is trivially
convertible into the second, or the other way around.
The resulting type of a comparison may be any integral type.
Because we special-case pointers to void we allow
comparisons of pointers with the same mode as well. */
if ((!useless_type_conversion_p (op0_type, op1_type)
&& !useless_type_conversion_p (op1_type, op0_type)
&& (!POINTER_TYPE_P (op0_type)
|| !POINTER_TYPE_P (op1_type)
|| TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
|| !INTEGRAL_TYPE_P (type)
|| (TREE_CODE (type) != BOOLEAN_TYPE
&& TYPE_PRECISION (type) != 1))
{
error ("type mismatch in comparison expression");
debug_generic_expr (type);
if (!useless_type_conversion_p (op0_type, op1_type)
&& !useless_type_conversion_p (op1_type, op0_type)
&& (!POINTER_TYPE_P (op0_type)
|| !POINTER_TYPE_P (op1_type)
|| TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
{
error ("mismatching comparison operand types");
debug_generic_expr (op0_type);
debug_generic_expr (op1_type);
return true;
}
/* The resulting type of a comparison may be an effective boolean type. */
if (INTEGRAL_TYPE_P (type)
&& (TREE_CODE (type) == BOOLEAN_TYPE
|| TYPE_PRECISION (type) == 1))
;
/* Or an integer vector type with the same size and element count
as the comparison operand types. */
else if (TREE_CODE (type) == VECTOR_TYPE
&& TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
{
if (TREE_CODE (op0_type) != VECTOR_TYPE
|| TREE_CODE (op1_type) != VECTOR_TYPE)
{
error ("non-vector operands in vector comparison");
debug_generic_expr (op0_type);
debug_generic_expr (op1_type);
return true;
}
if (TYPE_VECTOR_SUBPARTS (type) != TYPE_VECTOR_SUBPARTS (op0_type)
|| (GET_MODE_SIZE (TYPE_MODE (type))
!= GET_MODE_SIZE (TYPE_MODE (op0_type))))
{
error ("invalid vector comparison resulting type");
debug_generic_expr (type);
return true;
}
}
else
{
error ("bogus comparison result type");
debug_generic_expr (type);
return true;
}
return false;
}
......
......@@ -704,7 +704,10 @@ DEFTREECODE (TRUTH_NOT_EXPR, "truth_not_expr", tcc_expression, 1)
The others are allowed only for integer (or pointer or enumeral)
or real types.
In all cases the operands will have the same type,
and the value is always the type used by the language for booleans. */
and the value is either the type used by the language for booleans
or an integer vector type of the same size and with the same number
of elements as the comparison operands. True for a vector of
comparison results has all bits set while false is equal to zero. */
DEFTREECODE (LT_EXPR, "lt_expr", tcc_comparison, 2)
DEFTREECODE (LE_EXPR, "le_expr", tcc_comparison, 2)
DEFTREECODE (GT_EXPR, "gt_expr", tcc_comparison, 2)
......
......@@ -5274,7 +5274,7 @@ extern tree build_simple_mem_ref_loc (location_t, tree);
extern double_int mem_ref_offset (const_tree);
extern tree reference_alias_ptr_type (const_tree);
extern tree build_invariant_address (tree, tree, HOST_WIDE_INT);
extern tree constant_boolean_node (int, tree);
extern tree constant_boolean_node (bool, tree);
extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree);
extern bool tree_swap_operands_p (const_tree, const_tree, bool);
......
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