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

--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Qi Feng from comment #9)
> And there's another problem. Take `x >  y  &&  x != 0   -->   x > y' for
> example, I would also like to do
> 
>    x <  y  &&  y != 0  -->  x < y
>    x != 0  &&  x >  y  -->  x > y
>    y != 0  &&  x <  y  -->  x < y
> 
> If the constant always comes in as the second operand is incorrect, these
> would have to be doubled.
> 
> I tried to add :c to truth_andif, but got the `operation is not commutative'
> error.  I also tried to make truth_andif commutative by modifying
> genmatch.c, but again, I don't know it well, afraid that I would break
> something.
> 
> The patterns I wrote looks like:
> 
>     /* x >  y  &&  x != 0     -->     x > y
>        Only for unsigned x and y.  */
>     (simplify
>      (truth_andif:c (gt@2 @0 @1) (ne @0 integer_zerop))
>      (if (INTEGRAL_TYPE_P (TREE_TYPE(@0)) && TYPE_UNSIGNED (TREE_TYPE(@0))
>           && INTEGRAL_TYPE_P (TREE_TYPE(@1)) && TYPE_UNSIGNED
> (TREE_TYPE(@1)))
>        @2))
> 
> I have to wrote 4 of this with minor modification for a single
> transformation. If there's better way to do it, please do leave a comment.

I think first of all you do _not_ want to use truth_andif since that
will only prevail iff x or y have side-effects.  To match on GIMPLE
you want bit_and instead/as well since all truth_ stuff doesn't prevail there.

And obviously truth_andif is _not_ commutative.  You can use :C if you
want to force it though.  Both truth_and and bit_and are commutative.
So sth like

(for and (truth_and bit_and)
 (for ltgtop (lt le)
  (simplify
   (and:c (ltgtop:c@2 @0 @1) (ne @0 integer_zerop))
   (if (...)
    @2)))

should cover all of

   x <  y  &&  y != 0  -->  x < y
   x != 0  &&  x >  y  -->  x > y
   y != 0  &&  x <  y  -->  x < y
   x <  y  &&  y != 0  -->  x < y

note that from

(and (lt:c@2 @0 @1) (ne @0 integer_zerop))

we generate

(and (lt@2 @0 @1) (ne @0 integer_zerop))
(and (gt@2 @1 @0) (ne @0 integer_zerop))

so :c will ensure the semantically same operation will be present with
swapped operands.  As opposed to :C which would do lt@2 @1 @0.

Reply via email to