Bug 52578 - Fails to fold another size difference
Summary: Fails to fold another size difference
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 4.8.0
Assignee: Richard Biener
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-13 13:14 UTC by Richard Biener
Modified: 2012-03-14 10:55 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-03-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2012-03-13 13:14:38 UTC
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.
Comment 1 Richard Biener 2012-03-13 13:25:24 UTC
Fixing that we still do not fold foo (), but associate it to

  return ((long int) (long unsigned int) i - (long int) i) + 2;
Comment 2 Richard Biener 2012-03-14 10:51:38 UTC
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
Comment 3 Richard Biener 2012-03-14 10:55:36 UTC
Fixed.