While working on moving fold-const.c bit expression optimizations to a SSA based optimization, I found that if we optimize (a^N)&N to ~a & N, VRP does not change that to just a ^ N. Simple example: /* { dg-do compile } */ /* { dg-options "-O2 -fno-tree-ccp -fdump-tree-vrp1" } */ int f(int x) { if (x >= 0 && x <= 3) { x = (x ^ 3) & 3; } return x; } /* { dg-final { scan-tree-dump-times " & 3;" 0 "vrp1" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "vrp1" } } */
I am going to work on this with my combine patches, I am thinking about allowing VRP to supply a range to the combine stage and we should be able to use that info to do the folding there (in a more common place too).
The combine stage should have access to a valueize() hook as well, to query SSA propagator/VNs lattice. That hook can maybe supply this extra info (I wanted to make VRP info persistent for some time, in SSA_NAME_PTR_INFO much like we have alignment info there which really is kind of a value-range)
(In reply to comment #2) > The combine stage should have access to a valueize() hook as well, to query > SSA propagator/VNs lattice. That hook can maybe supply this extra info > (I wanted to make VRP info persistent for some time, in SSA_NAME_PTR_INFO > much like we have alignment info there which really is kind of a value-range) I was thinking about adding that. Even using nonzero bits to create a simple range.
Was fixed with r7-820 which adds the pattern to match.pd.