I have a target that supports a "push.b x" operation that puts a byte onto the stack but pre-decrements the stack pointer by 2 to maintain alignment.
I have a machine description that includes these two defines: (define_insn "*pushqi_pre_mod" [(set (mem:QI (pre_modify:HI (reg:HI 1) (plus:HI (reg:HI 1) (const_int -2)))) (match_operand:QI 0 "general_operand" "rim"))] "" "* return msp430_pushqi(insn, operands);" [(set_attr "length" "2")]) (define_insn "*pushqi" [(set (match_operand:QI 1 "push_operand" "=<") (match_operand:QI 0 "general_operand" "rim"))] "" "* return msp430_pushqi(insn, operands);" [(set_attr "length" "2")]) I'd hoped to clean this up by removing the apparently redundant first definition. I have a test program which normally works fine, but if I comment out the first define produces: movqi.c: In function ‘pushqi_r’: movqi.c:33:1: error: unable to generate reloads for: (insn 6 3 7 2 movqi.c:33 (set (mem/i:QI (pre_modify:HI (reg/f:HI 1 r1) (plus:HI (reg/f:HI 1 r1) (const_int -2 [0xfffffffe]))) [0 S1 A8]) (reg:QI 15 r15 [ p ])) 13 {*pushqi} (expr_list:REG_DEAD (reg:QI 15 r15 [ p ]) (nil))) movqi.c:33:1: internal compiler error: in find_reloads, at reload.c:3821 Instrumentation shows that push_operand succeeds, but the '<' constraint fails, as the mem operand with pre_modify does not pass that test (nor does it pass 'g' or 'm'; only 'X'). I've discovered HAVE_PRE_MODIFY_DISP which, based on its one-sentence description, appears to be relevant as I'm changing the stack pointer by 2 though the operand size is 1. But it seems to have no effect, nor does HAVE_PRE_MODIFY_REG. Is there a better alternative to make this work than either leaving the extra instruction in, or replacing the "=<" constraint with "=X"? Does the latter have consequences that I should expect to regret? Peter