Bug 26198 - Unfolded comparison after cfg_cleanup
Summary: Unfolded comparison after cfg_cleanup
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.2.0
: P3 enhancement
Target Milestone: 4.3.0
Assignee: Richard Biener
URL:
Keywords: missed-optimization
Depends on: 30965
Blocks:
  Show dependency treegraph
 
Reported: 2006-02-09 15:41 UTC by Richard Biener
Modified: 2007-10-12 08:42 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-10-11 11:57:13


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2006-02-09 15:41:44 UTC
struct A
{
  int* x[2];
  A() { for (int** p=x; p<x+2; ++p) *p = 0; }
};

struct B
{
  char c;
  A a0, a1, a2, a3, *p;

  B() {}
  B(const B& b) : c(), a0(b.a0), p(b.p) {}
  ~B() { delete p; }
};

inline void foo(const B& b) { new B(b); }

void bar()
{
  foo(B());
  foo(B());
}

After cfg_cleanup after loop header copying we end up with unfolded

  &D.2114.a0D.2019.xD.1986[2] > &D.2114.a0D.2019.xD.1986[0]

because in fold_binary where we handle this kind of stuff we have

              if (!offset0 || !offset1
                  || TREE_TYPE (offset0) == TREE_TYPE (offset1))
                {
...

and unfortunately the constants 2 and 0 have distinct types:

(gdb) call debug_tree(offset0)
 <integer_cst 0x4026e888 type <integer_type 0x402474ac> constant invariant 8>
(gdb) call debug_tree(offset1)
 <integer_cst 0x4018d180 type <integer_type 0x4019f000 unsigned int> constant invariant 0>
Comment 1 Andrew Pinski 2006-02-09 15:43:14 UTC
Confirmed, this testcase is from PR 26197.
Comment 2 Richard Biener 2006-06-19 19:40:51 UTC
Note that the reason mentioned was fixed recently, but we still have (in .optimized):

<L18>:;
  p = &D.2217->a2.x[0];
  D.2237 = &D.2217->a2.x[2];
  if (p < D.2237) goto <L19>; else goto <L21>;

...

<L21>:;
  p = &D.2217->a3.x[0];
  D.2243 = &D.2217->a3.x[2];
  if (p < D.2243) goto <L22>; else goto <L24>;
Comment 3 Richard Biener 2006-10-26 09:53:26 UTC
And note that before TER we have

  p_108 = &this_91->a3.x[0];
  D.3632_327 = p_108 + 15B;
  if (p_108 <= D.3632_327) goto <L203>; else goto <L47>;

it sucks that we don't tree-combine COND_EXPRs.  Testcase:

int foo(int p)
{
  int q = p + 5;
  return q < p;
}
void bar(int p)
{
  int q = p + 5;
  if (q < p)
    link_error ();
}
Comment 4 Richard Biener 2007-03-05 17:07:23 UTC
Depends on (and is partly fixed by) PR30965.
Comment 5 Richard Biener 2007-10-11 11:57:13 UTC
The original issue seems to no longer trigger with the testcase, the missed
combining is fixed with a patch I have.
Comment 6 Richard Biener 2007-10-11 12:10:59 UTC
Also

  because in fold_binary where we handle this kind of stuff we have

              if (!offset0 || !offset1
                  || TREE_TYPE (offset0) == TREE_TYPE (offset1))
                {
  ...

is no longer true, we compare offsets in signed sizetype.
Comment 7 Richard Biener 2007-10-12 08:42:25 UTC
Subject: Bug 26198

Author: rguenth
Date: Fri Oct 12 08:42:13 2007
New Revision: 129256

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129256
Log:
2007-10-12  Richard Guenther  <rguenther@suse.de>

	PR middle-end/26198
	* tree-ssa-forwprop.c (can_propagate_from): Do not propagate from
	a rhs with side-effects or which is a load.
	(forward_propagate_into_cond): Also try combining both operands.

	* gcc.dg/tree-ssa/forwprop-3.c: New testcase.
	* gcc.c-torture/execute/20071011-1.c: Likewise.
	* gcc.dg/tree-ssa/ssa-pre-9.c: Adjust.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/20071011-1.c
    trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-3.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-9.c
    trunk/gcc/tree-ssa-forwprop.c

Comment 8 Richard Biener 2007-10-12 08:42:35 UTC
Fixed.