The problem here is that -ffast-math is overridden when switching optimization options on a per function basis with __attribute__((optimize("O"))). The x86 ceilf* instructions depend on unsafe math optimizations, but the optabs are created at the beginning of the compilation. When fast math becomes unavailable, the target can no longer find the instructions. Fixed by recalculating the optabs when creating new optimization nodes, and switching to these (if appropriate) at cfun switching time. How does this look? Jakub, what's this you mention in the PR about caching __optimize__((3))? You also mention I shouldn't compare against this_target_optabs, but default_target_optabs. But what if this_target_optabs has changed? (See patch). Tested on x86-64 Linux. It would be nice if someone with access to a SWITCHABLE_TARGET platform (mips) could also test this.