https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65689
--- Comment #1 from alalaw01 at gcc dot gnu.org --- Problem stems from parse_input_constraint (in stmt.c): if (reg_class_for_constraint (cn) != NO_REGS || insn_extra_address_constraint (cn)) *allows_reg = true; else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else { /* Otherwise we can't assume anything about the nature of the constraint except that it isn't purely registers. Treat it like "g" and hope for the best. */ *allows_reg = true; *allows_mem = true; } which causes expand_asm_operands to use (reg/f:DI ...), which fails the definition of the S constraint. If instead parse_input_constraint set both allows_reg and allows_mem to false (as it does for e.g. an "i" constraint, via a special-case), expand_asm_operands would follow the register to its definition: (const:DI (plus:DI (symbol_ref:DI ("test") [flags 0x3] <function_decl 0x7fb7c60300 test>) (const_int 4 [0x4]))) (as also happens with -O), which satisfies the S constraint. One solution could be to generalize the special case in parse_input_constraint.