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

Reply via email to