https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83377
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Vinay Kumar from comment #3) > The below mentioned pattern match in match.pd generates the assembly code > similar to subtraction. > ========================================== > diff --git a/gcc/match.pd b/gcc/match.pd > index fbb4d6f..3cde6a6 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -925,6 +925,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (bit_and @0 integer_all_onesp) > (non_lvalue @0)) > > +/*Fold (x & ~CST) into (x - CST)*/ > +(simplify(bit_and:c @0 INTEGER_CST@1) > +(if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))) > + (minus @0 (negate @1)))) > + That is completely invalid transformation. Have you actually tried it? The reason you can do what is in #c0 is because the test guarantees you corresponding bit (has to be a single one) is set and so the subtraction works like masking off that single bit. In the RTL passes (e.g. combiner) I don't think we have information on guaranteed set bits, we have just information on guaranteed zero bits (through nonzero_bits). Not sure if GIMPLE ccp can handle this or not, at least in theory it could because it has a constant and mask for each SSA_NAME. Dunno if it has something similar to VRP assert expressions though or derives something from the edge state.