Mercurial > hg > CbC > CbC_llvm
comparison test/Transforms/InstCombine/sub.ll @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | afa8332a0e37 |
children | 803732b1fca8 |
comparison
equal
deleted
inserted
replaced
101:34baf5011add | 120:1172e4bd9c6f |
---|---|
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
1 target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" | 2 target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" |
2 | 3 |
3 ; Optimize subtracts. | 4 ; Optimize subtracts. |
4 ; | 5 ; |
5 ; RUN: opt < %s -instcombine -S | FileCheck %s | 6 ; RUN: opt < %s -instcombine -S | FileCheck %s |
6 | 7 |
7 define i32 @test1(i32 %A) { | 8 define i32 @test1(i32 %A) { |
8 %B = sub i32 %A, %A | |
9 ret i32 %B | |
10 ; CHECK-LABEL: @test1( | 9 ; CHECK-LABEL: @test1( |
11 ; CHECK: ret i32 0 | 10 ; CHECK-NEXT: ret i32 0 |
11 ; | |
12 %B = sub i32 %A, %A | |
13 ret i32 %B | |
12 } | 14 } |
13 | 15 |
14 define i32 @test2(i32 %A) { | 16 define i32 @test2(i32 %A) { |
15 %B = sub i32 %A, 0 | |
16 ret i32 %B | |
17 ; CHECK-LABEL: @test2( | 17 ; CHECK-LABEL: @test2( |
18 ; CHECK: ret i32 %A | 18 ; CHECK-NEXT: ret i32 %A |
19 ; | |
20 %B = sub i32 %A, 0 | |
21 ret i32 %B | |
19 } | 22 } |
20 | 23 |
21 define i32 @test3(i32 %A) { | 24 define i32 @test3(i32 %A) { |
22 %B = sub i32 0, %A | |
23 %C = sub i32 0, %B | |
24 ret i32 %C | |
25 ; CHECK-LABEL: @test3( | 25 ; CHECK-LABEL: @test3( |
26 ; CHECK: ret i32 %A | 26 ; CHECK-NEXT: ret i32 %A |
27 ; | |
28 %B = sub i32 0, %A | |
29 %C = sub i32 0, %B | |
30 ret i32 %C | |
27 } | 31 } |
28 | 32 |
29 define i32 @test4(i32 %A, i32 %x) { | 33 define i32 @test4(i32 %A, i32 %x) { |
30 %B = sub i32 0, %A | |
31 %C = sub i32 %x, %B | |
32 ret i32 %C | |
33 ; CHECK-LABEL: @test4( | 34 ; CHECK-LABEL: @test4( |
34 ; CHECK: %C = add i32 %x, %A | 35 ; CHECK-NEXT: [[C:%.*]] = add i32 %x, %A |
35 ; CHECK: ret i32 %C | 36 ; CHECK-NEXT: ret i32 [[C]] |
37 ; | |
38 %B = sub i32 0, %A | |
39 %C = sub i32 %x, %B | |
40 ret i32 %C | |
36 } | 41 } |
37 | 42 |
38 define i32 @test5(i32 %A, i32 %B, i32 %C) { | 43 define i32 @test5(i32 %A, i32 %B, i32 %C) { |
39 %D = sub i32 %B, %C | |
40 %E = sub i32 %A, %D | |
41 ret i32 %E | |
42 ; CHECK-LABEL: @test5( | 44 ; CHECK-LABEL: @test5( |
43 ; CHECK: %D1 = sub i32 %C, %B | 45 ; CHECK-NEXT: [[D1:%.*]] = sub i32 %C, %B |
44 ; CHECK: %E = add | 46 ; CHECK-NEXT: [[E:%.*]] = add i32 [[D1]], %A |
45 ; CHECK: ret i32 %E | 47 ; CHECK-NEXT: ret i32 [[E]] |
48 ; | |
49 %D = sub i32 %B, %C | |
50 %E = sub i32 %A, %D | |
51 ret i32 %E | |
46 } | 52 } |
47 | 53 |
48 define i32 @test6(i32 %A, i32 %B) { | 54 define i32 @test6(i32 %A, i32 %B) { |
49 %C = and i32 %A, %B | |
50 %D = sub i32 %A, %C | |
51 ret i32 %D | |
52 ; CHECK-LABEL: @test6( | 55 ; CHECK-LABEL: @test6( |
53 ; CHECK-NEXT: xor i32 %B, -1 | 56 ; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 %B, -1 |
54 ; CHECK-NEXT: %D = and i32 | 57 ; CHECK-NEXT: [[D:%.*]] = and i32 %A, [[B_NOT]] |
55 ; CHECK-NEXT: ret i32 %D | 58 ; CHECK-NEXT: ret i32 [[D]] |
59 ; | |
60 %C = and i32 %A, %B | |
61 %D = sub i32 %A, %C | |
62 ret i32 %D | |
56 } | 63 } |
57 | 64 |
58 define i32 @test7(i32 %A) { | 65 define i32 @test7(i32 %A) { |
59 %B = sub i32 -1, %A | |
60 ret i32 %B | |
61 ; CHECK-LABEL: @test7( | 66 ; CHECK-LABEL: @test7( |
62 ; CHECK: %B = xor i32 %A, -1 | 67 ; CHECK-NEXT: [[B:%.*]] = xor i32 %A, -1 |
63 ; CHECK: ret i32 %B | 68 ; CHECK-NEXT: ret i32 [[B]] |
69 ; | |
70 %B = sub i32 -1, %A | |
71 ret i32 %B | |
64 } | 72 } |
65 | 73 |
66 define i32 @test8(i32 %A) { | 74 define i32 @test8(i32 %A) { |
67 %B = mul i32 9, %A | |
68 %C = sub i32 %B, %A | |
69 ret i32 %C | |
70 ; CHECK-LABEL: @test8( | 75 ; CHECK-LABEL: @test8( |
71 ; CHECK: %C = shl i32 %A, 3 | 76 ; CHECK-NEXT: [[C:%.*]] = shl i32 %A, 3 |
72 ; CHECK: ret i32 %C | 77 ; CHECK-NEXT: ret i32 [[C]] |
78 ; | |
79 %B = mul i32 9, %A | |
80 %C = sub i32 %B, %A | |
81 ret i32 %C | |
73 } | 82 } |
74 | 83 |
75 define i32 @test9(i32 %A) { | 84 define i32 @test9(i32 %A) { |
76 %B = mul i32 3, %A | |
77 %C = sub i32 %A, %B | |
78 ret i32 %C | |
79 ; CHECK-LABEL: @test9( | 85 ; CHECK-LABEL: @test9( |
80 ; CHECK: %C = mul i32 %A, -2 | 86 ; CHECK-NEXT: [[C:%.*]] = mul i32 %A, -2 |
81 ; CHECK: ret i32 %C | 87 ; CHECK-NEXT: ret i32 [[C]] |
88 ; | |
89 %B = mul i32 3, %A | |
90 %C = sub i32 %A, %B | |
91 ret i32 %C | |
82 } | 92 } |
83 | 93 |
84 define i32 @test10(i32 %A, i32 %B) { | 94 define i32 @test10(i32 %A, i32 %B) { |
85 %C = sub i32 0, %A | |
86 %D = sub i32 0, %B | |
87 %E = mul i32 %C, %D | |
88 ret i32 %E | |
89 ; CHECK-LABEL: @test10( | 95 ; CHECK-LABEL: @test10( |
90 ; CHECK: %E = mul i32 %A, %B | 96 ; CHECK-NEXT: [[E:%.*]] = mul i32 %A, %B |
91 ; CHECK: ret i32 %E | 97 ; CHECK-NEXT: ret i32 [[E]] |
98 ; | |
99 %C = sub i32 0, %A | |
100 %D = sub i32 0, %B | |
101 %E = mul i32 %C, %D | |
102 ret i32 %E | |
92 } | 103 } |
93 | 104 |
94 define i32 @test10a(i32 %A) { | 105 define i32 @test10a(i32 %A) { |
95 %C = sub i32 0, %A | |
96 %E = mul i32 %C, 7 | |
97 ret i32 %E | |
98 ; CHECK-LABEL: @test10a( | 106 ; CHECK-LABEL: @test10a( |
99 ; CHECK: %E = mul i32 %A, -7 | 107 ; CHECK-NEXT: [[E:%.*]] = mul i32 %A, -7 |
100 ; CHECK: ret i32 %E | 108 ; CHECK-NEXT: ret i32 [[E]] |
109 ; | |
110 %C = sub i32 0, %A | |
111 %E = mul i32 %C, 7 | |
112 ret i32 %E | |
101 } | 113 } |
102 | 114 |
103 define i1 @test11(i8 %A, i8 %B) { | 115 define i1 @test11(i8 %A, i8 %B) { |
104 %C = sub i8 %A, %B | |
105 %cD = icmp ne i8 %C, 0 | |
106 ret i1 %cD | |
107 ; CHECK-LABEL: @test11( | 116 ; CHECK-LABEL: @test11( |
108 ; CHECK: %cD = icmp ne i8 %A, %B | 117 ; CHECK-NEXT: [[D:%.*]] = icmp ne i8 %A, %B |
109 ; CHECK: ret i1 %cD | 118 ; CHECK-NEXT: ret i1 [[D]] |
119 ; | |
120 %C = sub i8 %A, %B | |
121 %D = icmp ne i8 %C, 0 | |
122 ret i1 %D | |
123 } | |
124 | |
125 define <2 x i1> @test11vec(<2 x i8> %A, <2 x i8> %B) { | |
126 ; CHECK-LABEL: @test11vec( | |
127 ; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> %A, %B | |
128 ; CHECK-NEXT: ret <2 x i1> [[D]] | |
129 ; | |
130 %C = sub <2 x i8> %A, %B | |
131 %D = icmp ne <2 x i8> %C, zeroinitializer | |
132 ret <2 x i1> %D | |
110 } | 133 } |
111 | 134 |
112 define i32 @test12(i32 %A) { | 135 define i32 @test12(i32 %A) { |
113 %B = ashr i32 %A, 31 | |
114 %C = sub i32 0, %B | |
115 ret i32 %C | |
116 ; CHECK-LABEL: @test12( | 136 ; CHECK-LABEL: @test12( |
117 ; CHECK: %C = lshr i32 %A, 31 | 137 ; CHECK-NEXT: [[C:%.*]] = lshr i32 %A, 31 |
118 ; CHECK: ret i32 %C | 138 ; CHECK-NEXT: ret i32 [[C]] |
139 ; | |
140 %B = ashr i32 %A, 31 | |
141 %C = sub i32 0, %B | |
142 ret i32 %C | |
119 } | 143 } |
120 | 144 |
121 define i32 @test13(i32 %A) { | 145 define i32 @test13(i32 %A) { |
122 %B = lshr i32 %A, 31 | |
123 %C = sub i32 0, %B | |
124 ret i32 %C | |
125 ; CHECK-LABEL: @test13( | 146 ; CHECK-LABEL: @test13( |
126 ; CHECK: %C = ashr i32 %A, 31 | 147 ; CHECK-NEXT: [[C:%.*]] = ashr i32 %A, 31 |
127 ; CHECK: ret i32 %C | 148 ; CHECK-NEXT: ret i32 [[C]] |
128 } | 149 ; |
129 | 150 %B = lshr i32 %A, 31 |
130 define i32 @test14(i32 %A) { | 151 %C = sub i32 0, %B |
131 %B = lshr i32 %A, 31 | 152 ret i32 %C |
132 %C = bitcast i32 %B to i32 | 153 } |
133 %D = sub i32 0, %C | 154 |
134 ret i32 %D | 155 define <2 x i32> @test12vec(<2 x i32> %A) { |
135 ; CHECK-LABEL: @test14( | 156 ; CHECK-LABEL: @test12vec( |
136 ; CHECK: %D = ashr i32 %A, 31 | 157 ; CHECK-NEXT: [[C:%.*]] = lshr <2 x i32> %A, <i32 31, i32 31> |
137 ; CHECK: ret i32 %D | 158 ; CHECK-NEXT: ret <2 x i32> [[C]] |
159 ; | |
160 %B = ashr <2 x i32> %A, <i32 31, i32 31> | |
161 %C = sub <2 x i32> zeroinitializer, %B | |
162 ret <2 x i32> %C | |
163 } | |
164 | |
165 define <2 x i32> @test13vec(<2 x i32> %A) { | |
166 ; CHECK-LABEL: @test13vec( | |
167 ; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> %A, <i32 31, i32 31> | |
168 ; CHECK-NEXT: ret <2 x i32> [[C]] | |
169 ; | |
170 %B = lshr <2 x i32> %A, <i32 31, i32 31> | |
171 %C = sub <2 x i32> zeroinitializer, %B | |
172 ret <2 x i32> %C | |
138 } | 173 } |
139 | 174 |
140 define i32 @test15(i32 %A, i32 %B) { | 175 define i32 @test15(i32 %A, i32 %B) { |
141 %C = sub i32 0, %A | |
142 %D = srem i32 %B, %C | |
143 ret i32 %D | |
144 ; CHECK-LABEL: @test15( | 176 ; CHECK-LABEL: @test15( |
145 ; CHECK: %[[sub:.*]] = sub i32 0, %A | 177 ; CHECK-NEXT: [[C:%.*]] = sub i32 0, %A |
146 ; CHECK-NEXT: %[[rem:.*]] = srem i32 %B, %[[sub]] | 178 ; CHECK-NEXT: [[D:%.*]] = srem i32 %B, [[C]] |
147 ; CHECK: ret i32 %[[rem]] | 179 ; CHECK-NEXT: ret i32 [[D]] |
180 ; | |
181 %C = sub i32 0, %A | |
182 %D = srem i32 %B, %C | |
183 ret i32 %D | |
148 } | 184 } |
149 | 185 |
150 define i32 @test16(i32 %A) { | 186 define i32 @test16(i32 %A) { |
151 %X = sdiv i32 %A, 1123 | |
152 %Y = sub i32 0, %X | |
153 ret i32 %Y | |
154 ; CHECK-LABEL: @test16( | 187 ; CHECK-LABEL: @test16( |
155 ; CHECK: %Y = sdiv i32 %A, -1123 | 188 ; CHECK-NEXT: [[Y:%.*]] = sdiv i32 %A, -1123 |
156 ; CHECK: ret i32 %Y | 189 ; CHECK-NEXT: ret i32 [[Y]] |
190 ; | |
191 %X = sdiv i32 %A, 1123 | |
192 %Y = sub i32 0, %X | |
193 ret i32 %Y | |
157 } | 194 } |
158 | 195 |
159 ; Can't fold subtract here because negation it might oveflow. | 196 ; Can't fold subtract here because negation it might oveflow. |
160 ; PR3142 | 197 ; PR3142 |
161 define i32 @test17(i32 %A) { | 198 define i32 @test17(i32 %A) { |
162 %B = sub i32 0, %A | |
163 %C = sdiv i32 %B, 1234 | |
164 ret i32 %C | |
165 ; CHECK-LABEL: @test17( | 199 ; CHECK-LABEL: @test17( |
166 ; CHECK: %B = sub i32 0, %A | 200 ; CHECK-NEXT: [[B:%.*]] = sub i32 0, %A |
167 ; CHECK: %C = sdiv i32 %B, 1234 | 201 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 [[B]], 1234 |
168 ; CHECK: ret i32 %C | 202 ; CHECK-NEXT: ret i32 [[C]] |
203 ; | |
204 %B = sub i32 0, %A | |
205 %C = sdiv i32 %B, 1234 | |
206 ret i32 %C | |
169 } | 207 } |
170 | 208 |
171 define i64 @test18(i64 %Y) { | 209 define i64 @test18(i64 %Y) { |
172 %tmp.4 = shl i64 %Y, 2 | |
173 %tmp.12 = shl i64 %Y, 2 | |
174 %tmp.8 = sub i64 %tmp.4, %tmp.12 | |
175 ret i64 %tmp.8 | |
176 ; CHECK-LABEL: @test18( | 210 ; CHECK-LABEL: @test18( |
177 ; CHECK: ret i64 0 | 211 ; CHECK-NEXT: ret i64 0 |
212 ; | |
213 %tmp.4 = shl i64 %Y, 2 | |
214 %tmp.12 = shl i64 %Y, 2 | |
215 %tmp.8 = sub i64 %tmp.4, %tmp.12 | |
216 ret i64 %tmp.8 | |
178 } | 217 } |
179 | 218 |
180 define i32 @test19(i32 %X, i32 %Y) { | 219 define i32 @test19(i32 %X, i32 %Y) { |
181 %Z = sub i32 %X, %Y | |
182 %Q = add i32 %Z, %Y | |
183 ret i32 %Q | |
184 ; CHECK-LABEL: @test19( | 220 ; CHECK-LABEL: @test19( |
185 ; CHECK: ret i32 %X | 221 ; CHECK-NEXT: ret i32 %X |
222 ; | |
223 %Z = sub i32 %X, %Y | |
224 %Q = add i32 %Z, %Y | |
225 ret i32 %Q | |
186 } | 226 } |
187 | 227 |
188 define i1 @test20(i32 %g, i32 %h) { | 228 define i1 @test20(i32 %g, i32 %h) { |
189 %tmp.2 = sub i32 %g, %h | |
190 %tmp.4 = icmp ne i32 %tmp.2, %g | |
191 ret i1 %tmp.4 | |
192 ; CHECK-LABEL: @test20( | 229 ; CHECK-LABEL: @test20( |
193 ; CHECK: %tmp.4 = icmp ne i32 %h, 0 | 230 ; CHECK-NEXT: [[TMP_4:%.*]] = icmp ne i32 %h, 0 |
194 ; CHECK: ret i1 %tmp.4 | 231 ; CHECK-NEXT: ret i1 [[TMP_4]] |
232 ; | |
233 %tmp.2 = sub i32 %g, %h | |
234 %tmp.4 = icmp ne i32 %tmp.2, %g | |
235 ret i1 %tmp.4 | |
195 } | 236 } |
196 | 237 |
197 define i1 @test21(i32 %g, i32 %h) { | 238 define i1 @test21(i32 %g, i32 %h) { |
198 %tmp.2 = sub i32 %g, %h | |
199 %tmp.4 = icmp ne i32 %tmp.2, %g | |
200 ret i1 %tmp.4 | |
201 ; CHECK-LABEL: @test21( | 239 ; CHECK-LABEL: @test21( |
202 ; CHECK: %tmp.4 = icmp ne i32 %h, 0 | 240 ; CHECK-NEXT: [[TMP_4:%.*]] = icmp ne i32 %h, 0 |
203 ; CHECK: ret i1 %tmp.4 | 241 ; CHECK-NEXT: ret i1 [[TMP_4]] |
242 ; | |
243 %tmp.2 = sub i32 %g, %h | |
244 %tmp.4 = icmp ne i32 %tmp.2, %g | |
245 ret i1 %tmp.4 | |
204 } | 246 } |
205 | 247 |
206 ; PR2298 | 248 ; PR2298 |
207 define zeroext i1 @test22(i32 %a, i32 %b) nounwind { | 249 define zeroext i1 @test22(i32 %a, i32 %b) nounwind { |
208 %tmp2 = sub i32 0, %a | |
209 %tmp4 = sub i32 0, %b | |
210 %tmp5 = icmp eq i32 %tmp2, %tmp4 | |
211 ret i1 %tmp5 | |
212 ; CHECK-LABEL: @test22( | 250 ; CHECK-LABEL: @test22( |
213 ; CHECK: %tmp5 = icmp eq i32 %b, %a | 251 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 %b, %a |
214 ; CHECK: ret i1 %tmp5 | 252 ; CHECK-NEXT: ret i1 [[TMP5]] |
253 ; | |
254 %tmp2 = sub i32 0, %a | |
255 %tmp4 = sub i32 0, %b | |
256 %tmp5 = icmp eq i32 %tmp2, %tmp4 | |
257 ret i1 %tmp5 | |
215 } | 258 } |
216 | 259 |
217 ; rdar://7362831 | 260 ; rdar://7362831 |
218 define i32 @test23(i8* %P, i64 %A){ | 261 define i32 @test23(i8* %P, i64 %A){ |
262 ; CHECK-LABEL: @test23( | |
263 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 %A to i32 | |
264 ; CHECK-NEXT: ret i32 [[TMP1]] | |
265 ; | |
219 %B = getelementptr inbounds i8, i8* %P, i64 %A | 266 %B = getelementptr inbounds i8, i8* %P, i64 %A |
220 %C = ptrtoint i8* %B to i64 | 267 %C = ptrtoint i8* %B to i64 |
221 %D = trunc i64 %C to i32 | 268 %D = trunc i64 %C to i32 |
222 %E = ptrtoint i8* %P to i64 | 269 %E = ptrtoint i8* %P to i64 |
223 %F = trunc i64 %E to i32 | 270 %F = trunc i64 %E to i32 |
224 %G = sub i32 %D, %F | 271 %G = sub i32 %D, %F |
225 ret i32 %G | 272 ret i32 %G |
226 ; CHECK-LABEL: @test23( | |
227 ; CHECK-NEXT: = trunc i64 %A to i32 | |
228 ; CHECK-NEXT: ret i32 | |
229 } | 273 } |
230 | 274 |
231 define i8 @test23_as1(i8 addrspace(1)* %P, i16 %A) { | 275 define i8 @test23_as1(i8 addrspace(1)* %P, i16 %A) { |
232 ; CHECK: @test23_as1 | 276 ; CHECK-LABEL: @test23_as1( |
233 ; CHECK-NEXT: = trunc i16 %A to i8 | 277 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 %A to i8 |
234 ; CHECK-NEXT: ret i8 | 278 ; CHECK-NEXT: ret i8 [[TMP1]] |
279 ; | |
235 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A | 280 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A |
236 %C = ptrtoint i8 addrspace(1)* %B to i16 | 281 %C = ptrtoint i8 addrspace(1)* %B to i16 |
237 %D = trunc i16 %C to i8 | 282 %D = trunc i16 %C to i8 |
238 %E = ptrtoint i8 addrspace(1)* %P to i16 | 283 %E = ptrtoint i8 addrspace(1)* %P to i16 |
239 %F = trunc i16 %E to i8 | 284 %F = trunc i16 %E to i8 |
240 %G = sub i8 %D, %F | 285 %G = sub i8 %D, %F |
241 ret i8 %G | 286 ret i8 %G |
242 } | 287 } |
243 | 288 |
244 define i64 @test24(i8* %P, i64 %A){ | 289 define i64 @test24(i8* %P, i64 %A){ |
290 ; CHECK-LABEL: @test24( | |
291 ; CHECK-NEXT: ret i64 %A | |
292 ; | |
245 %B = getelementptr inbounds i8, i8* %P, i64 %A | 293 %B = getelementptr inbounds i8, i8* %P, i64 %A |
246 %C = ptrtoint i8* %B to i64 | 294 %C = ptrtoint i8* %B to i64 |
247 %E = ptrtoint i8* %P to i64 | 295 %E = ptrtoint i8* %P to i64 |
248 %G = sub i64 %C, %E | 296 %G = sub i64 %C, %E |
249 ret i64 %G | 297 ret i64 %G |
250 ; CHECK-LABEL: @test24( | |
251 ; CHECK-NEXT: ret i64 %A | |
252 } | 298 } |
253 | 299 |
254 define i16 @test24_as1(i8 addrspace(1)* %P, i16 %A) { | 300 define i16 @test24_as1(i8 addrspace(1)* %P, i16 %A) { |
255 ; CHECK: @test24_as1 | 301 ; CHECK-LABEL: @test24_as1( |
256 ; CHECK-NEXT: ret i16 %A | 302 ; CHECK-NEXT: ret i16 %A |
303 ; | |
257 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A | 304 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A |
258 %C = ptrtoint i8 addrspace(1)* %B to i16 | 305 %C = ptrtoint i8 addrspace(1)* %B to i16 |
259 %E = ptrtoint i8 addrspace(1)* %P to i16 | 306 %E = ptrtoint i8 addrspace(1)* %P to i16 |
260 %G = sub i16 %C, %E | 307 %G = sub i16 %C, %E |
261 ret i16 %G | 308 ret i16 %G |
262 } | 309 } |
263 | 310 |
264 define i64 @test24a(i8* %P, i64 %A){ | 311 define i64 @test24a(i8* %P, i64 %A){ |
312 ; CHECK-LABEL: @test24a( | |
313 ; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, %A | |
314 ; CHECK-NEXT: ret i64 [[DIFF_NEG]] | |
315 ; | |
265 %B = getelementptr inbounds i8, i8* %P, i64 %A | 316 %B = getelementptr inbounds i8, i8* %P, i64 %A |
266 %C = ptrtoint i8* %B to i64 | 317 %C = ptrtoint i8* %B to i64 |
267 %E = ptrtoint i8* %P to i64 | 318 %E = ptrtoint i8* %P to i64 |
268 %G = sub i64 %E, %C | 319 %G = sub i64 %E, %C |
269 ret i64 %G | 320 ret i64 %G |
270 ; CHECK-LABEL: @test24a( | |
271 ; CHECK-NEXT: sub i64 0, %A | |
272 ; CHECK-NEXT: ret i64 | |
273 } | 321 } |
274 | 322 |
275 define i16 @test24a_as1(i8 addrspace(1)* %P, i16 %A) { | 323 define i16 @test24a_as1(i8 addrspace(1)* %P, i16 %A) { |
276 ; CHECK: @test24a_as1 | 324 ; CHECK-LABEL: @test24a_as1( |
277 ; CHECK-NEXT: sub i16 0, %A | 325 ; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i16 0, %A |
278 ; CHECK-NEXT: ret i16 | 326 ; CHECK-NEXT: ret i16 [[DIFF_NEG]] |
327 ; | |
279 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A | 328 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A |
280 %C = ptrtoint i8 addrspace(1)* %B to i16 | 329 %C = ptrtoint i8 addrspace(1)* %B to i16 |
281 %E = ptrtoint i8 addrspace(1)* %P to i16 | 330 %E = ptrtoint i8 addrspace(1)* %P to i16 |
282 %G = sub i16 %E, %C | 331 %G = sub i16 %E, %C |
283 ret i16 %G | 332 ret i16 %G |
285 | 334 |
286 | 335 |
287 @Arr = external global [42 x i16] | 336 @Arr = external global [42 x i16] |
288 | 337 |
289 define i64 @test24b(i8* %P, i64 %A){ | 338 define i64 @test24b(i8* %P, i64 %A){ |
339 ; CHECK-LABEL: @test24b( | |
340 ; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i64 %A, 1 | |
341 ; CHECK-NEXT: ret i64 [[B_IDX]] | |
342 ; | |
290 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A | 343 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A |
291 %C = ptrtoint i16* %B to i64 | 344 %C = ptrtoint i16* %B to i64 |
292 %G = sub i64 %C, ptrtoint ([42 x i16]* @Arr to i64) | 345 %G = sub i64 %C, ptrtoint ([42 x i16]* @Arr to i64) |
293 ret i64 %G | 346 ret i64 %G |
294 ; CHECK-LABEL: @test24b( | |
295 ; CHECK-NEXT: shl nuw i64 %A, 1 | |
296 ; CHECK-NEXT: ret i64 | |
297 } | 347 } |
298 | 348 |
299 | 349 |
300 define i64 @test25(i8* %P, i64 %A){ | 350 define i64 @test25(i8* %P, i64 %A){ |
351 ; CHECK-LABEL: @test25( | |
352 ; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i64 %A, 1 | |
353 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B_IDX]], -84 | |
354 ; CHECK-NEXT: ret i64 [[TMP1]] | |
355 ; | |
301 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A | 356 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A |
302 %C = ptrtoint i16* %B to i64 | 357 %C = ptrtoint i16* %B to i64 |
303 %G = sub i64 %C, ptrtoint (i16* getelementptr ([42 x i16], [42 x i16]* @Arr, i64 1, i64 0) to i64) | 358 %G = sub i64 %C, ptrtoint (i16* getelementptr ([42 x i16], [42 x i16]* @Arr, i64 1, i64 0) to i64) |
304 ret i64 %G | 359 ret i64 %G |
305 ; CHECK-LABEL: @test25( | |
306 ; CHECK-NEXT: shl nuw i64 %A, 1 | |
307 ; CHECK-NEXT: add i64 {{.*}}, -84 | |
308 ; CHECK-NEXT: ret i64 | |
309 } | 360 } |
310 | 361 |
311 @Arr_as1 = external addrspace(1) global [42 x i16] | 362 @Arr_as1 = external addrspace(1) global [42 x i16] |
312 | 363 |
313 define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) { | 364 define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) { |
314 ; CHECK: @test25_as1 | 365 ; CHECK-LABEL: @test25_as1( |
315 ; CHECK-NEXT: %1 = trunc i64 %A to i16 | 366 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 %A to i16 |
316 ; CHECK-NEXT: shl nuw i16 %1, 1 | 367 ; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i16 [[TMP1]], 1 |
317 ; CHECK-NEXT: add i16 {{.*}}, -84 | 368 ; CHECK-NEXT: [[TMP2:%.*]] = add i16 [[B_IDX]], -84 |
318 ; CHECK-NEXT: ret i16 | 369 ; CHECK-NEXT: ret i16 [[TMP2]] |
370 ; | |
319 %B = getelementptr inbounds [42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 0, i64 %A | 371 %B = getelementptr inbounds [42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 0, i64 %A |
320 %C = ptrtoint i16 addrspace(1)* %B to i16 | 372 %C = ptrtoint i16 addrspace(1)* %B to i16 |
321 %G = sub i16 %C, ptrtoint (i16 addrspace(1)* getelementptr ([42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 1, i64 0) to i16) | 373 %G = sub i16 %C, ptrtoint (i16 addrspace(1)* getelementptr ([42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 1, i64 0) to i16) |
322 ret i16 %G | 374 ret i16 %G |
323 } | 375 } |
324 | 376 |
325 define i32 @test26(i32 %x) { | 377 define i32 @test26(i32 %x) { |
378 ; CHECK-LABEL: @test26( | |
379 ; CHECK-NEXT: [[NEG:%.*]] = shl i32 -3, %x | |
380 ; CHECK-NEXT: ret i32 [[NEG]] | |
381 ; | |
326 %shl = shl i32 3, %x | 382 %shl = shl i32 3, %x |
327 %neg = sub i32 0, %shl | 383 %neg = sub i32 0, %shl |
328 ret i32 %neg | 384 ret i32 %neg |
329 ; CHECK-LABEL: @test26( | |
330 ; CHECK-NEXT: shl i32 -3 | |
331 ; CHECK-NEXT: ret i32 | |
332 } | 385 } |
333 | 386 |
334 define i32 @test27(i32 %x, i32 %y) { | 387 define i32 @test27(i32 %x, i32 %y) { |
388 ; CHECK-LABEL: @test27( | |
389 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %y, 3 | |
390 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], %x | |
391 ; CHECK-NEXT: ret i32 [[SUB]] | |
392 ; | |
335 %mul = mul i32 %y, -8 | 393 %mul = mul i32 %y, -8 |
336 %sub = sub i32 %x, %mul | 394 %sub = sub i32 %x, %mul |
337 ret i32 %sub | 395 ret i32 %sub |
338 ; CHECK-LABEL: @test27( | |
339 ; CHECK-NEXT: shl i32 %y, 3 | |
340 ; CHECK-NEXT: add i32 | |
341 ; CHECK-NEXT: ret i32 | |
342 } | 396 } |
343 | 397 |
344 define i32 @test28(i32 %x, i32 %y, i32 %z) { | 398 define i32 @test28(i32 %x, i32 %y, i32 %z) { |
399 ; CHECK-LABEL: @test28( | |
400 ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %z, %y | |
401 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], %x | |
402 ; CHECK-NEXT: ret i32 [[SUB]] | |
403 ; | |
345 %neg = sub i32 0, %z | 404 %neg = sub i32 0, %z |
346 %mul = mul i32 %neg, %y | 405 %mul = mul i32 %neg, %y |
347 %sub = sub i32 %x, %mul | 406 %sub = sub i32 %x, %mul |
348 ret i32 %sub | 407 ret i32 %sub |
349 ; CHECK-LABEL: @test28( | |
350 ; CHECK-NEXT: mul i32 %z, %y | |
351 ; CHECK-NEXT: add i32 | |
352 ; CHECK-NEXT: ret i32 | |
353 } | 408 } |
354 | 409 |
355 define i64 @test29(i8* %foo, i64 %i, i64 %j) { | 410 define i64 @test29(i8* %foo, i64 %i, i64 %j) { |
411 ; CHECK-LABEL: @test29( | |
412 ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 %i, %j | |
413 ; CHECK-NEXT: ret i64 [[TMP1]] | |
414 ; | |
356 %gep1 = getelementptr inbounds i8, i8* %foo, i64 %i | 415 %gep1 = getelementptr inbounds i8, i8* %foo, i64 %i |
357 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j | 416 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j |
358 %cast1 = ptrtoint i8* %gep1 to i64 | 417 %cast1 = ptrtoint i8* %gep1 to i64 |
359 %cast2 = ptrtoint i8* %gep2 to i64 | 418 %cast2 = ptrtoint i8* %gep2 to i64 |
360 %sub = sub i64 %cast1, %cast2 | 419 %sub = sub i64 %cast1, %cast2 |
361 ret i64 %sub | 420 ret i64 %sub |
362 ; CHECK-LABEL: @test29( | |
363 ; CHECK-NEXT: sub i64 %i, %j | |
364 ; CHECK-NEXT: ret i64 | |
365 } | 421 } |
366 | 422 |
367 define i64 @test30(i8* %foo, i64 %i, i64 %j) { | 423 define i64 @test30(i8* %foo, i64 %i, i64 %j) { |
424 ; CHECK-LABEL: @test30( | |
425 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 %i, 2 | |
426 ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[GEP1_IDX]], %j | |
427 ; CHECK-NEXT: ret i64 [[TMP1]] | |
428 ; | |
368 %bit = bitcast i8* %foo to i32* | 429 %bit = bitcast i8* %foo to i32* |
369 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i | 430 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i |
370 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j | 431 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j |
371 %cast1 = ptrtoint i32* %gep1 to i64 | 432 %cast1 = ptrtoint i32* %gep1 to i64 |
372 %cast2 = ptrtoint i8* %gep2 to i64 | 433 %cast2 = ptrtoint i8* %gep2 to i64 |
373 %sub = sub i64 %cast1, %cast2 | 434 %sub = sub i64 %cast1, %cast2 |
374 ret i64 %sub | 435 ret i64 %sub |
375 ; CHECK-LABEL: @test30( | |
376 ; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2 | |
377 ; CHECK-NEXT: sub i64 %gep1.idx, %j | |
378 ; CHECK-NEXT: ret i64 | |
379 } | 436 } |
380 | 437 |
381 define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) { | 438 define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) { |
382 ; CHECK-LABEL: @test30_as1( | 439 ; CHECK-LABEL: @test30_as1( |
383 ; CHECK-NEXT: %gep1.idx = shl nuw i16 %i, 2 | 440 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i16 %i, 2 |
384 ; CHECK-NEXT: sub i16 %gep1.idx, %j | 441 ; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[GEP1_IDX]], %j |
385 ; CHECK-NEXT: ret i16 | 442 ; CHECK-NEXT: ret i16 [[TMP1]] |
443 ; | |
386 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* | 444 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* |
387 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i | 445 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i |
388 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j | 446 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j |
389 %cast1 = ptrtoint i32 addrspace(1)* %gep1 to i16 | 447 %cast1 = ptrtoint i32 addrspace(1)* %gep1 to i16 |
390 %cast2 = ptrtoint i8 addrspace(1)* %gep2 to i16 | 448 %cast2 = ptrtoint i8 addrspace(1)* %gep2 to i16 |
391 %sub = sub i16 %cast1, %cast2 | 449 %sub = sub i16 %cast1, %cast2 |
392 ret i16 %sub | 450 ret i16 %sub |
393 } | 451 } |
394 | 452 |
395 define <2 x i64> @test31(<2 x i64> %A) { | 453 define <2 x i64> @test31(<2 x i64> %A) { |
454 ; CHECK-LABEL: @test31( | |
455 ; CHECK-NEXT: [[SUB:%.*]] = add <2 x i64> %A, <i64 3, i64 4> | |
456 ; CHECK-NEXT: ret <2 x i64> [[SUB]] | |
457 ; | |
396 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> | 458 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> |
397 %sub = sub <2 x i64> <i64 2, i64 3>, %xor | 459 %sub = sub <2 x i64> <i64 2, i64 3>, %xor |
398 ret <2 x i64> %sub | 460 ret <2 x i64> %sub |
399 ; CHECK-LABEL: @test31( | |
400 ; CHECK-NEXT: %sub = add <2 x i64> %A, <i64 3, i64 4> | |
401 ; CHECK-NEXT: ret <2 x i64> %sub | |
402 } | 461 } |
403 | 462 |
404 define <2 x i64> @test32(<2 x i64> %A) { | 463 define <2 x i64> @test32(<2 x i64> %A) { |
464 ; CHECK-LABEL: @test32( | |
465 ; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> <i64 3, i64 4>, %A | |
466 ; CHECK-NEXT: ret <2 x i64> [[SUB]] | |
467 ; | |
405 %add = add <2 x i64> %A, <i64 -1, i64 -1> | 468 %add = add <2 x i64> %A, <i64 -1, i64 -1> |
406 %sub = sub <2 x i64> <i64 2, i64 3>, %add | 469 %sub = sub <2 x i64> <i64 2, i64 3>, %add |
407 ret <2 x i64> %sub | 470 ret <2 x i64> %sub |
408 ; CHECK-LABEL: @test32( | |
409 ; CHECK-NEXT: %sub = sub <2 x i64> <i64 3, i64 4> | |
410 ; CHECK-NEXT: ret <2 x i64> %sub | |
411 } | 471 } |
412 | 472 |
413 define <2 x i64> @test33(<2 x i1> %A) { | 473 define <2 x i64> @test33(<2 x i1> %A) { |
474 ; CHECK-LABEL: @test33( | |
475 ; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> %A to <2 x i64> | |
476 ; CHECK-NEXT: ret <2 x i64> [[SUB]] | |
477 ; | |
414 %ext = zext <2 x i1> %A to <2 x i64> | 478 %ext = zext <2 x i1> %A to <2 x i64> |
415 %sub = sub <2 x i64> zeroinitializer, %ext | 479 %sub = sub <2 x i64> zeroinitializer, %ext |
416 ret <2 x i64> %sub | 480 ret <2 x i64> %sub |
417 ; CHECK-LABEL: @test33( | |
418 ; CHECK-NEXT: %sub = sext <2 x i1> %A to <2 x i64> | |
419 ; CHECK-NEXT: ret <2 x i64> %sub | |
420 } | 481 } |
421 | 482 |
422 define <2 x i64> @test34(<2 x i1> %A) { | 483 define <2 x i64> @test34(<2 x i1> %A) { |
484 ; CHECK-LABEL: @test34( | |
485 ; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i1> %A to <2 x i64> | |
486 ; CHECK-NEXT: ret <2 x i64> [[SUB]] | |
487 ; | |
423 %ext = sext <2 x i1> %A to <2 x i64> | 488 %ext = sext <2 x i1> %A to <2 x i64> |
424 %sub = sub <2 x i64> zeroinitializer, %ext | 489 %sub = sub <2 x i64> zeroinitializer, %ext |
425 ret <2 x i64> %sub | 490 ret <2 x i64> %sub |
426 ; CHECK-LABEL: @test34( | |
427 ; CHECK-NEXT: %sub = zext <2 x i1> %A to <2 x i64> | |
428 ; CHECK-NEXT: ret <2 x i64> %sub | |
429 } | 491 } |
430 | 492 |
431 define <2 x i64> @test35(<2 x i64> %A) { | 493 define <2 x i64> @test35(<2 x i64> %A) { |
494 ; CHECK-LABEL: @test35( | |
495 ; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> %A, <i64 -2, i64 -3> | |
496 ; CHECK-NEXT: ret <2 x i64> [[SUB]] | |
497 ; | |
432 %mul = mul <2 x i64> %A, <i64 3, i64 4> | 498 %mul = mul <2 x i64> %A, <i64 3, i64 4> |
433 %sub = sub <2 x i64> %A, %mul | 499 %sub = sub <2 x i64> %A, %mul |
434 ret <2 x i64> %sub | 500 ret <2 x i64> %sub |
435 ; CHECK-LABEL: @test35( | |
436 ; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 -2, i64 -3> | |
437 ; CHECK-NEXT: ret <2 x i64> %sub | |
438 } | 501 } |
439 | 502 |
440 define <2 x i64> @test36(<2 x i64> %A) { | 503 define <2 x i64> @test36(<2 x i64> %A) { |
504 ; CHECK-LABEL: @test36( | |
505 ; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> %A, <i64 7, i64 15> | |
506 ; CHECK-NEXT: ret <2 x i64> [[SUB]] | |
507 ; | |
441 %shl = shl <2 x i64> %A, <i64 3, i64 4> | 508 %shl = shl <2 x i64> %A, <i64 3, i64 4> |
442 %sub = sub <2 x i64> %shl, %A | 509 %sub = sub <2 x i64> %shl, %A |
443 ret <2 x i64> %sub | 510 ret <2 x i64> %sub |
444 ; CHECK-LABEL: @test36( | |
445 ; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 7, i64 15> | |
446 ; CHECK-NEXT: ret <2 x i64> %sub | |
447 } | 511 } |
448 | 512 |
449 define <2 x i32> @test37(<2 x i32> %A) { | 513 define <2 x i32> @test37(<2 x i32> %A) { |
514 ; CHECK-LABEL: @test37( | |
515 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> %A, <i32 -2147483648, i32 -2147483648> | |
516 ; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32> | |
517 ; CHECK-NEXT: ret <2 x i32> [[SUB]] | |
518 ; | |
450 %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648> | 519 %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648> |
451 %sub = sub nsw <2 x i32> zeroinitializer, %div | 520 %sub = sub nsw <2 x i32> zeroinitializer, %div |
452 ret <2 x i32> %sub | 521 ret <2 x i32> %sub |
453 ; CHECK-LABEL: @test37( | |
454 ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> %A, <i32 -2147483648, i32 -2147483648> | |
455 ; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[ICMP]] to <2 x i32> | |
456 ; CHECK-NEXT: ret <2 x i32> [[SEXT]] | |
457 } | 522 } |
458 | 523 |
459 define i32 @test38(i32 %A) { | 524 define i32 @test38(i32 %A) { |
525 ; CHECK-LABEL: @test38( | |
526 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 %A, -2147483648 | |
527 ; CHECK-NEXT: [[SUB:%.*]] = sext i1 [[TMP1]] to i32 | |
528 ; CHECK-NEXT: ret i32 [[SUB]] | |
529 ; | |
460 %div = sdiv i32 %A, -2147483648 | 530 %div = sdiv i32 %A, -2147483648 |
461 %sub = sub nsw i32 0, %div | 531 %sub = sub nsw i32 0, %div |
462 ret i32 %sub | 532 ret i32 %sub |
463 ; CHECK-LABEL: @test38( | |
464 ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 %A, -2147483648 | |
465 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i32 | |
466 ; CHECK-NEXT: ret i32 [[SEXT]] | |
467 } | 533 } |
468 | 534 |
469 define i32 @test39(i32 %A, i32 %x) { | 535 define i32 @test39(i32 %A, i32 %x) { |
536 ; CHECK-LABEL: @test39( | |
537 ; CHECK-NEXT: [[C:%.*]] = add i32 %x, %A | |
538 ; CHECK-NEXT: ret i32 [[C]] | |
539 ; | |
470 %B = sub i32 0, %A | 540 %B = sub i32 0, %A |
471 %C = sub nsw i32 %x, %B | 541 %C = sub nsw i32 %x, %B |
472 ret i32 %C | 542 ret i32 %C |
473 ; CHECK-LABEL: @test39( | |
474 ; CHECK: %C = add i32 %x, %A | |
475 ; CHECK: ret i32 %C | |
476 } | 543 } |
477 | 544 |
478 define i16 @test40(i16 %a, i16 %b) { | 545 define i16 @test40(i16 %a, i16 %b) { |
546 ; CHECK-LABEL: @test40( | |
547 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 %a, 1 | |
548 ; CHECK-NEXT: [[ASHR1:%.*]] = ashr i16 %b, 1 | |
549 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[ASHR]], [[ASHR1]] | |
550 ; CHECK-NEXT: ret i16 [[SUB]] | |
551 ; | |
479 %ashr = ashr i16 %a, 1 | 552 %ashr = ashr i16 %a, 1 |
480 %ashr1 = ashr i16 %b, 1 | 553 %ashr1 = ashr i16 %b, 1 |
481 %sub = sub i16 %ashr, %ashr1 | 554 %sub = sub i16 %ashr, %ashr1 |
482 ret i16 %sub | 555 ret i16 %sub |
483 ; CHECK-LABEL: @test40( | |
484 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 %a, 1 | |
485 ; CHECK-NEXT: [[ASHR1:%.*]] = ashr i16 %b, 1 | |
486 ; CHECK-NEXT: [[RET:%.*]] = sub nsw i16 [[ASHR]], [[ASHR1]] | |
487 ; CHECK: ret i16 [[RET]] | |
488 } | 556 } |
489 | 557 |
490 define i32 @test41(i16 %a, i16 %b) { | 558 define i32 @test41(i16 %a, i16 %b) { |
559 ; CHECK-LABEL: @test41( | |
560 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 %a to i32 | |
561 ; CHECK-NEXT: [[CONV1:%.*]] = sext i16 %b to i32 | |
562 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]] | |
563 ; CHECK-NEXT: ret i32 [[SUB]] | |
564 ; | |
491 %conv = sext i16 %a to i32 | 565 %conv = sext i16 %a to i32 |
492 %conv1 = sext i16 %b to i32 | 566 %conv1 = sext i16 %b to i32 |
493 %sub = sub i32 %conv, %conv1 | 567 %sub = sub i32 %conv, %conv1 |
494 ret i32 %sub | 568 ret i32 %sub |
495 ; CHECK-LABEL: @test41( | |
496 ; CHECK-NEXT: [[SEXT:%.*]] = sext i16 %a to i32 | |
497 ; CHECK-NEXT: [[SEXT1:%.*]] = sext i16 %b to i32 | |
498 ; CHECK-NEXT: [[RET:%.*]] = sub nsw i32 [[SEXT]], [[SEXT1]] | |
499 ; CHECK: ret i32 [[RET]] | |
500 } | 569 } |
501 | 570 |
502 define i4 @test42(i4 %x, i4 %y) { | 571 define i4 @test42(i4 %x, i4 %y) { |
572 ; CHECK-LABEL: @test42( | |
573 ; CHECK-NEXT: [[A:%.*]] = and i4 %y, 7 | |
574 ; CHECK-NEXT: [[B:%.*]] = and i4 %x, 7 | |
575 ; CHECK-NEXT: [[C:%.*]] = sub nsw i4 [[A]], [[B]] | |
576 ; CHECK-NEXT: ret i4 [[C]] | |
577 ; | |
503 %a = and i4 %y, 7 | 578 %a = and i4 %y, 7 |
504 %b = and i4 %x, 7 | 579 %b = and i4 %x, 7 |
505 %c = sub i4 %a, %b | 580 %c = sub i4 %a, %b |
506 ret i4 %c | 581 ret i4 %c |
507 ; CHECK-LABEL: @test42( | |
508 ; CHECK-NEXT: [[AND:%.*]] = and i4 %y, 7 | |
509 ; CHECK-NEXT: [[AND1:%.*]] = and i4 %x, 7 | |
510 ; CHECK-NEXT: [[RET:%.*]] = sub nsw i4 [[AND]], [[AND1]] | |
511 ; CHECK: ret i4 [[RET]] | |
512 } | 582 } |
513 | 583 |
514 define i4 @test43(i4 %x, i4 %y) { | 584 define i4 @test43(i4 %x, i4 %y) { |
585 ; CHECK-LABEL: @test43( | |
586 ; CHECK-NEXT: [[A:%.*]] = or i4 %x, -8 | |
587 ; CHECK-NEXT: [[B:%.*]] = and i4 %y, 7 | |
588 ; CHECK-NEXT: [[C:%.*]] = sub nuw i4 [[A]], [[B]] | |
589 ; CHECK-NEXT: ret i4 [[C]] | |
590 ; | |
515 %a = or i4 %x, -8 | 591 %a = or i4 %x, -8 |
516 %b = and i4 %y, 7 | 592 %b = and i4 %y, 7 |
517 %c = sub i4 %a, %b | 593 %c = sub i4 %a, %b |
518 ret i4 %c | 594 ret i4 %c |
519 ; CHECK-LABEL: @test43( | |
520 ; CHECK-NEXT: [[OR:%.*]] = or i4 %x, -8 | |
521 ; CHECK-NEXT: [[AND:%.*]] = and i4 %y, 7 | |
522 ; CHECK-NEXT: [[RET:%.*]] = sub nuw i4 [[OR]], [[AND]] | |
523 ; CHECK: ret i4 [[RET]] | |
524 } | 595 } |
525 | 596 |
526 define i32 @test44(i32 %x) { | 597 define i32 @test44(i32 %x) { |
598 ; CHECK-LABEL: @test44( | |
599 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 %x, -32768 | |
600 ; CHECK-NEXT: ret i32 [[SUB]] | |
601 ; | |
527 %sub = sub nsw i32 %x, 32768 | 602 %sub = sub nsw i32 %x, 32768 |
528 ret i32 %sub | 603 ret i32 %sub |
529 ; CHECK-LABEL: @test44( | |
530 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -32768 | |
531 ; CHECK: ret i32 [[ADD]] | |
532 } | 604 } |
533 | 605 |
534 define i32 @test45(i32 %x, i32 %y) { | 606 define i32 @test45(i32 %x, i32 %y) { |
607 ; CHECK-LABEL: @test45( | |
608 ; CHECK-NEXT: [[SUB:%.*]] = and i32 %x, %y | |
609 ; CHECK-NEXT: ret i32 [[SUB]] | |
610 ; | |
535 %or = or i32 %x, %y | 611 %or = or i32 %x, %y |
536 %xor = xor i32 %x, %y | 612 %xor = xor i32 %x, %y |
537 %sub = sub i32 %or, %xor | 613 %sub = sub i32 %or, %xor |
538 ret i32 %sub | 614 ret i32 %sub |
539 ; CHECK-LABEL: @test45( | |
540 ; CHECK-NEXT: %sub = and i32 %x, %y | |
541 ; CHECK: ret i32 %sub | |
542 } | 615 } |
543 | 616 |
544 define i32 @test46(i32 %x, i32 %y) { | 617 define i32 @test46(i32 %x, i32 %y) { |
545 %or = or i32 %x, %y | |
546 %sub = sub i32 %or, %x | |
547 ret i32 %sub | |
548 ; CHECK-LABEL: @test46( | 618 ; CHECK-LABEL: @test46( |
549 ; CHECK-NEXT: %x.not = xor i32 %x, -1 | 619 ; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 %x, -1 |
550 ; CHECK-NEXT: %sub = and i32 %y, %x.not | 620 ; CHECK-NEXT: [[SUB:%.*]] = and i32 %y, [[X_NOT]] |
551 ; CHECK: ret i32 %sub | 621 ; CHECK-NEXT: ret i32 [[SUB]] |
622 ; | |
623 %or = or i32 %x, %y | |
624 %sub = sub i32 %or, %x | |
625 ret i32 %sub | |
552 } | 626 } |
553 | 627 |
554 define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) { | 628 define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) { |
629 ; CHECK-LABEL: @test47( | |
630 ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 %D, %C | |
631 ; CHECK-NEXT: [[SUB:%.*]] = select i1 %A, i32 [[TMP1]], i32 0 | |
632 ; CHECK-NEXT: ret i32 [[SUB]] | |
633 ; | |
555 %sel0 = select i1 %A, i32 %D, i32 %B | 634 %sel0 = select i1 %A, i32 %D, i32 %B |
556 %sel1 = select i1 %A, i32 %C, i32 %B | 635 %sel1 = select i1 %A, i32 %C, i32 %B |
557 %sub = sub i32 %sel0, %sel1 | 636 %sub = sub i32 %sel0, %sel1 |
558 ret i32 %sub | 637 ret i32 %sub |
559 ; CHECK-LABEL: @test47( | |
560 ; CHECK-NEXT: %[[sub:.*]] = sub i32 %D, %C | |
561 ; CHECK-NEXT: %[[sel:.*]] = select i1 %A, i32 %[[sub]], i32 0 | |
562 ; CHECK-NEXT: ret i32 %[[sel]] | |
563 } | 638 } |
564 | 639 |
565 define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) { | 640 define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) { |
641 ; CHECK-LABEL: @test48( | |
642 ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 %D, %C | |
643 ; CHECK-NEXT: [[SUB:%.*]] = select i1 %A, i32 0, i32 [[TMP1]] | |
644 ; CHECK-NEXT: ret i32 [[SUB]] | |
645 ; | |
566 %sel0 = select i1 %A, i32 %B, i32 %D | 646 %sel0 = select i1 %A, i32 %B, i32 %D |
567 %sel1 = select i1 %A, i32 %B, i32 %C | 647 %sel1 = select i1 %A, i32 %B, i32 %C |
568 %sub = sub i32 %sel0, %sel1 | 648 %sub = sub i32 %sel0, %sel1 |
569 ret i32 %sub | 649 ret i32 %sub |
570 ; CHECK-LABEL: @test48( | 650 } |
571 ; CHECK-NEXT: %[[sub:.*]] = sub i32 %D, %C | 651 |
572 ; CHECK-NEXT: %[[sel:.*]] = select i1 %A, i32 0, i32 %[[sub]] | 652 ; Zext+add is more canonical than sext+sub. |
573 ; CHECK-NEXT: ret i32 %[[sel]] | 653 |
574 } | 654 define i8 @bool_sext_sub(i8 %x, i1 %y) { |
655 ; CHECK-LABEL: @bool_sext_sub( | |
656 ; CHECK-NEXT: [[TMP1:%.*]] = zext i1 %y to i8 | |
657 ; CHECK-NEXT: [[SUB:%.*]] = add i8 [[TMP1]], %x | |
658 ; CHECK-NEXT: ret i8 [[SUB]] | |
659 ; | |
660 %sext = sext i1 %y to i8 | |
661 %sub = sub i8 %x, %sext | |
662 ret i8 %sub | |
663 } | |
664 | |
665 ; Vectors get the same transform. | |
666 | |
667 define <2 x i8> @bool_sext_sub_vec(<2 x i8> %x, <2 x i1> %y) { | |
668 ; CHECK-LABEL: @bool_sext_sub_vec( | |
669 ; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> %y to <2 x i8> | |
670 ; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[TMP1]], %x | |
671 ; CHECK-NEXT: ret <2 x i8> [[SUB]] | |
672 ; | |
673 %sext = sext <2 x i1> %y to <2 x i8> | |
674 %sub = sub <2 x i8> %x, %sext | |
675 ret <2 x i8> %sub | |
676 } | |
677 | |
678 ; NSW is preserved. | |
679 | |
680 define <2 x i8> @bool_sext_sub_vec_nsw(<2 x i8> %x, <2 x i1> %y) { | |
681 ; CHECK-LABEL: @bool_sext_sub_vec_nsw( | |
682 ; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> %y to <2 x i8> | |
683 ; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i8> [[TMP1]], %x | |
684 ; CHECK-NEXT: ret <2 x i8> [[SUB]] | |
685 ; | |
686 %sext = sext <2 x i1> %y to <2 x i8> | |
687 %sub = sub nsw <2 x i8> %x, %sext | |
688 ret <2 x i8> %sub | |
689 } | |
690 | |
691 ; We favor the canonical zext+add over keeping the NUW. | |
692 | |
693 define i8 @bool_sext_sub_nuw(i8 %x, i1 %y) { | |
694 ; CHECK-LABEL: @bool_sext_sub_nuw( | |
695 ; CHECK-NEXT: [[TMP1:%.*]] = zext i1 %y to i8 | |
696 ; CHECK-NEXT: [[SUB:%.*]] = add i8 [[TMP1]], %x | |
697 ; CHECK-NEXT: ret i8 [[SUB]] | |
698 ; | |
699 %sext = sext i1 %y to i8 | |
700 %sub = sub nuw i8 %x, %sext | |
701 ret i8 %sub | |
702 } | |
703 |