https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95803
Bug ID: 95803 Summary: Failure to optimize strlen in certain situations properly, instead leading to weird code Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: gabravier at gmail dot com Target Milestone: --- bool f(int i) { if (i < 4) i = 4; const char *s = &"abc"[i]; return strlen(s) > 3; } This can be optimized to a simple `return true` or `return false` (considering UB is invoked here). LLVM does this transformation, but GCC does not. Obviously this code is pretty weird and may not be very realistic itself, but this optimization would probably be effective for other code, and currently it results in rather weird code generation : f(int): mov ecx, 4 cmp edi, 4 mov eax, 3 mov edx, ecx cmovge edx, edi movsx rdx, edx sub rax, rdx cmp rdx, 3 mov edx, 0 cmova rax, rdx cmp rax, 3 seta al ret accompanied by very weird final tree optimized code : ;; Function f (_Z1fi, funcdef_no=287, decl_uid=9588, cgraph_uid=216, symbol_order=215) f (int i) { const char * s; long unsigned int _1; int _3; bool _6; sizetype _7; <bb 2> [local count: 1073741824]: # DEBUG BEGIN_STMT _3 = MAX_EXPR <i_2(D), 4>; # DEBUG i => _3 # DEBUG BEGIN_STMT _7 = (sizetype) _3; s_4 = "abc" + _7; # DEBUG s => s_4 # DEBUG BEGIN_STMT _1 = __builtin_strlen (s_4); _6 = _1 > 3; return _6; } Whereas this code : bool f(int i) { if (i < 4) i = 4; return strlen(&"abc"[i]) > 3; } Optimizes to this : ;; Function f (_Z1fi, funcdef_no=287, decl_uid=9588, cgraph_uid=216, symbol_order=215) f (int i) { <bb 2> [local count: 1073741824]: # DEBUG BEGIN_STMT # DEBUG i => NULL # DEBUG BEGIN_STMT return 0; }