https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86722
--- Comment #2 from Marc Glisse <glisse at gcc dot gnu.org> --- noce_try_cmove has if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode)) && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode))) but the first 3 times we go through there, we give up because if_info->a is (mem/u/c:DF (symbol_ref/u:DI ("*.LC1") [flags 0x2]) [0 S8 A64]) Looking in the dump, I see: (insn 6 15 16 5 (set (reg:DF 88 [ iftmp.0_3 ]) (mem/u/c:DF (symbol_ref/u:DI ("*.LC1") [flags 0x2]) [0 S8 A64])) "e.c":3 130 {*movdf_internal} (expr_list:REG_EQUAL (const_double:DF 0.0 [0x0.0p+0]) (nil))) so if we had looked through the REG_EQUAL to see the constant, things might have worked better. I don't know if we can do that though, since we seem very adverse to anything that looks like constant propagation in RTL. In ce2, we arrive there with registers instead of constants, so we do transform, but without seeing the constant 0 we cannot simplify.