yann@1: Date: Fri, 06 Feb 2004 12:35:58 +0900 yann@1: From: SUGIOKA Toshinobu yann@1: Subject: [linux-sh:03150] Re: gcc 3.3 optimisation problem yann@1: To: linux-sh@m17n.org yann@1: Message-Id: <4.2.0.58.J.20040206122503.04fe3058@router.itonet.co.jp> yann@1: List-Help: yann@1: List-Id: linux-sh.m17n.org yann@1: yann@1: At 19:40 03/12/01 +0000, Stuart Menefy wrote: yann@1: >On Sat, 29 Nov 2003 20:19:08 +0900 kkojima@rr.iij4u.or.jp wrote: yann@1: > yann@1: >> Dan Kegel wrote: yann@1: >> > Stuart Menefy wrote: yann@1: >> >> I've just been trying to put together a gcc 3.3.2 based toolchain, and yann@1: >> >> appear to be hitting a gcc optimisation bug. I was just wondering if yann@1: >> >> anyone else had seen anything similar. yann@1: >> >> yann@1: >> >> The problem is seen when building the kernel, in the function yann@1: >> >> root_nfs_parse_addr(). I've extracted this into a small stand alone yann@1: >> >> program which demonstrates the problem. yann@1: >> > yann@1: >> > Excellent work. I haven't seen anything like this (doesn't mean much) yann@1: >> > and the sh-specific optimization bugs in the gcc bug database don't look yann@1: >> > similar. I think you should submit this as a bug report at yann@1: >> > http://gcc.gnu.org/bugzilla/ yann@1: >> > It would be good if you could make your test case call abort() if yann@1: >> > the problem is present, so the test case can be automated. yann@1: >> yann@1: >> Indeed. It'd be very nice to create a gcc PR for this issue. yann@1: > yann@1: >OK, I've done that. PR 13260. yann@1: yann@1: PR 13260 was fixed by amylaar@gcc.gnu.org at 2003-12-04 20:10:29 on mainline(gcc-3.4). yann@1: I have back-ported that patch to gcc-3.3.3 and seems fine for me. yann@1: yann@1: * sh-protos.h (sh_expand_t_scc): Declare. yann@1: * sh.h (PREDICATE_CODES): Add cmpsi_operand. yann@1: * sh.c (cmpsi_operand, sh_expand_t_scc): New functions. yann@1: * sh.md (cmpsi): Use cmpsi_operand. If T_REG is compared to yann@1: something that is not a CONST_INT, copy it into a pseudo register. yann@1: (subc): Fix description of new T value. yann@1: (slt, sgt, sge, sgtu): Don't clobber T after rtl generation is over. yann@1: (sltu, sleu, sgeu): Likewise. yann@1: (seq, sne): Likewise. Use sh_expand_t_scc. yann@1: yann@1: diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh-protos.h gcc-3.3-20040126/gcc/config/sh/sh-protos.h yann@1: --- gcc-3.3-20040126-1/gcc/config/sh/sh-protos.h Tue Jan 13 02:03:24 2004 yann@1: +++ gcc-3.3-20040126/gcc/config/sh/sh-protos.h Fri Jan 30 17:54:04 2004 yann@1: @@ -102,6 +102,7 @@ yann@1: extern int sh_can_redirect_branch PARAMS ((rtx, rtx)); yann@1: extern void sh_expand_unop_v2sf PARAMS ((enum rtx_code, rtx, rtx)); yann@1: extern void sh_expand_binop_v2sf PARAMS ((enum rtx_code, rtx, rtx, rtx)); yann@1: +extern int sh_expand_t_scc (enum rtx_code code, rtx target); yann@1: #ifdef TREE_CODE yann@1: extern void sh_va_start PARAMS ((tree, rtx)); yann@1: extern rtx sh_va_arg PARAMS ((tree, tree)); yann@1: diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh.c gcc-3.3-20040126/gcc/config/sh/sh.c yann@1: --- gcc-3.3-20040126-1/gcc/config/sh/sh.c Thu Jan 15 03:11:36 2004 yann@1: +++ gcc-3.3-20040126/gcc/config/sh/sh.c Fri Jan 30 17:53:58 2004 yann@1: @@ -7870,6 +7870,15 @@ yann@1: return register_operand (op, mode); yann@1: } yann@1: yann@1: +int yann@1: +cmpsi_operand (rtx op, enum machine_mode mode) yann@1: +{ yann@1: + if (GET_CODE (op) == REG && REGNO (op) == T_REG yann@1: + && GET_MODE (op) == SImode) yann@1: + return 1; yann@1: + return arith_operand (op, mode); yann@1: +} yann@1: + yann@1: /* INSN is an sfunc; return the rtx that describes the address used. */ yann@1: static rtx yann@1: extract_sfunc_addr (rtx insn) yann@1: @@ -7917,4 +7926,33 @@ yann@1: abort (); yann@1: } yann@1: yann@1: +int yann@1: +sh_expand_t_scc (enum rtx_code code, rtx target) yann@1: +{ yann@1: + rtx result = target; yann@1: + HOST_WIDE_INT val; yann@1: + yann@1: + if (GET_CODE (sh_compare_op0) != REG || REGNO (sh_compare_op0) != T_REG yann@1: + || GET_CODE (sh_compare_op1) != CONST_INT) yann@1: + return 0; yann@1: + if (GET_CODE (result) != REG) yann@1: + result = gen_reg_rtx (SImode); yann@1: + val = INTVAL (sh_compare_op1); yann@1: + if ((code == EQ && val == 1) || (code == NE && val == 0)) yann@1: + emit_insn (gen_movt (result)); yann@1: + else if ((code == EQ && val == 0) || (code == NE && val == 1)) yann@1: + { yann@1: + emit_insn (gen_rtx_CLOBBER (VOIDmode, result)); yann@1: + emit_insn (gen_subc (result, result, result)); yann@1: + emit_insn (gen_addsi3 (result, result, GEN_INT (1))); yann@1: + } yann@1: + else if (code == EQ || code == NE) yann@1: + emit_insn (gen_move_insn (result, GEN_INT (code == NE))); yann@1: + else yann@1: + return 0; yann@1: + if (result != target) yann@1: + emit_move_insn (target, result); yann@1: + return 1; yann@1: +} yann@1: + yann@1: #include "gt-sh.h" yann@1: diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh.h gcc-3.3-20040126/gcc/config/sh/sh.h yann@1: --- gcc-3.3-20040126-1/gcc/config/sh/sh.h Wed Apr 16 02:06:09 2003 yann@1: +++ gcc-3.3-20040126/gcc/config/sh/sh.h Fri Jan 30 17:53:51 2004 yann@1: @@ -3231,6 +3231,7 @@ yann@1: {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \ yann@1: {"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \ yann@1: {"binary_logical_operator", {AND, IOR, XOR}}, \ yann@1: + {"cmpsi_operand", {SUBREG, REG, CONST_INT}}, \ yann@1: {"commutative_float_operator", {PLUS, MULT}}, \ yann@1: {"equality_comparison_operator", {EQ,NE}}, \ yann@1: {"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \ yann@1: diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh.md gcc-3.3-20040126/gcc/config/sh/sh.md yann@1: --- gcc-3.3-20040126-1/gcc/config/sh/sh.md Tue Jan 13 02:03:25 2004 yann@1: +++ gcc-3.3-20040126/gcc/config/sh/sh.md Fri Jan 30 17:54:20 2004 yann@1: @@ -685,11 +685,14 @@ yann@1: yann@1: (define_expand "cmpsi" yann@1: [(set (reg:SI T_REG) yann@1: - (compare (match_operand:SI 0 "arith_operand" "") yann@1: + (compare (match_operand:SI 0 "cmpsi_operand" "") yann@1: (match_operand:SI 1 "arith_operand" "")))] yann@1: "TARGET_SH1" yann@1: " yann@1: { yann@1: + if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG yann@1: + && GET_CODE (operands[1]) != CONST_INT) yann@1: + operands[0] = copy_to_mode_reg (SImode, operands[0]); yann@1: sh_compare_op0 = operands[0]; yann@1: sh_compare_op1 = operands[1]; yann@1: DONE; yann@1: @@ -1147,7 +1150,9 @@ yann@1: (match_operand:SI 2 "arith_reg_operand" "r")) yann@1: (reg:SI T_REG))) yann@1: (set (reg:SI T_REG) yann@1: - (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))] yann@1: + (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2)) yann@1: + (reg:SI T_REG)) yann@1: + (match_dup 1)))] yann@1: "TARGET_SH1" yann@1: "subc %2,%0" yann@1: [(set_attr "type" "arith")]) yann@1: @@ -7223,6 +7228,10 @@ yann@1: } yann@1: DONE; yann@1: } yann@1: + if (sh_expand_t_scc (EQ, operands[0])) yann@1: + DONE; yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (EQ); yann@1: }") yann@1: yann@1: @@ -7269,6 +7278,8 @@ yann@1: } yann@1: DONE; yann@1: } yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (LT); yann@1: }") yann@1: yann@1: @@ -7371,6 +7382,8 @@ yann@1: } yann@1: DONE; yann@1: } yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (GT); yann@1: }") yann@1: yann@1: @@ -7423,6 +7436,8 @@ yann@1: DONE; yann@1: } yann@1: yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT) yann@1: { yann@1: if (TARGET_IEEE) yann@1: @@ -7462,6 +7477,8 @@ yann@1: sh_compare_op0, sh_compare_op1)); yann@1: DONE; yann@1: } yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (GTU); yann@1: }") yann@1: yann@1: @@ -7486,6 +7503,8 @@ yann@1: sh_compare_op1, sh_compare_op0)); yann@1: DONE; yann@1: } yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (LTU); yann@1: }") yann@1: yann@1: @@ -7515,6 +7534,8 @@ yann@1: yann@1: DONE; yann@1: } yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (LEU); yann@1: }") yann@1: yann@1: @@ -7545,6 +7566,8 @@ yann@1: DONE; yann@1: } yann@1: yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: operands[1] = prepare_scc_operands (GEU); yann@1: }") yann@1: yann@1: @@ -7592,8 +7615,12 @@ yann@1: DONE; yann@1: } yann@1: yann@1: - operands[1] = prepare_scc_operands (EQ); yann@1: - operands[2] = gen_reg_rtx (SImode); yann@1: + if (sh_expand_t_scc (NE, operands[0])) yann@1: + DONE; yann@1: + if (! rtx_equal_function_value_matters) yann@1: + FAIL; yann@1: + operands[1] = prepare_scc_operands (EQ); yann@1: + operands[2] = gen_reg_rtx (SImode); yann@1: }") yann@1: yann@1: (define_expand "sunordered" yann@1: yann@1: ---- yann@1: SUGIOKA Toshinobu yann@1: yann@1: yann@1: yann@1: