On Fri, 14 Sep 2012, Marc Glisse wrote:
While checking my facts for the previous paragraph, I got an ICE :-(
typedef int vec __attribute__((vector_size(16)));
vec const f(vec x,vec y){return x<y;}
cc.c:2:11: internal compiler error: in prepare_cmp_insn, at optabs.c:4176
The same program compiles with gcc (prepare_cmp_insn isn't called), but ICEs
with g++. Looking at the 003t.original tree dump, the C one looks like:
return VIEW_CONVERT_EXPR<const vec>(x < y);
while the C++ one looks like:
return <retval> = x < y ? { -1, -1, -1, -1 } : { 0, 0, 0, 0 };
or in raw form:
gimple_cond <lt_expr, x, y, <D.2200>, <D.2201>>
gimple_label <<D.2200>>
gimple_assign <vector_cst, iftmp.0, { -1, -1, -1, -1 }, NULL, NULL>
gimple_goto <<D.2202>>
gimple_label <<D.2201>>
gimple_assign <vector_cst, iftmp.0, { 0, 0, 0, 0 }, NULL, NULL>
gimple_label <<D.2202>>
gimple_assign <var_decl, D.2198, iftmp.0, NULL, NULL>
gimple_return <D.2198>
That doesn't look very vector-like... I'll investigate before resending the
patch.
Looks like a latent bug in fold_unary. The following seems to work in this
case. We then end up with a VIEW_CONVERT_EXPR in C and a NOP_EXPR in C++,
both seem fine. I'll post a combined patch once I have tested it.
--- ../fold-const.c (revision 191279)
+++ ../fold-const.c (working copy)
@@ -7764,21 +7764,21 @@ fold_unary_loc (location_t loc, enum tre
/* If we have (type) (a CMP b) and type is an integral type, return
new expression involving the new type. Canonicalize
(type) (a CMP b) to (a CMP b) ? (type) true : (type) false for
non-integral type.
Do not fold the result as that would not simplify further, also
folding again results in recursions. */
if (TREE_CODE (type) == BOOLEAN_TYPE)
return build2_loc (loc, TREE_CODE (op0), type,
TREE_OPERAND (op0, 0),
TREE_OPERAND (op0, 1));
- else if (!INTEGRAL_TYPE_P (type))
+ else if (!INTEGRAL_TYPE_P (type) && TREE_CODE (type) != VECTOR_TYPE)
return build3_loc (loc, COND_EXPR, type, op0,
constant_boolean_node (true, type),
constant_boolean_node (false, type));
}
/* Handle cases of two conversions in a row. */
if (CONVERT_EXPR_P (op0))
{
tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
tree inter_type = TREE_TYPE (op0);
--
Marc Glisse