Thanks all for your comments. Posting my comments for posterity. I defined a define_insn pattern as follows and it worked well for me : (define_insn "testnew36" [(set (match_operand:DI 0 "register_operand" "=d") (op3:DI (op2:DI (op1:DI (match_operand:DI 1 "register_operand" "") (match_operand:SI 2 "immediate_operand" "")) (match_operand:DI 3 "register_operand" ""))))] "TARGET_MYCORE" "testnew36" [(set_attr "mode" "DI") (set_attr "length" "4")]) I am working on a clean way to update the rtx_costs this still. But once the insn costs are in place (I somewhat put a dirty hack for now), GCC's combine pass does fuse these ops for me. There are a few cases where the combine pass falters with suboptimal patterns. The case is when (I think) GCC thinks that the result of op1 +op2 combination is required for a latter insn : (parallel [ (set (reg:DI 256 [ *_15 ]) (op3:DI (op2:DI (op1:DI (reg:DI 202 [ D.1563 ]) (const_int 4 [0x4])) (reg/v/f:DI 242 [ inbuf ])) [0 *_15+0 S4 A32])) (set (reg/f:DI 205 [ D.1566 ]) (op2:DI (op1:DI (reg:DI 202 [ D.1563 ]) (const_int 4 [0x4])) (reg/v/f:DI 242 [ inbuf ]))) ]) The second set insn in the above parallel expression can be combined with another define_insn pattern that can fuse op1, op2 and "op4" to a new insn "testnew40". Is there a way to accomplish this ? When does the combine pass create these parallel expressions ? To be clear, I have two define_insn patterns at the moment : 1. testnew36 (fuses op1, op2, and op3) 2. testnew40 (fuses op1, op2, and op4) So a stream of insns like below : ... op1 ... op2 (consumes result of op1) ... op3 (consumes result of op2) ... op4 (consumes result of op2) ... gets translated to : ... testnew36 ... testnew40 On Tue, Aug 5, 2014 at 10:51 PM, Marc Glisse <marc.glisse@xxxxxxxx> wrote: > On Tue, 5 Aug 2014, Cherry Vanc wrote: > >> Thanks. I am now using a define_insn based on your inputs : >> >> (define_insn "testnew36" >> [(set (match_operand:DI 0 "register_operand" "") >> (op1:DI (match_operand:DI 1 "register_operand" "") >> (match_operand:SI 2 "immediate_operand" "") )) >> (set (match_operand:DI 3 "register_operand" "") >> (op2:DI (match_operand:DI 4 "register_operand" "") (match_dup 0))) >> (set (match_operand:DI 5 "register_operand" "") >> (sign_extend:DI (op3:SI (match_dup 3))))] >> "TARGET_MYCORE" >> "testnew 36" >> [(set_attr "mode" "DI")]) > > > Er, no, that's not what was recommended. Your *testnew in the previous email > was much better. > > >> Why doesnt -fdump-rtl-all-all / -fdump-rtl-all generate those .life >> and .combine files so that I can take a look at the combine pass is >> doing ? dump-rtl-combine doesnt spit anything either. MYCORE is a mips >> adaptation using GCC 4.9.0. > > > Are you sure compiling file.c with options -O -da (or any of the options you > tried) doesn't create file.c.201r.combine (number can vary)? You'll need to > debug that first then. > > -- > Marc Glisse