On Thu, Nov 1, 2012 at 10:10 PM, Marc Glisse <marc.gli...@inria.fr> wrote:
> Hello,
>
> this patch makes gimple checking of vector comparisons more strict by
> ensuring that it doesn't return a boolean. It also fixes a bug that this
> check detected in fold-const.c: for (void)(x<0), the C front-end was calling
> fold_unary_loc on the conversion to void, which was then converted to
> if(x<0)(void)0.
>
> 2012-11-02  Marc Glisse  <marc.gli...@inria.fr>
>
>         * tree-cfg.c (verify_gimple_comparison): Verify that vector
>         comparison returns a vector.
>         * fold-const.c (fold_unary_loc): Disable conversion optimization
>         for void type.
>
> --
> Marc Glisse
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c    (revision 193060)
> +++ gcc/fold-const.c    (working copy)
> @@ -7742,21 +7742,22 @@ 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) && TREE_CODE (type) !=
> VECTOR_TYPE)
> +         else if (!INTEGRAL_TYPE_P (type) && !VOID_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);

Ok for this part.

> Index: gcc/tree-cfg.c
> ===================================================================
> --- gcc/tree-cfg.c      (revision 193060)
> +++ gcc/tree-cfg.c      (working copy)
> @@ -3263,21 +3263,30 @@ verify_gimple_comparison (tree type, tre
>        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))
> -    ;
> +    {
> +      if (TREE_CODE (op0_type) == VECTOR_TYPE
> +         || TREE_CODE (op1_type) == VECTOR_TYPE)
> +        {
> +          error ("vector comparison returning a boolean");
> +          debug_generic_expr (op0_type);
> +          debug_generic_expr (op1_type);
> +          return true;
> +        }

verify_gimple_* should have "positive" checks, thus, check that
if there are vector operands the comparison result should be a
vector.  Not complaining about a vector comparison having a
boolean result.

Richard.

> +    }
>    /* 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);
>

Reply via email to