MATCH: [PR109959] `(uns <= 1) & uns` could be optimized to `uns == 1`
I noticed while looking into some code generation of bitmap_single_bit_set_p, that sometimes: ``` if (uns > 1) return 0; return uns == 1; ``` Would not optimize down to just: ``` return uns == 1; ``` In this case, VRP likes to change `a == 1` into `(bool)a` if a has a range of [0,1] due to `a <= 1` side of the branch. We might end up with this similar code even without VRP, in the case of builtin-sprintf-warn-23.c (and Wrestrict.c), we had: ``` if (s < 0 || 1 < s) s = 0; ``` Which is the same as `s = ((unsigned)s) <= 1 ? s : 0`; So we should be able to catch that also. This adds 2 patterns to catch `(uns <= 1) & uns` and `(uns > 1) ? 0 : uns` and convert those into: `(convert) uns == 1`. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. PR tree-optimization/109959 gcc/ChangeLog: * match.pd (`(a > 1) ? 0 : (cast)a`, `(a <= 1) & (cast)a`): New patterns. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/builtin-sprintf-warn-23.c: Remove xfail. * c-c++-common/Wrestrict.c: Update test and remove some xfail. * gcc.dg/tree-ssa/cmpeq-1.c: New test. * gcc.dg/tree-ssa/cmpeq-2.c: New test. * gcc.dg/tree-ssa/cmpeq-3.c: New test.
Showing
- gcc/match.pd 20 additions, 0 deletionsgcc/match.pd
- gcc/testsuite/c-c++-common/Wrestrict.c 6 additions, 5 deletionsgcc/testsuite/c-c++-common/Wrestrict.c
- gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-23.c 1 addition, 1 deletiongcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-23.c
- gcc/testsuite/gcc.dg/tree-ssa/cmpeq-1.c 36 additions, 0 deletionsgcc/testsuite/gcc.dg/tree-ssa/cmpeq-1.c
- gcc/testsuite/gcc.dg/tree-ssa/cmpeq-2.c 32 additions, 0 deletionsgcc/testsuite/gcc.dg/tree-ssa/cmpeq-2.c
- gcc/testsuite/gcc.dg/tree-ssa/cmpeq-3.c 22 additions, 0 deletionsgcc/testsuite/gcc.dg/tree-ssa/cmpeq-3.c
Loading
Please register or sign in to comment