Hello! As suggested by Richard S. [1], after the patch that converts subreg:M (op:N (...)(...)) to op:M (subreg:M (...) subreg:M (...)), we can remove several peephole2 patterns that handle subregs of PLUS, MINUS and MULT operators. I have attached RFC prototype patch that will trigger an ICE when to-be-removed pattern triggers, with the intention that these patterns wil be removed entirely (An "invalid" pattern was indeed generated elsewhere, see patch).
2012-10-18 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (ashift to lea splitter): Split to SImode mult. (simple lea to add/shift peephole2s): Remove peephole2s that operate on subregs of DImode operations. (*mov<mode>_insv_1_rex64): Use gen_int_mode to truncate const_int RTX to QImode value. (*movsi_insv_1): Ditto. The patch was bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32} without problems, but I will ask H.J. to test the patch on x32 before it is committed to mainline SVN. [1] http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01856.html Uros.
Index: i386.md =================================================================== --- i386.md (revision 192873) +++ i386.md (working copy) @@ -2704,7 +2704,8 @@ "TARGET_64BIT" { if (CONST_INT_P (operands[1])) - operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0); + operands[1] = gen_int_mode (INTVAL (operands[1]), QImode); + return "mov{b}\t{%b1, %h0|%h0, %b1}"; } [(set_attr "type" "imov") @@ -2718,7 +2719,8 @@ "!TARGET_64BIT" { if (CONST_INT_P (operands[1])) - operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0); + operands[1] = gen_int_mode (INTVAL (operands[1]), QImode); + return "mov{b}\t{%b1, %h0|%h0, %b1}"; } [(set_attr "type" "imov") @@ -9600,10 +9602,10 @@ "TARGET_64BIT && reload_completed && true_regnum (operands[0]) != true_regnum (operands[1])" [(set (match_dup 0) - (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))] + (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))] { - operands[1] = gen_lowpart (DImode, operands[1]); - operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode); }) ;; This pattern can't accept a variable shift count, since shifts by @@ -17366,7 +17368,7 @@ && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[2] = gen_lowpart (SImode, operands[2]);") + "gcc_unreachable ();") (define_peephole2 [(set (match_operand:SI 0 "register_operand") @@ -17377,7 +17379,7 @@ && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) (clobber (reg:CC FLAGS_REG))])] - "operands[1] = gen_lowpart (SImode, operands[1]);") + "gcc_unreachable ();") (define_peephole2 [(set (match_operand:DI 0 "register_operand") @@ -17413,10 +17415,7 @@ [(parallel [(set (match_dup 0) (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))])] -{ - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_lowpart (SImode, operands[0]); -}) + "gcc_unreachable ();") (define_peephole2 [(set (match_operand:DI 0 "register_operand") @@ -17428,10 +17427,7 @@ [(parallel [(set (match_dup 0) (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))])] -{ - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_lowpart (SImode, operands[0]); -}) + "gcc_unreachable ();") (define_peephole2 [(set (match_operand:SWI48 0 "register_operand") @@ -17453,7 +17449,7 @@ && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") + "gcc_unreachable ();") (define_peephole2 [(set (match_operand:DI 0 "register_operand") @@ -17480,10 +17476,7 @@ [(parallel [(set (match_dup 0) (zero_extend:DI (ashift:SI (match_dup 2) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))])] -{ - operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1]))); - operands[2] = gen_lowpart (SImode, operands[0]); -}) + "gcc_unreachable ();") ;; The ESP adjustments can be done by the push and pop instructions. Resulting ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.