With the _FORTIFY_SOURCE hackery we have the transposed args to memset
check which boils down to sth like

extern void foo(void);
extern char *pt;
extern void __warn_memset_zero_len (void);
typedef unsigned long size_t;
void e_malloc(size_t size)
{
  if (size > 0)
    foo ();
  __builtin_constant_p (size) && (size) == 0
    ? (__warn_memset_zero_len (), (void) (0), (void) (size), (void *) (pt))
      : __builtin_memset (pt, 0, size);
}

where we expect the call to __warn_memset_zero_len to be optimized away.
This used to work with 4.0, but now with -O2 we get

<bb 0>:
  if (size != 0) goto <L0>; else goto <L1>;

<L0>:;
  foo ();
  iftmp.0 = __builtin_memset (pt, 0, size) [tail call];
  goto <bb 3> (<L4>);

<L1>:;
  __warn_memset_zero_len () [tail call];

<L4>:;
  return;

as appearantly at some point we decide to ignore the __builtin_constant_p
check.  DOM1 threads the edge from after the call to foo() to after the
check, where later VRP or whatever can no longer cope with this CFG structure:

<bb 0>:
  if (size_1 != 0) goto <L0>; else goto <L1>;

<L0>:;
  foo ();
  goto <bb 6> (<L6>);

<L1>:; 
  D.1286_2 = __builtin_constant_p (size_1);
  D.1287_3 = D.1286_2 != 0;
  D.1288_4 = size_1 == 0;
  D.1289_5 = D.1287_3 && D.1288_4;
  if (D.1289_5) goto <L2>; else goto <L3>;

<L2>:; 
  __warn_memset_zero_len ();
  goto <bb 5> (<L4>);

<L3>:;
  pt.1_7 = pt;
  iftmp.0_8 = __builtin_memset (pt.1_7, 0, size_1);

<L4>:;
  return;

<L6>:;
  D.1286_15 = __builtin_constant_p (size_1);
  D.1287_16 = D.1286_15 != 0;
  D.1288_17 = size_1 == 0;
  D.1289_18 = D.1287_16 && D.1288_17;
  goto <bb 4> (<L3>);

though even without DOM we end up with (unoptimized, at the tree level)

<bb 0>:
  if (size != 0) goto <L0>; else goto <L1>;

<L0>:;
  foo ();

<L1>:;
  D.1287 = 0;
  if (D.1287 && size == 0) goto <L2>; else goto <L3>;

<L2>:;
  __warn_memset_zero_len () [tail call];
  goto <bb 5> (<L4>);

<L3>:;
  iftmp.0 = __builtin_memset (pt, 0, size) [tail call];

<L4>:;
  return;

while RTL passes are able to optimize away the BB following L2.

Note this is with gcc (GCC) 4.1.0 20051211 (prerelease), I need to check
more recent versions.


-- 
           Summary: [4.1 Regression] Loosing __builtin_constant_p during
                    tree optimization
           Product: gcc
           Version: 4.1.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rguenth at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25639


Reply via email to