[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Xi Ruoyao changed: What|Removed |Added CC||xry111 at gcc dot gnu.org See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=26 --- Comment #14 from Xi Ruoyao --- (In reply to Jeffrey A. Law from comment #13) > So like the other bug involving multiplies against objects with a known > range [0,1], we should very seriously consider turning the multiply into a > conditional move. ie x * b where b is known to have the range [0,1] we can > turn that into > > dest = b ? x : 0 > > Some processors that don't have generalized conditional moves do have > conditional zero instructions. ie, zicond on RISC-V. It's PR26.
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Jeffrey A. Law changed: What|Removed |Added CC||rzinsly at ventanamicro dot com --- Comment #13 from Jeffrey A. Law --- So like the other bug involving multiplies against objects with a known range [0,1], we should very seriously consider turning the multiply into a conditional move. ie x * b where b is known to have the range [0,1] we can turn that into dest = b ? x : 0 Some processors that don't have generalized conditional moves do have conditional zero instructions. ie, zicond on RISC-V.
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Jeffrey A. Law changed: What|Removed |Added CC||law at gcc dot gnu.org Priority|P3 |P2
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Andrew Pinski changed: What|Removed |Added URL|https://gcc.gnu.org/piperma | |il/gcc-patches/2023-Septemb | |er/630651.html | Status|ASSIGNED|NEW Keywords|patch | Assignee|pinskia at gcc dot gnu.org |unassigned at gcc dot gnu.org --- Comment #12 from Andrew Pinski --- Not working on this. a Ranger/VRP person should fix this instead ...
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Andrew Pinski changed: What|Removed |Added Keywords||patch URL||https://gcc.gnu.org/piperma ||il/gcc-patches/2023-Septemb ||er/630651.html --- Comment #11 from Andrew Pinski --- Patch posted: https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630651.html
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 --- Comment #10 from Andrew Pinski --- This is what I came up with in the end: /* (a * b@[0,1]) == CST -> CST == 0 ? (a == CST | b == 0) : (a == CST & b != 0) (a * b@[0,1]) != CST -> CST != 0 ? (a != CST | b == 0) : (a != CST & b != 0) */ (for cmp (ne eq) (simplify (cmp (mult:cs @0 zero_one_valued_p@1) INTEGER_CST@2) (if ((cmp == EQ_EXPR) ^ (wi::to_wide (@2) != 0)) (bit_ior (cmp @0 @2) (convert (bit_xor @1 { build_one_cst (TREE_TYPE (@1)); }))) (bit_and (cmp @0 @2) (convert @1) This allows more than just CST == 0 even. I will write up some testcases now ...
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 --- Comment #9 from Andrew Pinski --- This is what I have so far: /* Transform (a * { 0 or 1 }) != 0 into {0 or 1} != 0 & (a != 0) */ /* Transform (a * { 0 or 1 }) == 0 into ({0 or 1} == 0) | (a == 0) */ (for cmp (ne eq) bit_op (bit_and bit_ior) (simplify (cmp (mult:cs @0 zero_one_valued_p@1) integer_zerop@2) (bit_op (cmp @1 { build_zero_cst (TREE_TYPE (@1)); }) (cmp @0 @2 /* zero_one_valued_p != 0 -> (cast)zero_one_valued_p */ (simplify (ne zero_one_valued_p@0 integer_zerop) (convert @0))
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 --- Comment #8 from Andrew Pinski --- (In reply to Andrew Pinski from comment #7) > Actually we should transform it into > ((convert)zero_one_valued_p) & (a != 0) > > Or ^1 for the == 0 case ... > > This should allow for better code I think. Or better yet: (((Convert)cmp) & b) != 0 Into cmp & (b!=0) Icmp for == 0. Now I have seen that before too.
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 --- Comment #7 from Andrew Pinski --- Actually we should transform it into ((convert)zero_one_valued_p) & (a != 0) Or ^1 for the == 0 case ... This should allow for better code I think.
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Andrew Pinski changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |pinskia at gcc dot gnu.org --- Comment #6 from Andrew Pinski --- One way of fixing this is: /* Transform (a * { 0 or 1 }) !=/== 0 into (a & { 0 or 1 }) !=/== 0. */ (for cmp (ne eq) (simplify (cmp (mult:cs @0 zero_one_valued_p@1) integer_zerop@2) (cmp (bit_and @0 @1) @2))) That is (a*zero_one_valued_p)!=0 transform it into (a & zero_one_valued_p) != 0 if the multiply was single use. That is how I am going to fix this.
[Bug tree-optimization/110992] [13/14 Regression] missed VRP optimization due to transformation of `a & -zero_one_valued_p` into `a * zero_one_valued_p`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992 Andrew Pinski changed: What|Removed |Added Target Milestone|14.0|13.3 Summary|[14 Regression] Dead Code |[13/14 Regression] missed |Elimination Regression at |VRP optimization due to |-O3 since |transformation of `a & |r14-1654-g7ceed7e3e29 |-zero_one_valued_p` into `a ||* zero_one_valued_p` --- Comment #5 from Andrew Pinski --- Hmm, I think this is a ranger issue really. Take: ``` int f(unsigned b, short c) { int bt = b; int bt1 = bt; int t = bt1 & -(c!=0); // int t = bt1 * (c!=0); if (!t) return 0; foo(bt == 0); return 0; } ``` That `bt == 0` should be figured out that is 0 there. We could figure that out in GCC 12 even. But in GCC 13+ we could not. That is traced back to r13-793-g8fb94fc6097c but really the ranger should figure out if you have a*b != 0, then both a and b should be non-zero ... But currently that is not support It looks like we only handle `a & b` that way ...