[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 Roger Sayle changed: What|Removed |Added CC||roger at nextmovesoftware dot com Status|ASSIGNED|RESOLVED Target Milestone|--- |13.0 Resolution|--- |FIXED --- Comment #13 from Roger Sayle --- This should now be fixed on mainline.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #12 from CVS Commits --- The master branch has been updated by Roger Sayle : https://gcc.gnu.org/g:418b71c0d535bf91df78bad2e198c57934682eaa commit r13-2048-g418b71c0d535bf91df78bad2e198c57934682eaa Author: Roger Sayle Date: Mon Aug 15 17:39:47 2022 +0100 PR tree-optimization/64992: (B << 2) != 0 is B when B is Boolean. This patch resolves both PR tree-optimization/64992 and PR tree-optimization/98956 which are missed optimization enhancement request, for which Andrew Pinski already has a proposed solution (related to a fix for PR tree-optimization/98954). Yesterday, I proposed an alternate improved patch for PR98954, which although superior in most respects, alas didn't address this case [which doesn't include a BIT_AND_EXPR], hence this follow-up fix. For many functions, F(B), of a (zero-one) Boolean value B, the expression F(B) != 0 can often be simplified to just B. Hence "(B * 5) != 0" is B, "-B != 0" is B, "bswap(B) != 0" is B, "(B >>r 3) != 0" is B. These are all currently optimized by GCC, with the strange exception of left shifts by a constant (possibly due to the undefined/implementation defined behaviour when the shift constant is larger than the first operand's precision). This patch adds support for this particular case, when the shift constant is valid. 2022-08-15 Roger Sayle gcc/ChangeLog PR tree-optimization/64992 PR tree-optimization/98956 * match.pd (ne (lshift @0 @1) 0): Simplify (X << C) != 0 to X when X is zero_one_valued_p and the shift constant C is valid. (eq (lshift @0 @1) 0): Likewise, simplify (X << C) == 0 to !X when X is zero_one_valued_p and the shift constant C is valid. gcc/testsuite/ChangeLog PR tree-optimization/64992 * gcc.dg/pr64992.c: New test case.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #11 from Andrew Pinski --- Note the latest patch for PR 98954 fixes this one.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #10 from Andrew Pinski --- (In reply to Andrew Pinski from comment #9) > Note for rotate it is as simple as: > (for cmp (eq ne) > (simplify > (cmp (rotate @0 INTEGER_CST@1) INTEGER_CST@2) > (cmp @0 (rotate @2 @1 > > Let me see if that is already there or not and test that one out. Well it is already done (and I messed up the above which should have been invrotote anyways): /* (X >>r C1) cmp C2 may simplify to X cmp C3. */ (simplify (cmp (rotate @0 INTEGER_CST@1) INTEGER_CST@2) (cmp @0 { const_binop (invrot, TREE_TYPE (@0), @2, @1); })) So it is just lshift and rshift that need to be implemented.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #9 from Andrew Pinski --- Note for rotate it is as simple as: (for cmp (eq ne) (simplify (cmp (rotate @0 INTEGER_CST@1) INTEGER_CST@2) (cmp @0 (rotate @2 @1 Let me see if that is already there or not and test that one out.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 Andrew Pinski changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |pinskia at gcc dot gnu.org Status|NEW |ASSIGNED --- Comment #8 from Andrew Pinski --- The missed optimization is: int f(int c) { unsigned t = c == 1; t <<= 1; return t == 0; } int f1(int c) { unsigned t = c == 1; return ((int)t) <= 0; } That is (t << 1) == 0 should be convert into either: (t & 0x7fff) or ((int)t) <= 0 Though the (semi more) general case is: (for shift (lshift rshift) (for eqne (eq ne) (simplify (eqne (shift @0 INTEGER_CST@1) integer_zerop@2) (with { mask = ... } (eqne (bit_and @0 { mask; }) @2) And then the mask bit_and neeq to gtle And then the rest will just work
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #7 from Jakub Jelinek --- Well, if the value range for one MULT_EXPR operand is [0, 1], then it will never overflow, and is enough to know the other operand is ~[0, 0] and it can be optimized to the [0, 1] range operand.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 Andrew Pinski changed: What|Removed |Added Keywords||missed-optimization Severity|normal |enhancement
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #6 from Andrew Pinski --- if a was signed, then a * 2 == 0 just becomes a == 0 as if a * 2 overflows that would become undefined For unsigned, if a has a range of [0,(unsigned)INT_MAX] then a * 2 == 0 can be optimized to a == 0.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 Marc Glisse glisse at gcc dot gnu.org changed: What|Removed |Added Status|WAITING |NEW --- Comment #5 from Marc Glisse glisse at gcc dot gnu.org --- We do not sink the code that computes d into the branch c==-1. If we did, the second comparison would simplify to a constant. VRP is not clever enough to backport new assertions to already computed values. We could also simplify N*x==0 to x==0 even for unsigned when VRP information tells us that overflow/wrap cannot happen (here N is 2 and x is in [0,1]).
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #4 from Ishiura Lab Compiler Team ishiura-compiler at ml dot kwansei.ac.jp --- FYI, clang-3.6 -O3 seems to do the same optimization on org.c as well as on opt.c.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 --- Comment #3 from Ishiura Lab Compiler Team ishiura-compiler at ml dot kwansei.ac.jp --- Looking only from outside, the two programs are virtually equal, so we just wondered what hinders the optimization on one of the programs. The Optimization on opt.c seems very strong, so we think it would be nice if the same transformation would work on org.c.
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 Richard Biener rguenth at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |WAITING Last reconfirmed||2015-02-10 Ever confirmed|0 |1 --- Comment #1 from Richard Biener rguenth at gcc dot gnu.org --- That is simply because you declared b volatile and thus b may be zero HERE. Not sure what you are expecting?
[Bug tree-optimization/64992] More optimize opportunity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64992 Jakub Jelinek jakub at gcc dot gnu.org changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek jakub at gcc dot gnu.org --- Well, b is not volatile. The difference is that 2U * (1 == c) we expand during gimplification as if (1 == c) iftmp = 2; else iftmp = 0; while b * (1 == c) is expanded as multiplication of the EQ_EXPR result and nothing at the tree level changes that afterwards. Perhaps something for match.pd, though not sure if such an transformation is always a win.