[Bug middle-end/77889] New: missing optimization on strlen(p + offset) with a bounded offset
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Oct 6 23:53:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77889
Bug ID: 77889
Summary: missing optimization on strlen(p + offset) with a
bounded offset
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
While testing my patch for bug 77608 I noticed another case of the same
limitation, this one in the tree-ssa-strlen pass. The test case below shows
that while (with my patch) __builtin_object_size is able to compute the range
the smallest sizes of the string that p points to (i.e., either 2 or 3 bytes),
__builtin_strlen is not able to compute the range of lengths of the string that
p points to, even though the range of the offsets into the string is available
via the get_range_info function. (The test cases uses _Bool only to constrain
the range to small bounds; the problem is general and not specific to a
particular type of the offset variable.)
$ cat rng.c && /build/gcc-77608/gcc/xgcc -B /build/gcc-77608/gcc -O2 -S -Wall
-Wextra -Wpedantic -fdump-tree-vrp=/dev/stdout rng.c
void f (_Bool i)
{
const char *p = "abc";
p += i;
unsigned long n = __builtin_strlen (p);
if (n < 2 || 3 < n)
__builtin_abort ();
}
void g (_Bool i)
{
const char *p = "ab";
p += i;
unsigned long n = __builtin_object_size (p, 2);
if (n < 2 || 3 < n)
__builtin_abort ();
}
;; Function f (f, funcdef_no=0, decl_uid=1791, cgraph_uid=0, symbol_order=0)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4
;; 2 succs { 3 4 }
;; 3 succs { }
;; 4 succs { 1 }
Value ranges after VRP:
_1: [0, 1]
_2: [0, +INF]
i_3(D): VARYING
p_4: VARYING
n_6: VARYING
f (_Bool i)
{
long unsigned int n;
const char * p;
sizetype _1;
long unsigned int _2;
<bb 2>:
_1 = (sizetype) i_3(D);
p_4 = "abc" + _1;
n_6 = __builtin_strlen (p_4);
_2 = n_6 + 18446744073709551614;
if (_2 > 1)
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
__builtin_abort ();
<bb 4>:
return;
}
;; Function f (f, funcdef_no=0, decl_uid=1791, cgraph_uid=0, symbol_order=0)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4
;; 2 succs { 3 4 }
;; 3 succs { }
;; 4 succs { 1 }
Value ranges after VRP:
_1: [0, 1]
_2: [0, +INF]
i_3(D): VARYING
p_4: VARYING
n_6: VARYING
f (_Bool i)
{
long unsigned int n;
const char * p;
sizetype _1;
long unsigned int _2;
<bb 2>:
_1 = (sizetype) i_3(D);
p_4 = "abc" + _1;
n_6 = __builtin_strlen (p_4);
_2 = n_6 + 18446744073709551614;
if (_2 > 1)
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
__builtin_abort ();
<bb 4>:
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1796, cgraph_uid=1, symbol_order=1)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
Value ranges after VRP:
_1: [0, 1]
i_3(D): VARYING
p_4: VARYING
n_6: VARYING
g (_Bool i)
{
long unsigned int n;
const char * p;
sizetype _1;
<bb 2>:
_1 = (sizetype) i_3(D);
p_4 = "ab" + _1;
n_6 = __builtin_object_size (p_4, 2);
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1796, cgraph_uid=1, symbol_order=1)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
Value ranges after VRP:
g (_Bool i)
{
long unsigned int n;
const char * p;
<bb 2>:
return;
}
More information about the Gcc-bugs
mailing list