https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82062

--- Comment #8 from rguenther at suse dot de <rguenther at suse dot de> ---
On Wed, 25 Oct 2017, ebotcazou at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82062
> 
> --- Comment #7 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> But in fact we probably just need:
> 
> Index: fold-const.c
> ===================================================================
> --- fold-const.c        (revision 254037)
> +++ fold-const.c        (working copy)
> @@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_
>  #undef OP_SAME_WITH_NULL
>  }
> 
> 
> -/* Similar to operand_equal_p, but strip nops first.  */
> +/* Similar to operand_equal_p, but see if ARG1 might be a variant of ARG0
> +   with a different signedness or a simple conversion.  */
> 
>  static bool
>  operand_equal_for_comparison_p (tree arg0, tree arg1)
> @@ -3378,12 +3379,15 @@ operand_equal_for_comparison_p (tree arg
>        || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
>      return false;
> 
> -  /* Discard any conversions that don't change the modes of ARG0 and ARG1
> -     and see if the inner values are the same.  This removes any
> -     signedness comparison, which doesn't matter here.  */
> -  STRIP_NOPS (arg0);
> -  STRIP_NOPS (arg1);
> -  if (operand_equal_p (arg0, arg1, 0))
> +  tree op0 = arg0;
> +  tree op1 = arg1;
> +  STRIP_NOPS (op0);
> +  STRIP_NOPS (op1);
> +  if (operand_equal_p (op0, op1, 0))
> +    return true;
> +
> +  if (TREE_CODE (arg1) == NOP_EXPR
> +      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
>      return true;

I would really like to see fold_cond_expr_with_comparison
to be re-written into match.pd rules.  Esp. due to
operand_equal_for_comparison_p its correctness is far from
obvious...

There are two things to it, stripping sign-nops from the comparison
operand (careful!) and stripping arbitrary nops from the result
to look for an argument equal to the comparison operand.

I guess a canonicalization transform

 X CMP Y ? (T') X : Z

to

 (T') (X CMP Y ? X : (T'')Z)

is what it implicitely wants to do but given the stripping of
sign-nops from the comparison operand it's not obvious it
does this.

Maybe refactor operand_equal_for_comparison_p into sth
that does not strip arg0 at all but leave that to the caller.

Reply via email to