diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0278-PR-tree-optimization-49039.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0278-PR-tree-optimization-49039.patch | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0278-PR-tree-optimization-49039.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0278-PR-tree-optimization-49039.patch new file mode 100644 index 0000000000..49232cdcab --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0278-PR-tree-optimization-49039.patch | |||
@@ -0,0 +1,217 @@ | |||
1 | From 2961db51d944dc693c16502ef40dc47ee4f92143 Mon Sep 17 00:00:00 2001 | ||
2 | From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Wed, 18 May 2011 20:43:44 +0000 | ||
4 | Subject: [PATCH] PR tree-optimization/49039 | ||
5 | * tree-vrp.c (extract_range_from_binary_expr): For | ||
6 | MIN_EXPR <~[a, b], ~[c, d]> and MAX_EXPR <~[a, b], ~[c, d]> | ||
7 | return ~[MAX_EXPR <a, c>, MIN_EXPR <b, d>]. | ||
8 | |||
9 | * gcc.c-torture/execute/pr49039.c: New test. | ||
10 | * gcc.dg/tree-ssa/pr49039.c: New test. | ||
11 | * g++.dg/torture/pr49039.C: New test. | ||
12 | |||
13 | |||
14 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173877 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
15 | |||
16 | index 25f9804..cb6627c 100644 | ||
17 | new file mode 100644 | ||
18 | index 0000000..f576cba | ||
19 | --- /dev/null | ||
20 | +++ b/gcc/testsuite/g++.dg/torture/pr49039.C | ||
21 | @@ -0,0 +1,76 @@ | ||
22 | +// PR tree-optimization/49039 | ||
23 | +// { dg-do run } | ||
24 | + | ||
25 | +template <class T1, class T2> | ||
26 | +struct pair | ||
27 | +{ | ||
28 | + T1 first; | ||
29 | + T2 second; | ||
30 | + pair (const T1 & a, const T2 & b):first (a), second (b) {} | ||
31 | +}; | ||
32 | + | ||
33 | +template <class T1, class T2> | ||
34 | +inline pair <T1, T2> | ||
35 | +make_pair (T1 x, T2 y) | ||
36 | +{ | ||
37 | + return pair <T1, T2> (x, y); | ||
38 | +} | ||
39 | + | ||
40 | +typedef __SIZE_TYPE__ size_t; | ||
41 | +struct S | ||
42 | +{ | ||
43 | + const char *Data; | ||
44 | + size_t Length; | ||
45 | + static size_t min (size_t a, size_t b) { return a < b ? a : b; } | ||
46 | + static size_t max (size_t a, size_t b) { return a > b ? a : b; } | ||
47 | + S () :Data (0), Length (0) { } | ||
48 | + S (const char *Str) : Data (Str), Length (__builtin_strlen (Str)) {} | ||
49 | + S (const char *data, size_t length) : Data (data), Length (length) {} | ||
50 | + bool empty () const { return Length == 0; } | ||
51 | + size_t size () const { return Length; } | ||
52 | + S slice (size_t Start, size_t End) const | ||
53 | + { | ||
54 | + Start = min (Start, Length); | ||
55 | + End = min (max (Start, End), Length); | ||
56 | + return S (Data + Start, End - Start); | ||
57 | + } | ||
58 | + pair <S, S> split (char Separator) const | ||
59 | + { | ||
60 | + size_t Idx = find (Separator); | ||
61 | + if (Idx == ~size_t (0)) | ||
62 | + return make_pair (*this, S ()); | ||
63 | + return make_pair (slice (0, Idx), slice (Idx + 1, ~size_t (0))); | ||
64 | + } | ||
65 | + size_t find (char C, size_t From = 0) const | ||
66 | + { | ||
67 | + for (size_t i = min (From, Length), e = Length; i != e; ++i) | ||
68 | + if (Data[i] == C) | ||
69 | + return i; | ||
70 | + return ~size_t (0); | ||
71 | + } | ||
72 | +}; | ||
73 | + | ||
74 | +void | ||
75 | +Test (const char *arg) | ||
76 | +{ | ||
77 | + S Desc (arg); | ||
78 | + while (!Desc.empty ()) | ||
79 | + { | ||
80 | + pair <S, S> Split = Desc.split ('-'); | ||
81 | + S Token = Split.first; | ||
82 | + Desc = Split.second; | ||
83 | + if (Token.empty ()) | ||
84 | + continue; | ||
85 | + Split = Token.split (':'); | ||
86 | + S Specifier = Split.first; | ||
87 | + if (Specifier.empty ()) | ||
88 | + __builtin_abort (); | ||
89 | + } | ||
90 | +} | ||
91 | + | ||
92 | +int | ||
93 | +main () | ||
94 | +{ | ||
95 | + Test ("-"); | ||
96 | + return 0; | ||
97 | +} | ||
98 | diff --git a/gcc/testsuite/gcc.c-torture/execute/pr49039.c b/gcc/testsuite/gcc.c-torture/execute/pr49039.c | ||
99 | new file mode 100644 | ||
100 | index 0000000..546d114 | ||
101 | --- /dev/null | ||
102 | +++ b/gcc/testsuite/gcc.c-torture/execute/pr49039.c | ||
103 | @@ -0,0 +1,26 @@ | ||
104 | +/* PR tree-optimization/49039 */ | ||
105 | +extern void abort (void); | ||
106 | +int cnt; | ||
107 | + | ||
108 | +__attribute__((noinline, noclone)) void | ||
109 | +foo (unsigned int x, unsigned int y) | ||
110 | +{ | ||
111 | + unsigned int minv, maxv; | ||
112 | + if (x == 1 || y == -2U) | ||
113 | + return; | ||
114 | + minv = x < y ? x : y; | ||
115 | + maxv = x > y ? x : y; | ||
116 | + if (minv == 1) | ||
117 | + ++cnt; | ||
118 | + if (maxv == -2U) | ||
119 | + ++cnt; | ||
120 | +} | ||
121 | + | ||
122 | +int | ||
123 | +main () | ||
124 | +{ | ||
125 | + foo (-2U, 1); | ||
126 | + if (cnt != 2) | ||
127 | + abort (); | ||
128 | + return 0; | ||
129 | +} | ||
130 | diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c b/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c | ||
131 | new file mode 100644 | ||
132 | index 0000000..3500dbf | ||
133 | --- /dev/null | ||
134 | +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c | ||
135 | @@ -0,0 +1,31 @@ | ||
136 | +/* PR tree-optimization/49039 */ | ||
137 | +/* { dg-do compile } */ | ||
138 | +/* { dg-options "-O2 -fdump-tree-vrp1" } */ | ||
139 | + | ||
140 | +extern void bar (void); | ||
141 | + | ||
142 | +void | ||
143 | +foo (unsigned int x, unsigned int y) | ||
144 | +{ | ||
145 | + unsigned int minv, maxv; | ||
146 | + if (x >= 3 && x <= 6) | ||
147 | + return; | ||
148 | + if (y >= 5 && y <= 8) | ||
149 | + return; | ||
150 | + minv = x < y ? x : y; | ||
151 | + maxv = x > y ? x : y; | ||
152 | + if (minv == 5) | ||
153 | + bar (); | ||
154 | + if (minv == 6) | ||
155 | + bar (); | ||
156 | + if (maxv == 5) | ||
157 | + bar (); | ||
158 | + if (maxv == 6) | ||
159 | + bar (); | ||
160 | +} | ||
161 | + | ||
162 | +/* { dg-final { scan-tree-dump "Folding predicate minv_\[0-9\]* == 5 to 0" "vrp1" } } */ | ||
163 | +/* { dg-final { scan-tree-dump "Folding predicate minv_\[0-9\]* == 6 to 0" "vrp1" } } */ | ||
164 | +/* { dg-final { scan-tree-dump "Folding predicate maxv_\[0-9\]* == 5 to 0" "vrp1" } } */ | ||
165 | +/* { dg-final { scan-tree-dump "Folding predicate maxv_\[0-9\]* == 6 to 0" "vrp1" } } */ | ||
166 | +/* { dg-final { cleanup-tree-dump "vrp1" } } */ | ||
167 | diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c | ||
168 | index 280e6da..7bff5fa 100644 | ||
169 | --- a/gcc/tree-vrp.c | ||
170 | +++ b/gcc/tree-vrp.c | ||
171 | @@ -1,5 +1,5 @@ | ||
172 | /* Support routines for Value Range Propagation (VRP). | ||
173 | - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 | ||
174 | + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 | ||
175 | Free Software Foundation, Inc. | ||
176 | Contributed by Diego Novillo <dnovillo@redhat.com>. | ||
177 | |||
178 | @@ -2357,17 +2357,27 @@ extract_range_from_binary_expr (value_range_t *vr, | ||
179 | op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0]. | ||
180 | Note that we are guaranteed to have vr0.type == vr1.type at | ||
181 | this point. */ | ||
182 | - if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE) | ||
183 | + if (vr0.type == VR_ANTI_RANGE) | ||
184 | { | ||
185 | - set_value_range_to_varying (vr); | ||
186 | - return; | ||
187 | + if (code == PLUS_EXPR) | ||
188 | + { | ||
189 | + set_value_range_to_varying (vr); | ||
190 | + return; | ||
191 | + } | ||
192 | + /* For MIN_EXPR and MAX_EXPR with two VR_ANTI_RANGEs, | ||
193 | + the resulting VR_ANTI_RANGE is the same - intersection | ||
194 | + of the two ranges. */ | ||
195 | + min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min); | ||
196 | + max = vrp_int_const_binop (MIN_EXPR, vr0.max, vr1.max); | ||
197 | + } | ||
198 | + else | ||
199 | + { | ||
200 | + /* For operations that make the resulting range directly | ||
201 | + proportional to the original ranges, apply the operation to | ||
202 | + the same end of each range. */ | ||
203 | + min = vrp_int_const_binop (code, vr0.min, vr1.min); | ||
204 | + max = vrp_int_const_binop (code, vr0.max, vr1.max); | ||
205 | } | ||
206 | - | ||
207 | - /* For operations that make the resulting range directly | ||
208 | - proportional to the original ranges, apply the operation to | ||
209 | - the same end of each range. */ | ||
210 | - min = vrp_int_const_binop (code, vr0.min, vr1.min); | ||
211 | - max = vrp_int_const_binop (code, vr0.max, vr1.max); | ||
212 | |||
213 | /* If both additions overflowed the range kind is still correct. | ||
214 | This happens regularly with subtracting something in unsigned | ||
215 | -- | ||
216 | 1.7.0.4 | ||
217 | |||