gnat.dg/opt9.adb will fail with the bitfield handling patch with -m32 because we do not fold long bar (long i) { return (long)((unsigned long)i + 2) - (long)i; } long foo (int i) { return (long)((unsigned long)i + 2) - (long)i; } to constants. the associate: path splits the above to var0 == (long unsigned int) i, lit0 == 2, var1 == -i which fails to associate because of /* With undefined overflow we can only associate constants with one variable, and constants whose association doesn't overflow. */ if ((POINTER_TYPE_P (type) && POINTER_TYPE_OVERFLOW_UNDEFINED) || (INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type))) { if (var0 && var1) { tree tmp0 = var0; tree tmp1 = var1; if (TREE_CODE (tmp0) == NEGATE_EXPR) tmp0 = TREE_OPERAND (tmp0, 0); if (TREE_CODE (tmp1) == NEGATE_EXPR) tmp1 = TREE_OPERAND (tmp1, 0); /* The only case we can still associate with two variables is if they are the same, modulo negation. */ if (!operand_equal_p (tmp0, tmp1, 0)) ok = false; but we can as well strip widening and sign-changing conversions I think.
Fixing that we still do not fold foo (), but associate it to return ((long int) (long unsigned int) i - (long int) i) + 2;
Author: rguenth Date: Wed Mar 14 10:51:34 2012 New Revision: 185378 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185378 Log: 2012-03-14 Richard Guenther <rguenther@suse.de> PR middle-end/52578 * fold-const.c (fold_unary_loc): Fold (T1)(T2)x to (T1)x if the outermost conversion is a sign-change only. (fold_binary_loc): Disregard widening and sign-changing conversions when we determine if two variables are equal for reassociation. * tree-ssa-forwprop.c (combine_conversions): Fold (T1)(T2)x to (T1)x if the outermost conversion is a sign-change only. * gcc.dg/pr52578.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/pr52578.c Modified: trunk/gcc/ChangeLog trunk/gcc/fold-const.c trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-forwprop.c
Fixed.