https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107986
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |85316 CC| |aldyh at gcc dot gnu.org Keywords| |missed-optimization --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- One of the reasons we diagnose this is that we fail to compute a range for 'qa_7'. Before the VRP pass that diagnoses the -Warray-bounds violation we have <bb 6> [local count: 1073741824]: # qa_7 = PHI <0(2), qa_6(5)> # RANGE [irange] int [0, 3] NONZERO 0x3 # i_8 = PHI <0(2), i_16(5)> if (i_8 != 3) goto <bb 3>; [75.00%] else goto <bb 7>; [25.00%] <bb 7> [local count: 268435456]: # RANGE [irange] long unsigned int [0, 2147483647][18446744071562067968, +INF] _3 = (long unsigned int) qa_7; # RANGE [irange] long unsigned int [0, 8589934588][18446744065119617024, 18446744073709551612] NONZERO 0xfffffffffffffffc _4 = _3 * 4; # PT = { D.18799 } (escaped) # ALIGN = 4, MISALIGN = 0 _5 = &a + _4; if (&a != _5) goto <bb 8>; [53.47%] else goto <bb 17>; [46.53%] <bb 8> [local count: 143532440]: _11 = (signed long) _4; # RANGE [irange] long int [-2305843009213693952, 2305843009213693951] _20 = _11 /[ex] 4; # RANGE [irange] long unsigned int [0, 2305843009213693951][16140901064495857664, +INF] __n.3_21 = (long unsigned int) _20; # RANGE [irange] int [0, 63] NONZERO 0x3f _22 = __builtin_clzl (__n.3_21); # RANGE [irange] int [0, 63] NONZERO 0x3f _23 = 63 - _22; # RANGE [irange] long int [0, 63] NONZERO 0x3f _24 = (long int) _23; # RANGE [irange] long int [0, 126] NONZERO 0x7e _25 = _24 * 2; # USE = nonlocal escaped null { D.18799 } (escaped) # CLB = nonlocal escaped null { D.18799 } (escaped) std::__introsort_loop.isra (&a, _5, _25); if (_11 > 64) goto <bb 9>; [50.00%] else goto <bb 15>; [50.00%] and we fail to eliminate this last conditional. We also fail to eliminate the (long)(((unsigned long)qa_37) * 4) /[ex] 4 round-trip (because of possible overflow). So even proving qa_7 is [0, +INF] would help a bit (not the diagnostic), realizing qa_7 is [0, 3] like i_8 would be even better. A testcase for this could look like void bar (); void foo (int *a) { int qa = 0; for (int i = 0; i < 3; i++) if (a[i]) a[qa++] = 0; if (qa > 3) bar (); } where we should be able to eliminate the call to bar (). Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85316 [Bug 85316] [meta-bug] VRP range propagation missed cases