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?