diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0392-2011-06-06-Richard-Guenther-rguenther-suse.de.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0392-2011-06-06-Richard-Guenther-rguenther-suse.de.patch | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0392-2011-06-06-Richard-Guenther-rguenther-suse.de.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0392-2011-06-06-Richard-Guenther-rguenther-suse.de.patch new file mode 100644 index 0000000000..bded821fe5 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0392-2011-06-06-Richard-Guenther-rguenther-suse.de.patch | |||
@@ -0,0 +1,267 @@ | |||
1 | From 701245b3347bb4ac5433de15e4c69924c2d1a7e8 Mon Sep 17 00:00:00 2001 | ||
2 | From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Mon, 6 Jun 2011 10:13:23 +0000 | ||
4 | Subject: [PATCH] 2011-06-06 Richard Guenther <rguenther@suse.de> | ||
5 | |||
6 | PR tree-optimization/48702 | ||
7 | * tree-ssa-address.c (create_mem_ref_raw): Create MEM_REFs | ||
8 | only when we know the base address is within bounds. | ||
9 | * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Do not | ||
10 | assume the base address of TARGET_MEM_REFs is in bounds. | ||
11 | (indirect_refs_may_alias_p): Fix TARGET_MEM_REF without index tests. | ||
12 | |||
13 | * gcc.dg/torture/pr48702.c: New testcase. | ||
14 | |||
15 | Backport from mainline | ||
16 | 2011-05-31 Jakub Jelinek <jakub@redhat.com> | ||
17 | |||
18 | PR rtl-optimization/49235 | ||
19 | * tree-ssa-address.c (gen_addr_rtx): Ignore base if it is const0_rtx. | ||
20 | (create_mem_ref_raw): Create MEM_REF even if base is INTEGER_CST. | ||
21 | |||
22 | * gcc.dg/pr49235.c: New test. | ||
23 | |||
24 | |||
25 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174688 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
26 | |||
27 | index 1a7b287..b3199f9 100644 | ||
28 | new file mode 100644 | ||
29 | index 0000000..f1e589f | ||
30 | --- /dev/null | ||
31 | +++ b/gcc/testsuite/gcc.dg/pr49235.c | ||
32 | @@ -0,0 +1,25 @@ | ||
33 | +/* PR rtl-optimization/49235 */ | ||
34 | +/* { dg-do compile { target { int32plus } } } */ | ||
35 | +/* { dg-options "-O -fno-delete-null-pointer-checks -fno-tree-scev-cprop -ftree-vectorize -fno-vect-cost-model -w" } */ | ||
36 | + | ||
37 | +void | ||
38 | +foo (void) | ||
39 | +{ | ||
40 | + unsigned i; | ||
41 | + unsigned *p = 0; | ||
42 | + for (i = 0; i < 4; ++i) | ||
43 | + *p++ = 0; | ||
44 | + for (i = 0; i < 4; ++i) | ||
45 | + *p++ = 0; | ||
46 | +} | ||
47 | + | ||
48 | +void | ||
49 | +bar (void) | ||
50 | +{ | ||
51 | + unsigned i; | ||
52 | + unsigned *p = (unsigned *) (__UINTPTR_TYPE__) 0x12340000; | ||
53 | + for (i = 0; i < 4; ++i) | ||
54 | + *p++ = 0; | ||
55 | + for (i = 0; i < 4; ++i) | ||
56 | + *p++ = 0; | ||
57 | +} | ||
58 | diff --git a/gcc/testsuite/gcc.dg/torture/pr48702.c b/gcc/testsuite/gcc.dg/torture/pr48702.c | ||
59 | new file mode 100644 | ||
60 | index 0000000..1ec371d | ||
61 | --- /dev/null | ||
62 | +++ b/gcc/testsuite/gcc.dg/torture/pr48702.c | ||
63 | @@ -0,0 +1,47 @@ | ||
64 | +/* { dg-do run } */ | ||
65 | + | ||
66 | +extern void abort (void); | ||
67 | + | ||
68 | +#define LEN 4 | ||
69 | + | ||
70 | +static inline void unpack(int array[LEN]) | ||
71 | +{ | ||
72 | + int ii, val; | ||
73 | + val = 1; | ||
74 | + for (ii = 0; ii < LEN; ii++) { | ||
75 | + array[ii] = val % 2; | ||
76 | + val = val / 2; | ||
77 | + } | ||
78 | +} | ||
79 | + | ||
80 | +static inline int pack(int array[LEN]) | ||
81 | +{ | ||
82 | + int ans, ii; | ||
83 | + ans = 0; | ||
84 | + for (ii = LEN-1; ii >= 0; ii--) { | ||
85 | + ans = 2 * ans + array[ii]; | ||
86 | + } | ||
87 | + return ans; | ||
88 | +} | ||
89 | + | ||
90 | +int __attribute__((noinline)) | ||
91 | +foo() | ||
92 | +{ | ||
93 | + int temp, ans; | ||
94 | + int array[LEN]; | ||
95 | + unpack(array); | ||
96 | + temp = array[0]; | ||
97 | + array[0] = array[2]; | ||
98 | + array[2] = temp; | ||
99 | + ans = pack(array); | ||
100 | + return ans; | ||
101 | +} | ||
102 | + | ||
103 | +int main(void) | ||
104 | +{ | ||
105 | + int val; | ||
106 | + val = foo(); | ||
107 | + if (val != 4) | ||
108 | + abort (); | ||
109 | + return 0; | ||
110 | +} | ||
111 | diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c | ||
112 | index a9ca835..437460d 100644 | ||
113 | --- a/gcc/tree-ssa-address.c | ||
114 | +++ b/gcc/tree-ssa-address.c | ||
115 | @@ -1,5 +1,5 @@ | ||
116 | /* Memory address lowering and addressing mode selection. | ||
117 | - Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 | ||
118 | + Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2011 | ||
119 | Free Software Foundation, Inc. | ||
120 | |||
121 | This file is part of GCC. | ||
122 | @@ -129,7 +129,7 @@ gen_addr_rtx (enum machine_mode address_mode, | ||
123 | *addr = act_elem; | ||
124 | } | ||
125 | |||
126 | - if (base) | ||
127 | + if (base && base != const0_rtx) | ||
128 | { | ||
129 | if (*addr) | ||
130 | *addr = simplify_gen_binary (PLUS, address_mode, base, *addr); | ||
131 | @@ -361,8 +361,11 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr, | ||
132 | index2 = addr->base; | ||
133 | } | ||
134 | |||
135 | - /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */ | ||
136 | - if (alias_ptr_type | ||
137 | + /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. | ||
138 | + ??? As IVOPTs does not follow restrictions to where the base | ||
139 | + pointer may point to create a MEM_REF only if we know that | ||
140 | + base is valid. */ | ||
141 | + if ((TREE_CODE (base) == ADDR_EXPR || TREE_CODE (base) == INTEGER_CST) | ||
142 | && (!index2 || integer_zerop (index2)) | ||
143 | && (!addr->index || integer_zerop (addr->index))) | ||
144 | return fold_build2 (MEM_REF, type, base, addr->offset); | ||
145 | diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c | ||
146 | index 8434179..1d213df 100644 | ||
147 | --- a/gcc/tree-ssa-alias.c | ||
148 | +++ b/gcc/tree-ssa-alias.c | ||
149 | @@ -719,8 +719,9 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, | ||
150 | alias_set_type base2_alias_set, bool tbaa_p) | ||
151 | { | ||
152 | tree ptr1; | ||
153 | - tree ptrtype1; | ||
154 | + tree ptrtype1, dbase2; | ||
155 | HOST_WIDE_INT offset1p = offset1, offset2p = offset2; | ||
156 | + HOST_WIDE_INT doffset1, doffset2; | ||
157 | |||
158 | ptr1 = TREE_OPERAND (base1, 0); | ||
159 | |||
160 | @@ -744,11 +745,12 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, | ||
161 | the pointer access is beyond the extent of the variable access. | ||
162 | (the pointer base cannot validly point to an offset less than zero | ||
163 | of the variable). | ||
164 | - They also cannot alias if the pointer may not point to the decl. */ | ||
165 | - if ((TREE_CODE (base1) != TARGET_MEM_REF | ||
166 | - || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1))) | ||
167 | + ??? IVOPTs creates bases that do not honor this restriction, | ||
168 | + so do not apply this optimization for TARGET_MEM_REFs. */ | ||
169 | + if (TREE_CODE (base1) != TARGET_MEM_REF | ||
170 | && !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2)) | ||
171 | return false; | ||
172 | + /* They also cannot alias if the pointer may not point to the decl. */ | ||
173 | if (!ptr_deref_may_alias_decl_p (ptr1, base2)) | ||
174 | return false; | ||
175 | |||
176 | @@ -771,20 +773,6 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, | ||
177 | if (base2_alias_set == -1) | ||
178 | base2_alias_set = get_alias_set (base2); | ||
179 | |||
180 | - /* If both references are through the same type, they do not alias | ||
181 | - if the accesses do not overlap. This does extra disambiguation | ||
182 | - for mixed/pointer accesses but requires strict aliasing. | ||
183 | - For MEM_REFs we require that the component-ref offset we computed | ||
184 | - is relative to the start of the type which we ensure by | ||
185 | - comparing rvalue and access type and disregarding the constant | ||
186 | - pointer offset. */ | ||
187 | - if ((TREE_CODE (base1) != TARGET_MEM_REF | ||
188 | - || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1))) | ||
189 | - && (TREE_CODE (base1) != MEM_REF | ||
190 | - || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1) | ||
191 | - && same_type_for_tbaa (TREE_TYPE (ptrtype1), TREE_TYPE (base2)) == 1) | ||
192 | - return ranges_overlap_p (offset1, max_size1, offset2, max_size2); | ||
193 | - | ||
194 | /* When we are trying to disambiguate an access with a pointer dereference | ||
195 | as base versus one with a decl as base we can use both the size | ||
196 | of the decl and its dynamic type for extra disambiguation. | ||
197 | @@ -814,6 +802,48 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, | ||
198 | && tree_int_cst_lt (DECL_SIZE (base2), TYPE_SIZE (TREE_TYPE (ptrtype1)))) | ||
199 | return false; | ||
200 | |||
201 | + if (!ref2) | ||
202 | + return true; | ||
203 | + | ||
204 | + /* If the decl is accressed via a MEM_REF, reconstruct the base | ||
205 | + we can use for TBAA and an appropriately adjusted offset. */ | ||
206 | + dbase2 = ref2; | ||
207 | + while (handled_component_p (dbase2)) | ||
208 | + dbase2 = TREE_OPERAND (dbase2, 0); | ||
209 | + doffset1 = offset1; | ||
210 | + doffset2 = offset2; | ||
211 | + if (TREE_CODE (dbase2) == MEM_REF | ||
212 | + || TREE_CODE (dbase2) == TARGET_MEM_REF) | ||
213 | + { | ||
214 | + double_int moff = mem_ref_offset (dbase2); | ||
215 | + moff = double_int_lshift (moff, | ||
216 | + BITS_PER_UNIT == 8 | ||
217 | + ? 3 : exact_log2 (BITS_PER_UNIT), | ||
218 | + HOST_BITS_PER_DOUBLE_INT, true); | ||
219 | + if (double_int_negative_p (moff)) | ||
220 | + doffset1 -= double_int_neg (moff).low; | ||
221 | + else | ||
222 | + doffset2 -= moff.low; | ||
223 | + } | ||
224 | + | ||
225 | + /* If either reference is view-converted, give up now. */ | ||
226 | + if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1 | ||
227 | + || same_type_for_tbaa (TREE_TYPE (dbase2), | ||
228 | + TREE_TYPE (reference_alias_ptr_type (dbase2))) != 1) | ||
229 | + return true; | ||
230 | + | ||
231 | + /* If both references are through the same type, they do not alias | ||
232 | + if the accesses do not overlap. This does extra disambiguation | ||
233 | + for mixed/pointer accesses but requires strict aliasing. | ||
234 | + For MEM_REFs we require that the component-ref offset we computed | ||
235 | + is relative to the start of the type which we ensure by | ||
236 | + comparing rvalue and access type and disregarding the constant | ||
237 | + pointer offset. */ | ||
238 | + if ((TREE_CODE (base1) != TARGET_MEM_REF | ||
239 | + || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1))) | ||
240 | + && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1) | ||
241 | + return ranges_overlap_p (doffset1, max_size1, doffset2, max_size2); | ||
242 | + | ||
243 | /* Do access-path based disambiguation. */ | ||
244 | if (ref1 && ref2 | ||
245 | && handled_component_p (ref1) | ||
246 | @@ -942,12 +972,12 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, | ||
247 | /* If both references are through the same type, they do not alias | ||
248 | if the accesses do not overlap. This does extra disambiguation | ||
249 | for mixed/pointer accesses but requires strict aliasing. */ | ||
250 | - if ((TREE_CODE (base1) != TARGET_MEM_REF || !TMR_INDEX (base1)) | ||
251 | - && (TREE_CODE (base2) != TARGET_MEM_REF || !TMR_INDEX (base2)) | ||
252 | - && (TREE_CODE (base1) != MEM_REF | ||
253 | - || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1) | ||
254 | - && (TREE_CODE (base2) != MEM_REF | ||
255 | - || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1) | ||
256 | + if ((TREE_CODE (base1) != TARGET_MEM_REF | ||
257 | + || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1))) | ||
258 | + && (TREE_CODE (base2) != TARGET_MEM_REF | ||
259 | + || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2))) | ||
260 | + && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1 | ||
261 | + && same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1 | ||
262 | && same_type_for_tbaa (TREE_TYPE (ptrtype1), | ||
263 | TREE_TYPE (ptrtype2)) == 1) | ||
264 | return ranges_overlap_p (offset1, max_size1, offset2, max_size2); | ||
265 | -- | ||
266 | 1.7.0.4 | ||
267 | |||