From 3db1b4348632d87e6a372ffc19a1b533b5a78a3a Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Thu, 4 Dec 2003 20:10:29 +0000 Subject: [PATCH] re PR rtl-optimization/13260 (Incorrect optimisation of loop termination condition) PR optimization/13260 * sh-protos.h (sh_expand_t_scc): Declare. * sh.h (PREDICATE_CODES): Add cmpsi_operand. * sh.c (cmpsi_operand, sh_expand_t_scc): New functions. * sh.md (cmpsi): Use cmpsi_operand. If T_REG is compared to something that is not a CONST_INT, copy it into a pseudo register. (subc): Fix description of new T value. (slt, sgt, sge, sgtu): Don't clobber T after rtl generation is over. (sltu, sleu, sgeu): Likewise. (seq, sne): Likewise. Use sh_expand_t_scc. From-SVN: r74294 --- gcc/ChangeLog | 13 +++++++++++++ gcc/config/sh/sh-protos.h | 1 + gcc/config/sh/sh.c | 38 ++++++++++++++++++++++++++++++++++++++ gcc/config/sh/sh.h | 1 + gcc/config/sh/sh.md | 35 +++++++++++++++++++++++++++++++---- 5 files changed, 84 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f339b8c0586..8cd28e7e682 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2003-12-04 J"orn Rennecke + + PR optimization/13260 + * sh-protos.h (sh_expand_t_scc): Declare. + * sh.h (PREDICATE_CODES): Add cmpsi_operand. + * sh.c (cmpsi_operand, sh_expand_t_scc): New functions. + * sh.md (cmpsi): Use cmpsi_operand. If T_REG is compared to + something that is not a CONST_INT, copy it into a pseudo register. + (subc): Fix description of new T value. + (slt, sgt, sge, sgtu): Don't clobber T after rtl generation is over. + (sltu, sleu, sgeu): Likewise. + (seq, sne): Likewise. Use sh_expand_t_scc. + 2003-12-04 Nathanael Nerode * configure.in: Generalize the CONFIG_HEADERS pattern under which diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 008d4bcd62f..ec723bda127 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -97,6 +97,7 @@ extern int sh_insn_length_adjustment (rtx); extern int sh_can_redirect_branch (rtx, rtx); extern void sh_expand_unop_v2sf (enum rtx_code, rtx, rtx); extern void sh_expand_binop_v2sf (enum rtx_code, rtx, rtx, rtx); +extern int sh_expand_t_scc (enum rtx_code code, rtx target); #ifdef TREE_CODE extern void sh_va_start (tree, rtx); extern rtx sh_va_arg (tree, tree); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 52f9500aae4..186372ff73f 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -8898,6 +8898,15 @@ sh_register_operand (rtx op, enum machine_mode mode) return register_operand (op, mode); } +int +cmpsi_operand (rtx op, enum machine_mode mode) +{ + if (GET_CODE (op) == REG && REGNO (op) == T_REG + && GET_MODE (op) == SImode) + return 1; + return arith_operand (op, mode); +} + static rtx emit_load_ptr (rtx, rtx); static rtx @@ -9129,4 +9138,33 @@ sh_get_pr_initial_val (void) return val; } +int +sh_expand_t_scc (enum rtx_code code, rtx target) +{ + rtx result = target; + HOST_WIDE_INT val; + + if (GET_CODE (sh_compare_op0) != REG || REGNO (sh_compare_op0) != T_REG + || GET_CODE (sh_compare_op1) != CONST_INT) + return 0; + if (GET_CODE (result) != REG) + result = gen_reg_rtx (SImode); + val = INTVAL (sh_compare_op1); + if ((code == EQ && val == 1) || (code == NE && val == 0)) + emit_insn (gen_movt (result)); + else if ((code == EQ && val == 0) || (code == NE && val == 1)) + { + emit_insn (gen_rtx_CLOBBER (VOIDmode, result)); + emit_insn (gen_subc (result, result, result)); + emit_insn (gen_addsi3 (result, result, GEN_INT (1))); + } + else if (code == EQ || code == NE) + emit_insn (gen_move_insn (result, GEN_INT (code == NE))); + else + return 0; + if (result != target) + emit_move_insn (target, result); + return 1; +} + #include "gt-sh.h" diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 581f7efb9ce..e79f6c1a277 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -3145,6 +3145,7 @@ extern int rtx_equal_function_value_matters; {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \ {"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \ {"binary_logical_operator", {AND, IOR, XOR}}, \ + {"cmpsi_operand", {SUBREG, REG, CONST_INT}}, \ {"commutative_float_operator", {PLUS, MULT}}, \ {"equality_comparison_operator", {EQ,NE}}, \ {"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \ diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 228d4e5336f..aa63209dbf6 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -705,11 +705,14 @@ (define_expand "cmpsi" [(set (reg:SI T_REG) - (compare (match_operand:SI 0 "arith_operand" "") + (compare (match_operand:SI 0 "cmpsi_operand" "") (match_operand:SI 1 "arith_operand" "")))] "TARGET_SH1" " { + if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG + && GET_CODE (operands[1]) != CONST_INT) + operands[0] = copy_to_mode_reg (SImode, operands[0]); sh_compare_op0 = operands[0]; sh_compare_op1 = operands[1]; DONE; @@ -1167,7 +1170,9 @@ (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (set (reg:SI T_REG) - (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))] + (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2)) + (reg:SI T_REG)) + (match_dup 1)))] "TARGET_SH1" "subc %2,%0" [(set_attr "type" "arith")]) @@ -7446,6 +7451,10 @@ mov.l\\t1f,r0\\n\\ } DONE; } + if (sh_expand_t_scc (EQ, operands[0])) + DONE; + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (EQ); }") @@ -7492,6 +7501,8 @@ mov.l\\t1f,r0\\n\\ } DONE; } + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (LT); }") @@ -7594,6 +7605,8 @@ mov.l\\t1f,r0\\n\\ } DONE; } + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (GT); }") @@ -7646,6 +7659,8 @@ mov.l\\t1f,r0\\n\\ DONE; } + if (! rtx_equal_function_value_matters) + FAIL; if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT) { if (TARGET_IEEE) @@ -7685,6 +7700,8 @@ mov.l\\t1f,r0\\n\\ sh_compare_op0, sh_compare_op1)); DONE; } + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (GTU); }") @@ -7709,6 +7726,8 @@ mov.l\\t1f,r0\\n\\ sh_compare_op1, sh_compare_op0)); DONE; } + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (LTU); }") @@ -7738,6 +7757,8 @@ mov.l\\t1f,r0\\n\\ DONE; } + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (LEU); }") @@ -7768,6 +7789,8 @@ mov.l\\t1f,r0\\n\\ DONE; } + if (! rtx_equal_function_value_matters) + FAIL; operands[1] = prepare_scc_operands (GEU); }") @@ -7815,8 +7838,12 @@ mov.l\\t1f,r0\\n\\ DONE; } - operands[1] = prepare_scc_operands (EQ); - operands[2] = gen_reg_rtx (SImode); + if (sh_expand_t_scc (NE, operands[0])) + DONE; + if (! rtx_equal_function_value_matters) + FAIL; + operands[1] = prepare_scc_operands (EQ); + operands[2] = gen_reg_rtx (SImode); }") (define_expand "sunordered"