https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96482
Bug ID: 96482 Summary: Combination of -finline-small-functions and ipa-cp optimisations causes incorrect values being passed to a function Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: yevh.kolesnikov at gmail dot com Target Milestone: --- The bug was originally reported in mesa: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3239 Combination of LTO and O3 caused a crash on replaying a video with mpv. Backtrace showed pretty unrealistic values passed to a function. I reduced a number of necessary optimisations to: + -O1 + -finline-small-functions + -fipa-bit-cp + -fipa-cp + LTO It happens with gcc 10.1.0, but not with gcc 9. I bisected the problem to c7ac9a0c7e3916f192ad41227e16238fd1fa2fbf. I wasn't able to produce a minimal reproducer, and even though a preprocessed file doesn't trigger the bug for me (I assume, LTO is essential for this bug), I'm attaching it anyway. Looking at the produced assembler, though, shows that it goes wrong somewhere around a call to addr_to_index at https://gitlab.freedesktop.org/mesa/mesa/-/blob/7f25f1f106728f0046672adf9c9ed79185265ea5/src/compiler/nir/nir_lower_io.c#L870. addr_to_index gets inlined and so is nir_channel, called from it. Those two are pretty simple functions: static nir_ssa_def * addr_to_index(nir_builder *b, nir_ssa_def *addr, nir_address_format addr_format) { if (addr_format == nir_address_format_32bit_index_offset) { assert(addr->num_components == 2); return nir_channel(b, addr, 0); } else if (addr_format == nir_address_format_vec2_index_32bit_offset) { assert(addr->num_components == 3); return nir_channels(b, addr, 0x3); } else { unreachable("bad address format for index"); } } static inline nir_ssa_def * nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) { return nir_swizzle(b, def, &c, 1); } In the final assembly we end up with just a call to nir_swizzle: mov edx,r14d mov rsi,r15 mov rdi,rbp call 0x7fffd26e0ef9 <nir_swizzle(nir_builder*, nir_ssa_def*, unsigned int const*, unsigned int) However, edx, rsi, and rdi contain values, that clearly were ment to the original addr_to_index function.