Patchwork vector comparisons in C++

login
register
mail settings
Submitter Marc Glisse
Date Sept. 13, 2012, 11:37 p.m.
Message ID <alpine.DEB.2.02.1209140123400.3772@laptop-mg.saclay.inria.fr>
Download mbox | patch
Permalink /patch/183768/
State New
Headers show

Comments

Marc Glisse - Sept. 13, 2012, 11:37 p.m.
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.
Jason Merrill - Sept. 14, 2012, 1:17 p.m.
On 09/13/2012 07:37 PM, Marc Glisse wrote:
> Looks like a latent bug in fold_unary. The following seems to work in
> this case.

Looks good.

Jason

Patch

--- ../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);