------- Additional Comments From jakub at gcc dot gnu dot org 2005-02-10 18:07 ------- Actually, I see there multiple problems elsewhere. First is on int i; int foo (void) { return i & ~(unsigned int)3; } First is that if (change) return fold (build2 (BIT_AND_EXPR, type, fold_convert (type, and0), fold_convert (type, and1))); folds (int) ((unsigned)i & ~(unsigned)3) into i & (int)~(unsigned)3 where (int)~(unsigned)3 is -4 with TREE_OVERFLOW set. But there is no overflow in the original program, so we shouldn't IMHO create one as part of this optimization.
Another problem is that case POINTER_TYPE: case REFERENCE_TYPE: if (integer_zerop (expr)) expr = integer_zero_node; else expr = fold (build1 (CONVERT_EXPR, lang_hooks.types.type_for_size (POINTER_SIZE, 0), expr)); return convert_to_integer (type, expr); unconditionally converts to signed type as wide as pointer (== intptr_t) instead of considering TYPE_UNSIGNED (type). As the result of these 2, fold_truthop is presented with ll_mask and ll_and_mask TREE_OVERFLOW -4 and given that gets confused into believing the whole comparison is always 0. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19857