https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100228
Bug ID: 100228 Summary: repeated std::atomic<double>::load() misoptimized by x87 peephole Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: aoliva at gcc dot gnu.org Target Milestone: --- Target: i686-pc-linux-gnu compile this with -O2 -mfpmath=387 -mno-sse #include <atomic> int main() { std::atomic<double> a0; std::atomic<double> a1(1.0); a0 = a1.load(); if (a0.load() != a1.load()) __builtin_abort (); } it aborts because the first a1.load() is optimized by sync.md:398: (define_peephole2 [(set (match_operand:DF 0 "memory_operand") (match_operand:DF 1 "any_fp_register_operand")) (set (mem:BLK (scratch:SI)) (unspec:BLK [(mem:BLK (scratch:SI))] UNSPEC_MEMORY_BLOCKAGE)) (set (match_operand:DF 2 "fp_register_operand") (unspec:DF [(match_operand:DI 3 "memory_operand")] UNSPEC_FILD_ATOMIC)) (set (match_operand:DI 4 "memory_operand") (unspec:DI [(match_dup 2)] UNSPEC_FIST_ATOMIC))] "!TARGET_64BIT && peep2_reg_dead_p (4, operands[2]) && rtx_equal_p (XEXP (operands[0], 0), XEXP (operands[3], 0))" [(const_int 0)] { emit_insn (gen_memory_blockage ()); emit_move_insn (gen_lowpart (DFmode, operands[4]), operands[1]); DONE; }) the memory location operands[0] stored into by the first instruction is reused and loaded again in the second a1.load(), but after this peephole, there's no store before the load. I don't think we have infrastructure in peephole to test whether there are any other uses of a store, so I think we have to keep it. There are other variations of this peephole around it, that appear to have the same problem.