https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89536
--- Comment #12 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- > On the testcase, value is -2 and before your change it would derive > correctly that if BIT_NOT_EXPR is -2, then rhs must be ~-2, i.e. 1, but > after the patch it says rhs must be 0. Right, an annoying oversight, which would be cured by: Index: tree-ssa-dom.c =================================================================== --- tree-ssa-dom.c (revision 269211) +++ tree-ssa-dom.c (working copy) @@ -346,7 +346,8 @@ edge_info::derive_equivalences (tree nam boolean types with precision > 1. */ if (code == BIT_NOT_EXPR && TREE_CODE (rhs) == SSA_NAME - && ssa_name_has_boolean_range (rhs)) + && ssa_name_has_boolean_range (rhs) + && (integer_zerop (value) || integer_onep (value))) { if (integer_zerop (value)) res = build_one_cst (TREE_TYPE (rhs)); > Adding integer_onep wouldn't be > correct IMHO, if you have some non-boolean non-prec==1 integral type, even > if you know rhs has range [0, 1], if BIT_NOT_EXPR should be assumed to have > value 0, then rhs needs to be assumed to have value ~0, i.e. -1, rather than > 1, and similarly if BIT_NOT_EXPR has value 1, then rhs needs to be assumed > to have value ~1, i.e. -2, rather than 0. Due to actual value range that > will turn to be something impossible, but what the boolean-ish case does is > just not correct for non-boolean. With this line of reasoning, how can the BIT_AND_EXPR case be correct?