Consider the following templates: > (define_insn "movhi" > [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") > (match_operand:HI 1 "general_operand" "i,r,m,r"))] > "" > { > return \"move %1, %0\"; > } > ) > > (define_insn "pushhi_16" > [(set (mem:HI (pre_inc:HI (reg:HI SP_REG))) > (match_operand:HI 0 "general_operand" "rni"))] > "" > "push %0" > ) And the following translation unit (if at all relevant): > volatile int* const e = 0x5; > > void _entry() { > *e = 6 > } My question concerns the code generator behavior when confronted by the following final RTL code; the following snippet is from the prologue, where the `a' register is saved onto the stack: ... (insn 12 4 13 (set (mem/c:HI (pre_inc:HI (reg/f:HI 4 sp)) [2 S2 A8]) (reg:HI 0 a)) test.c:3 1 {movhi} (expr_list:REG_DEAD (reg:HI 0 a) (nil))) (note 13 12 3 NOTE_INSN_PROLOGUE_END) ... >From this, the following (incorrect) code is generated: > "move %a, (%sp)" It is incorrect, as on my machine the %sp register is only incremented with a push or pop instruction. Thus, the correct code should be: > "push %a" My question is, why does the compiler match the above RTL code to my "movhi" template? I have not specified an auto {pre,post} inc/decremented ("<" or ">") operand constraint anywhere in the "movhi" template; thus, surely the template match should fail, if the RTL that is attempted to be matched contains such a *cremented expression? I currently solve this problem by simply defining the "push"/"pop" RTL templates above that of the "movhi", so that they get considered first, however I would much prefer a solid solution that does not depend on the position of code in a file.