[Bug tree-optimization/81776] New: missing sprintf optimization due to pointer escape analysis
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Aug 9 02:26:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81776
Bug ID: 81776
Summary: missing sprintf optimization due to pointer escape
analysis
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
When a built-in function like memcpy or strcpy is called with a local buffer
GCC knows that the call doesn't clobber other local buffers. But the analysis
seems to be missing a case to make the same determination for calls to sprintf
or snprintf. As a result, as the following case shows, when sprintf if
transformed to strcpy, GCC successfully optimizes away the test and subsequent
call to abort in g1(). But when the same sprintf to strcpy transformation is
defeated by using the '-' flag in the "%-s" directive, GCC fails to make the
same optimization in g2().
$ cat a.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout b.c
void f (void*);
struct S { char *a, *b; };
void g1 (struct S *p, const char *s, unsigned n)
{
p->a = __builtin_malloc (n + 1);
p->a[0] = 123;
p->b = __builtin_malloc (n + 1);
__builtin_sprintf (p->b, "%s", s);
if (p->a[0] != 123) // can never be true
__builtin_abort (); // eliminated
__builtin_sprintf (p->b, "%s", s);
f (p);
}
void g2 (struct S *p, const char *s, unsigned n)
{
p->a = __builtin_malloc (n + 1);
p->a[0] = 123;
p->b = __builtin_malloc (n + 1);
__builtin_sprintf (p->b, "%-s", s);
if (p->a[0] != 123) // can never be true
__builtin_abort (); // not eliminated
__builtin_sprintf (p->a, "%-s", s);
f (p);
}
;; Function g1 (g1, funcdef_no=0, decl_uid=1822, cgraph_uid=0, symbol_order=0)
g1 (struct S * p, const char * s, unsigned int n)
{
unsigned int _1;
long unsigned int _2;
void * _3;
void * _4;
<bb 2> [100.00%] [count: INV]:
_1 = n_8(D) + 1;
_2 = (long unsigned int) _1;
_3 = __builtin_malloc (_2);
p_11(D)->a = _3;
MEM[(char *)_3] = 123;
_4 = __builtin_malloc (_2);
p_11(D)->b = _4;
__builtin_strcpy (_4, s_16(D));
__builtin_strcpy (_4, s_16(D));
f (p_11(D)); [tail call]
return;
}
;; Function g2 (g2, funcdef_no=1, decl_uid=1827, cgraph_uid=1, symbol_order=1)
g2 (struct S * p, const char * s, unsigned int n)
{
unsigned int _1;
long unsigned int _2;
void * _3;
void * _4;
char * _5;
char _6;
<bb 2> [100.00%] [count: INV]:
_1 = n_7(D) + 1;
_2 = (long unsigned int) _1;
_3 = __builtin_malloc (_2);
p_10(D)->a = _3;
MEM[(char *)_3] = 123;
_4 = __builtin_malloc (_2);
p_10(D)->b = _4;
__builtin_sprintf (_4, "%-s", s_15(D));
_5 = p_10(D)->a;
_6 = *_5;
if (_6 != 123)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
__builtin_sprintf (_5, "%-s", s_15(D));
f (p_10(D)); [tail call]
return;
}
More information about the Gcc-bugs
mailing list