This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR middle-end/14490


This fixes a missed optimization which is not done on the tree level or RTL level.
We should be able to fold "x -+ CONST1 > CONST2" to "x > CONST2 +- CONST1" if the
addition/subtraction does not overflow. This can only be done for signed types
when wrapping is undefined.


I also found a latent bug in handing the return value of
fold_to_nonsharp_ineq_using_bound in that if we get back the same tree (not same
memory location but represents the same tree) back, we end up in an infinite loop.
This happens as we generate the following to fold in that function:
"a - 1 >= 0" (to a > 0) but originally we had "a > 0" so we end up trying to do
the same fold over and over.


OK? Tested on powerpc-darwin with no regressions.

Thanks,
Andrew Pinski

ChangeLog:

	* fold-const.c (fold_binary): Handle the return value of
	fold_to_nonsharp_ineq_using_bound if we get back the same operand back.
	Implement "X +- C1 CMP C2" folding to "X CMP C2 -+ C1".


Attachment: t.diff.txt
Description: Text document




Testcases:
--- testone ---
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* We going into an infinite loop in fold because we
were mishandling the return value of fold_to_nonsharp_ineq_using_bound. */
_Bool f();
void g(int);
void h (int old_size)
{
int new_size = old_size, i;
g(old_size - 1);
i = 0;
while (i < old_size - 1)
{
if (f())
{
i++;
continue;
}
while (i < old_size - 1)
i++;
}
g(new_size);
}


--- testtwo ---
/* { dg-do compile } */
/* { dg-options "-fdump-tree-gimple" } */
int g(int x)
{
  return (x - 10) < 0;
}
/* There should be only x >= 9 and no x - 10. */
/* { dg-final { scan-tree-dump-times ">= 9" 1 "gimple"} } */
/* { dg-final { scan-tree-dump-times "- 10" 0 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */

--- testthree ---
/* { dg-do compile } */
/* { dg-options "-fdump-tree-gimple -fwrapv" } */
int g(int x)
{
  return (x - 10) < 0;
}
/* There should be no x >= 9 and one x - 10. */
/* { dg-final { scan-tree-dump-times ">= 9" 0 "gimple"} } */
/* { dg-final { scan-tree-dump-times "- 10" 1 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */

--- testfour ---
/* { dg-do compile } */
/* { dg-options "-fdump-tree-gimple" } */
int g(int x)
{
  return (x + 10) < 0;
}
/* There should be only x >= -9 and no x + 10. */
/* { dg-final { scan-tree-dump-times ">= 9" 1 "gimple"} } */
/* { dg-final { scan-tree-dump-times "- 10" 0 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */

--- testfive ---
/* { dg-do compile } */
/* { dg-options "-fdump-tree-gimple -fwrapv" } */
int g(int x)
{
  return (x + 10) < 0;
}
/* There should be no x >= -9 and one x + 10. */
/* { dg-final { scan-tree-dump-times ">= 9" 0 "gimple"} } */
/* { dg-final { scan-tree-dump-times "- 10" 1 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]