yann@1
|
1 |
Date: Fri, 06 Feb 2004 12:35:58 +0900
|
yann@1
|
2 |
From: SUGIOKA Toshinobu <sugioka@itonet.co.jp>
|
yann@1
|
3 |
Subject: [linux-sh:03150] Re: gcc 3.3 optimisation problem
|
yann@1
|
4 |
To: linux-sh@m17n.org
|
yann@1
|
5 |
Message-Id: <4.2.0.58.J.20040206122503.04fe3058@router.itonet.co.jp>
|
yann@1
|
6 |
List-Help: <mailto:linux-sh-ctl@m17n.org?body=help>
|
yann@1
|
7 |
List-Id: linux-sh.m17n.org
|
yann@1
|
8 |
|
yann@1
|
9 |
At 19:40 03/12/01 +0000, Stuart Menefy <stuart.menefy@st.com> wrote:
|
yann@1
|
10 |
>On Sat, 29 Nov 2003 20:19:08 +0900 kkojima@rr.iij4u.or.jp wrote:
|
yann@1
|
11 |
>
|
yann@1
|
12 |
>> Dan Kegel <dank@kegel.com> wrote:
|
yann@1
|
13 |
>> > Stuart Menefy wrote:
|
yann@1
|
14 |
>> >> I've just been trying to put together a gcc 3.3.2 based toolchain, and
|
yann@1
|
15 |
>> >> appear to be hitting a gcc optimisation bug. I was just wondering if
|
yann@1
|
16 |
>> >> anyone else had seen anything similar.
|
yann@1
|
17 |
>> >>
|
yann@1
|
18 |
>> >> The problem is seen when building the kernel, in the function
|
yann@1
|
19 |
>> >> root_nfs_parse_addr(). I've extracted this into a small stand alone
|
yann@1
|
20 |
>> >> program which demonstrates the problem.
|
yann@1
|
21 |
>> >
|
yann@1
|
22 |
>> > Excellent work. I haven't seen anything like this (doesn't mean much)
|
yann@1
|
23 |
>> > and the sh-specific optimization bugs in the gcc bug database don't look
|
yann@1
|
24 |
>> > similar. I think you should submit this as a bug report at
|
yann@1
|
25 |
>> > http://gcc.gnu.org/bugzilla/
|
yann@1
|
26 |
>> > It would be good if you could make your test case call abort() if
|
yann@1
|
27 |
>> > the problem is present, so the test case can be automated.
|
yann@1
|
28 |
>>
|
yann@1
|
29 |
>> Indeed. It'd be very nice to create a gcc PR for this issue.
|
yann@1
|
30 |
>
|
yann@1
|
31 |
>OK, I've done that. PR 13260.
|
yann@1
|
32 |
|
yann@1
|
33 |
PR 13260 was fixed by amylaar@gcc.gnu.org at 2003-12-04 20:10:29 on mainline(gcc-3.4).
|
yann@1
|
34 |
I have back-ported that patch to gcc-3.3.3 and seems fine for me.
|
yann@1
|
35 |
|
yann@1
|
36 |
* sh-protos.h (sh_expand_t_scc): Declare.
|
yann@1
|
37 |
* sh.h (PREDICATE_CODES): Add cmpsi_operand.
|
yann@1
|
38 |
* sh.c (cmpsi_operand, sh_expand_t_scc): New functions.
|
yann@1
|
39 |
* sh.md (cmpsi): Use cmpsi_operand. If T_REG is compared to
|
yann@1
|
40 |
something that is not a CONST_INT, copy it into a pseudo register.
|
yann@1
|
41 |
(subc): Fix description of new T value.
|
yann@1
|
42 |
(slt, sgt, sge, sgtu): Don't clobber T after rtl generation is over.
|
yann@1
|
43 |
(sltu, sleu, sgeu): Likewise.
|
yann@1
|
44 |
(seq, sne): Likewise. Use sh_expand_t_scc.
|
yann@1
|
45 |
|
yann@1
|
46 |
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
|
47 |
--- gcc-3.3-20040126-1/gcc/config/sh/sh-protos.h Tue Jan 13 02:03:24 2004
|
yann@1
|
48 |
+++ gcc-3.3-20040126/gcc/config/sh/sh-protos.h Fri Jan 30 17:54:04 2004
|
yann@1
|
49 |
@@ -102,6 +102,7 @@
|
yann@1
|
50 |
extern int sh_can_redirect_branch PARAMS ((rtx, rtx));
|
yann@1
|
51 |
extern void sh_expand_unop_v2sf PARAMS ((enum rtx_code, rtx, rtx));
|
yann@1
|
52 |
extern void sh_expand_binop_v2sf PARAMS ((enum rtx_code, rtx, rtx, rtx));
|
yann@1
|
53 |
+extern int sh_expand_t_scc (enum rtx_code code, rtx target);
|
yann@1
|
54 |
#ifdef TREE_CODE
|
yann@1
|
55 |
extern void sh_va_start PARAMS ((tree, rtx));
|
yann@1
|
56 |
extern rtx sh_va_arg PARAMS ((tree, tree));
|
yann@1
|
57 |
diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh.c gcc-3.3-20040126/gcc/config/sh/sh.c
|
yann@1
|
58 |
--- gcc-3.3-20040126-1/gcc/config/sh/sh.c Thu Jan 15 03:11:36 2004
|
yann@1
|
59 |
+++ gcc-3.3-20040126/gcc/config/sh/sh.c Fri Jan 30 17:53:58 2004
|
yann@1
|
60 |
@@ -7870,6 +7870,15 @@
|
yann@1
|
61 |
return register_operand (op, mode);
|
yann@1
|
62 |
}
|
yann@1
|
63 |
|
yann@1
|
64 |
+int
|
yann@1
|
65 |
+cmpsi_operand (rtx op, enum machine_mode mode)
|
yann@1
|
66 |
+{
|
yann@1
|
67 |
+ if (GET_CODE (op) == REG && REGNO (op) == T_REG
|
yann@1
|
68 |
+ && GET_MODE (op) == SImode)
|
yann@1
|
69 |
+ return 1;
|
yann@1
|
70 |
+ return arith_operand (op, mode);
|
yann@1
|
71 |
+}
|
yann@1
|
72 |
+
|
yann@1
|
73 |
/* INSN is an sfunc; return the rtx that describes the address used. */
|
yann@1
|
74 |
static rtx
|
yann@1
|
75 |
extract_sfunc_addr (rtx insn)
|
yann@1
|
76 |
@@ -7917,4 +7926,33 @@
|
yann@1
|
77 |
abort ();
|
yann@1
|
78 |
}
|
yann@1
|
79 |
|
yann@1
|
80 |
+int
|
yann@1
|
81 |
+sh_expand_t_scc (enum rtx_code code, rtx target)
|
yann@1
|
82 |
+{
|
yann@1
|
83 |
+ rtx result = target;
|
yann@1
|
84 |
+ HOST_WIDE_INT val;
|
yann@1
|
85 |
+
|
yann@1
|
86 |
+ if (GET_CODE (sh_compare_op0) != REG || REGNO (sh_compare_op0) != T_REG
|
yann@1
|
87 |
+ || GET_CODE (sh_compare_op1) != CONST_INT)
|
yann@1
|
88 |
+ return 0;
|
yann@1
|
89 |
+ if (GET_CODE (result) != REG)
|
yann@1
|
90 |
+ result = gen_reg_rtx (SImode);
|
yann@1
|
91 |
+ val = INTVAL (sh_compare_op1);
|
yann@1
|
92 |
+ if ((code == EQ && val == 1) || (code == NE && val == 0))
|
yann@1
|
93 |
+ emit_insn (gen_movt (result));
|
yann@1
|
94 |
+ else if ((code == EQ && val == 0) || (code == NE && val == 1))
|
yann@1
|
95 |
+ {
|
yann@1
|
96 |
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
|
yann@1
|
97 |
+ emit_insn (gen_subc (result, result, result));
|
yann@1
|
98 |
+ emit_insn (gen_addsi3 (result, result, GEN_INT (1)));
|
yann@1
|
99 |
+ }
|
yann@1
|
100 |
+ else if (code == EQ || code == NE)
|
yann@1
|
101 |
+ emit_insn (gen_move_insn (result, GEN_INT (code == NE)));
|
yann@1
|
102 |
+ else
|
yann@1
|
103 |
+ return 0;
|
yann@1
|
104 |
+ if (result != target)
|
yann@1
|
105 |
+ emit_move_insn (target, result);
|
yann@1
|
106 |
+ return 1;
|
yann@1
|
107 |
+}
|
yann@1
|
108 |
+
|
yann@1
|
109 |
#include "gt-sh.h"
|
yann@1
|
110 |
diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh.h gcc-3.3-20040126/gcc/config/sh/sh.h
|
yann@1
|
111 |
--- gcc-3.3-20040126-1/gcc/config/sh/sh.h Wed Apr 16 02:06:09 2003
|
yann@1
|
112 |
+++ gcc-3.3-20040126/gcc/config/sh/sh.h Fri Jan 30 17:53:51 2004
|
yann@1
|
113 |
@@ -3231,6 +3231,7 @@
|
yann@1
|
114 |
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
|
yann@1
|
115 |
{"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \
|
yann@1
|
116 |
{"binary_logical_operator", {AND, IOR, XOR}}, \
|
yann@1
|
117 |
+ {"cmpsi_operand", {SUBREG, REG, CONST_INT}}, \
|
yann@1
|
118 |
{"commutative_float_operator", {PLUS, MULT}}, \
|
yann@1
|
119 |
{"equality_comparison_operator", {EQ,NE}}, \
|
yann@1
|
120 |
{"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
|
yann@1
|
121 |
diff -ru gcc-3.3-20040126-1/gcc/config/sh/sh.md gcc-3.3-20040126/gcc/config/sh/sh.md
|
yann@1
|
122 |
--- gcc-3.3-20040126-1/gcc/config/sh/sh.md Tue Jan 13 02:03:25 2004
|
yann@1
|
123 |
+++ gcc-3.3-20040126/gcc/config/sh/sh.md Fri Jan 30 17:54:20 2004
|
yann@1
|
124 |
@@ -685,11 +685,14 @@
|
yann@1
|
125 |
|
yann@1
|
126 |
(define_expand "cmpsi"
|
yann@1
|
127 |
[(set (reg:SI T_REG)
|
yann@1
|
128 |
- (compare (match_operand:SI 0 "arith_operand" "")
|
yann@1
|
129 |
+ (compare (match_operand:SI 0 "cmpsi_operand" "")
|
yann@1
|
130 |
(match_operand:SI 1 "arith_operand" "")))]
|
yann@1
|
131 |
"TARGET_SH1"
|
yann@1
|
132 |
"
|
yann@1
|
133 |
{
|
yann@1
|
134 |
+ if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
|
yann@1
|
135 |
+ && GET_CODE (operands[1]) != CONST_INT)
|
yann@1
|
136 |
+ operands[0] = copy_to_mode_reg (SImode, operands[0]);
|
yann@1
|
137 |
sh_compare_op0 = operands[0];
|
yann@1
|
138 |
sh_compare_op1 = operands[1];
|
yann@1
|
139 |
DONE;
|
yann@1
|
140 |
@@ -1147,7 +1150,9 @@
|
yann@1
|
141 |
(match_operand:SI 2 "arith_reg_operand" "r"))
|
yann@1
|
142 |
(reg:SI T_REG)))
|
yann@1
|
143 |
(set (reg:SI T_REG)
|
yann@1
|
144 |
- (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
|
yann@1
|
145 |
+ (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
|
yann@1
|
146 |
+ (reg:SI T_REG))
|
yann@1
|
147 |
+ (match_dup 1)))]
|
yann@1
|
148 |
"TARGET_SH1"
|
yann@1
|
149 |
"subc %2,%0"
|
yann@1
|
150 |
[(set_attr "type" "arith")])
|
yann@1
|
151 |
@@ -7223,6 +7228,10 @@
|
yann@1
|
152 |
}
|
yann@1
|
153 |
DONE;
|
yann@1
|
154 |
}
|
yann@1
|
155 |
+ if (sh_expand_t_scc (EQ, operands[0]))
|
yann@1
|
156 |
+ DONE;
|
yann@1
|
157 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
158 |
+ FAIL;
|
yann@1
|
159 |
operands[1] = prepare_scc_operands (EQ);
|
yann@1
|
160 |
}")
|
yann@1
|
161 |
|
yann@1
|
162 |
@@ -7269,6 +7278,8 @@
|
yann@1
|
163 |
}
|
yann@1
|
164 |
DONE;
|
yann@1
|
165 |
}
|
yann@1
|
166 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
167 |
+ FAIL;
|
yann@1
|
168 |
operands[1] = prepare_scc_operands (LT);
|
yann@1
|
169 |
}")
|
yann@1
|
170 |
|
yann@1
|
171 |
@@ -7371,6 +7382,8 @@
|
yann@1
|
172 |
}
|
yann@1
|
173 |
DONE;
|
yann@1
|
174 |
}
|
yann@1
|
175 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
176 |
+ FAIL;
|
yann@1
|
177 |
operands[1] = prepare_scc_operands (GT);
|
yann@1
|
178 |
}")
|
yann@1
|
179 |
|
yann@1
|
180 |
@@ -7423,6 +7436,8 @@
|
yann@1
|
181 |
DONE;
|
yann@1
|
182 |
}
|
yann@1
|
183 |
|
yann@1
|
184 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
185 |
+ FAIL;
|
yann@1
|
186 |
if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
|
yann@1
|
187 |
{
|
yann@1
|
188 |
if (TARGET_IEEE)
|
yann@1
|
189 |
@@ -7462,6 +7477,8 @@
|
yann@1
|
190 |
sh_compare_op0, sh_compare_op1));
|
yann@1
|
191 |
DONE;
|
yann@1
|
192 |
}
|
yann@1
|
193 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
194 |
+ FAIL;
|
yann@1
|
195 |
operands[1] = prepare_scc_operands (GTU);
|
yann@1
|
196 |
}")
|
yann@1
|
197 |
|
yann@1
|
198 |
@@ -7486,6 +7503,8 @@
|
yann@1
|
199 |
sh_compare_op1, sh_compare_op0));
|
yann@1
|
200 |
DONE;
|
yann@1
|
201 |
}
|
yann@1
|
202 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
203 |
+ FAIL;
|
yann@1
|
204 |
operands[1] = prepare_scc_operands (LTU);
|
yann@1
|
205 |
}")
|
yann@1
|
206 |
|
yann@1
|
207 |
@@ -7515,6 +7534,8 @@
|
yann@1
|
208 |
|
yann@1
|
209 |
DONE;
|
yann@1
|
210 |
}
|
yann@1
|
211 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
212 |
+ FAIL;
|
yann@1
|
213 |
operands[1] = prepare_scc_operands (LEU);
|
yann@1
|
214 |
}")
|
yann@1
|
215 |
|
yann@1
|
216 |
@@ -7545,6 +7566,8 @@
|
yann@1
|
217 |
DONE;
|
yann@1
|
218 |
}
|
yann@1
|
219 |
|
yann@1
|
220 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
221 |
+ FAIL;
|
yann@1
|
222 |
operands[1] = prepare_scc_operands (GEU);
|
yann@1
|
223 |
}")
|
yann@1
|
224 |
|
yann@1
|
225 |
@@ -7592,8 +7615,12 @@
|
yann@1
|
226 |
DONE;
|
yann@1
|
227 |
}
|
yann@1
|
228 |
|
yann@1
|
229 |
- operands[1] = prepare_scc_operands (EQ);
|
yann@1
|
230 |
- operands[2] = gen_reg_rtx (SImode);
|
yann@1
|
231 |
+ if (sh_expand_t_scc (NE, operands[0]))
|
yann@1
|
232 |
+ DONE;
|
yann@1
|
233 |
+ if (! rtx_equal_function_value_matters)
|
yann@1
|
234 |
+ FAIL;
|
yann@1
|
235 |
+ operands[1] = prepare_scc_operands (EQ);
|
yann@1
|
236 |
+ operands[2] = gen_reg_rtx (SImode);
|
yann@1
|
237 |
}")
|
yann@1
|
238 |
|
yann@1
|
239 |
(define_expand "sunordered"
|
yann@1
|
240 |
|
yann@1
|
241 |
----
|
yann@1
|
242 |
SUGIOKA Toshinobu
|
yann@1
|
243 |
|
yann@1
|
244 |
|
yann@1
|
245 |
|
yann@1
|
246 |
|