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.