https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96351
Bug ID: 96351
Summary: missed opportunity to optimize out redundant loop
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: felix.yang at huawei dot com
Target Milestone: ---
inline unsigned int
stringLen(const short* const src)
{
if (src == 0 || *src == 0) {
return 0;
} else {
const short* pszTmp = src + 1;
while (*pszTmp)
++pszTmp;
return (unsigned int)(pszTmp - src);
}
}
extern void bar();
void foo(const short* const str) {
unsigned int len = stringLen(str);
if (!len) {
bar();
}
}
When stringLen is inlined into foo, the else block in stringLen can be
simplified into non-zero, thus eliminating the while loop. This looks like a
tree VRP issue, but this pass does not work as expected for this test case.
$ g++ -S -O2 foo.cpp -fdump-tree-vrp
Consider function foo, value ranges after VRP does not help here:
48
49 .MEM_1: <<< error >>> VARYING
50 str_3(D): const short int * const VARYING
51 _6: short int VARYING
52 str_7: const short int * const [1B, +INF] EQUIVALENCES: { str_3(D) } (1
elements)
53 pszTmp_8: const short int * [1B, +INF] EQUIVALENCES: { pszTmp_10 } (1
elements)
54 pszTmp_9: const short int * const [1B, +INF]
55 pszTmp_10: const short int * const [1B, +INF]
56 _11: short int VARYING
57 pszTmp_12: const short int * [1B, +INF]
58 _13: unsigned int [0, 0]
59 _14: long int VARYING
60 _15: long int [-4611686018427387904, 4611686018427387903]
61 _16: unsigned int VARYING
62 _18: unsigned int [0, 0]
63 pszTmp_19: const short int * [1B, +INF] EQUIVALENCES: { pszTmp_10 } (1
elements)
......
93 <bb 4> [local count: 439750964]:
94 pszTmp_9 = str_3(D) + 2;
95
96 <bb 5> [local count: 3997736055]:
97 # pszTmp_10 = PHI <pszTmp_9(4), pszTmp_12(6)>
98 _11 = *pszTmp_10;
99 if (_11 == 0)
100 goto <bb 7>; [11.00%]
101 else
102 goto <bb 6>; [89.00%]
103
104 <bb 6> [local count: 3557985095]:
105 pszTmp_12 = pszTmp_10 + 2;
106 goto <bb 5>; [100.00%]
107
108 <bb 7> [local count: 439750964]:
109 # pszTmp_8 = PHI <pszTmp_10(5)>
110 _14 = pszTmp_8 - str_3(D);
111 _15 = _14 /[ex] 2;
112 _16 = (unsigned int) _15;
113 if (_16 == 0)
114 goto <bb 8>; [3.91%]
115 else
116 goto <bb 9>; [96.09%]
117
118 <bb 8> [local count: 354334798]:
119 bar ();
120
121 <bb 9> [local count: 1073741824]:
122 return;
Any suggestions to proceed?