Hello, It seems that splitting multi-word insns before reload results in slightly better code on average (according to CSiBE). The attached patch implements that. Tested on rev. 204263 with make -k -j4 check RUNTESTFLAGS="--target_board=sh-sim \{-m2/-ml,-m2/-mb,-m2a/-mb,-m2a-single/-mb,-m4/-ml,-m4/-mb,-m4-single/ -ml,-m4-single/-mb,-m4a-single/-ml,-m4a-single/-mb}"
and no new failures. However, as far as I recall there have been some issues with this in the past, I just can't find/remember what it was exactly. Kaz, could you please run it through your test setup, too and let me know if it's OK for trunk? Thanks, Oleg gcc/ChangeLog: * config/sh/sh.md (adddi3): Remove empty constraints. Remove can_create_pseudo_p and arith_reg_operand check. (adddi3_compact, subdi3_compact, *negdi2): Remove constraints, split before reload.
Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 204263) +++ gcc/config/sh/sh.md (working copy) @@ -1747,15 +1747,13 @@ ;; ------------------------------------------------------------------------- (define_expand "adddi3" - [(set (match_operand:DI 0 "arith_reg_operand" "") - (plus:DI (match_operand:DI 1 "arith_reg_operand" "") - (match_operand:DI 2 "arith_operand" "")))] + [(set (match_operand:DI 0 "arith_reg_operand") + (plus:DI (match_operand:DI 1 "arith_reg_operand") + (match_operand:DI 2 "arith_operand")))] "" { if (TARGET_SH1) { - if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode)) - FAIL; operands[2] = force_reg (DImode, operands[2]); emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2])); DONE; @@ -1794,22 +1792,22 @@ (set_attr "highpart" "ignore")]) (define_insn_and_split "adddi3_compact" - [(set (match_operand:DI 0 "arith_reg_dest" "=&r") - (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0") - (match_operand:DI 2 "arith_reg_operand" "r"))) + [(set (match_operand:DI 0 "arith_reg_dest") + (plus:DI (match_operand:DI 1 "arith_reg_operand") + (match_operand:DI 2 "arith_reg_operand"))) (clobber (reg:SI T_REG))] "TARGET_SH1" "#" - "&& reload_completed" + "&& can_create_pseudo_p ()" [(const_int 0)] { - rtx high0 = gen_highpart (SImode, operands[0]); - rtx high2 = gen_highpart (SImode, operands[2]); - rtx low0 = gen_lowpart (SImode, operands[0]); - emit_insn (gen_clrt ()); - emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2]))); - emit_insn (gen_addc (high0, high0, high2)); + emit_insn (gen_addc (gen_lowpart (SImode, operands[0]), + gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))); + emit_insn (gen_addc (gen_highpart (SImode, operands[0]), + gen_highpart (SImode, operands[1]), + gen_highpart (SImode, operands[2]))); DONE; }) @@ -2108,22 +2106,22 @@ (set_attr "highpart" "ignore")]) (define_insn_and_split "subdi3_compact" - [(set (match_operand:DI 0 "arith_reg_dest" "=&r") - (minus:DI (match_operand:DI 1 "arith_reg_operand" "0") - (match_operand:DI 2 "arith_reg_operand" "r"))) + [(set (match_operand:DI 0 "arith_reg_dest") + (minus:DI (match_operand:DI 1 "arith_reg_operand") + (match_operand:DI 2 "arith_reg_operand"))) (clobber (reg:SI T_REG))] "TARGET_SH1" "#" - "&& reload_completed" + "&& can_create_pseudo_p ()" [(const_int 0)] { - rtx high0 = gen_highpart (SImode, operands[0]); - rtx high2 = gen_highpart (SImode, operands[2]); - rtx low0 = gen_lowpart (SImode, operands[0]); - emit_insn (gen_clrt ()); - emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2]))); - emit_insn (gen_subc (high0, high0, high2)); + emit_insn (gen_subc (gen_lowpart (SImode, operands[0]), + gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))); + emit_insn (gen_subc (gen_highpart (SImode, operands[0]), + gen_highpart (SImode, operands[1]), + gen_highpart (SImode, operands[2]))); DONE; }) @@ -5567,8 +5565,8 @@ "sub r63, %1, %0" [(set_attr "type" "arith_media")]) -;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be -;; combined. +;; Don't split into individual negc insns immediately so that neg:DI (abs:DI) +;; can be combined. (define_expand "negdi2" [(parallel [(set (match_operand:DI 0 "arith_reg_dest") (neg:DI (match_operand:DI 1 "arith_reg_operand"))) @@ -5576,12 +5574,12 @@ "TARGET_SH1") (define_insn_and_split "*negdi2" - [(set (match_operand:DI 0 "arith_reg_dest" "=&r") - (neg:DI (match_operand:DI 1 "arith_reg_operand" "r"))) + [(set (match_operand:DI 0 "arith_reg_dest") + (neg:DI (match_operand:DI 1 "arith_reg_operand"))) (clobber (reg:SI T_REG))] "TARGET_SH1" "#" - "&& reload_completed" + "&& can_create_pseudo_p ()" [(const_int 0)] { emit_insn (gen_clrt ());