https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113907
--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> --- One set of range changes in evrp is more precise ranges in return values of uprv_swapArray{16,32,64}, those contain early return 0 if length<0 || (length&1)!=0 or length<0 || (length&3)!=0 or length<0 || (length&7)!=0 so changing those return ranges from [0, +INF] to [0, 0][4, +INF] (for the second, 2 or 8 instead of 4 for the first/last) seems completely reasonable. And uprv_copyArray{16,32,64} has something very similar, length<0 || (length&{1,3,7})!=0 early exit and length > 0 guarded memcpy. So, even there it is completely reasonable to change - # RANGE [irange] unsigned int [1, 2147483647] MASK 0x7ffffff8 VALUE 0x0 + # RANGE [irange] unsigned int [8, 2147483647] MASK 0x7ffffff8 VALUE 0x0 length.37_10 = (unsigned int) length_25(D); memcpy (outData_26(D), inData_24(D), length.37_10); for the copy and - # RANGE [irange] int32_t [0, +INF] MASK 0x7fffffff VALUE 0x0 + # RANGE [irange] int32_t [0, 0][8, +INF] MASK 0x7fffffff VALUE 0x0 # _12 = PHI <0(4), 0(9), length_25(D)(12)> return _12; for the return, but naturally copyData16 uses 2 instead of 8 and copyData32 4 instead of 8. What seems wrong is that the 8 in the ranges somehow leaks into copyData16 during IPA. IPA-ICF?