Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / AggressiveInstCombine / AArch64 / fptosisat.ll
blob5fea6f669ead69fbf55247e765d4886c4745ff48
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=aggressive-instcombine -mtriple aarch64 -S | FileCheck %s --check-prefixes=CHECK,CHECK-FP
3 ; RUN: opt < %s -passes=aggressive-instcombine -mtriple aarch64 -mattr=+fullfp16 -S | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
5 define i64 @f32_i32(float %in) {
6 ; CHECK-LABEL: @f32_i32(
7 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[IN:%.*]])
8 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
9 ; CHECK-NEXT:    ret i64 [[TMP2]]
11   %conv = fptosi float %in to i64
12   %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
13   %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)
14   ret i64 %max
17 define i64 @f32_i31(float %in) {
18 ; CHECK-LABEL: @f32_i31(
19 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64
20 ; CHECK-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823)
21 ; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824)
22 ; CHECK-NEXT:    ret i64 [[MAX]]
24   %conv = fptosi float %in to i64
25   %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823)
26   %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824)
27   ret i64 %max
30 define i32 @f32_i16(float %in) {
31 ; CHECK-LABEL: @f32_i16(
32 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32
33 ; CHECK-NEXT:    [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767)
34 ; CHECK-NEXT:    [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768)
35 ; CHECK-NEXT:    ret i32 [[MAX]]
37   %conv = fptosi float %in to i32
38   %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
39   %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768)
40   ret i32 %max
43 define i32 @f32_i8(float %in) {
44 ; CHECK-LABEL: @f32_i8(
45 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32
46 ; CHECK-NEXT:    [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127)
47 ; CHECK-NEXT:    [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128)
48 ; CHECK-NEXT:    ret i32 [[MAX]]
50   %conv = fptosi float %in to i32
51   %min = call i32 @llvm.smin.i32(i32 %conv, i32 127)
52   %max = call i32 @llvm.smax.i32(i32 %min, i32 -128)
53   ret i32 %max
56 define i64 @f64_i32(double %in) {
57 ; CHECK-LABEL: @f64_i32(
58 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f64(double [[IN:%.*]])
59 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
60 ; CHECK-NEXT:    ret i64 [[TMP2]]
62   %conv = fptosi double %in to i64
63   %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
64   %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)
65   ret i64 %max
68 define i64 @f64_i31(double %in) {
69 ; CHECK-LABEL: @f64_i31(
70 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64
71 ; CHECK-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823)
72 ; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824)
73 ; CHECK-NEXT:    ret i64 [[MAX]]
75   %conv = fptosi double %in to i64
76   %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823)
77   %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824)
78   ret i64 %max
81 define i32 @f64_i16(double %in) {
82 ; CHECK-LABEL: @f64_i16(
83 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi double [[IN:%.*]] to i32
84 ; CHECK-NEXT:    [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767)
85 ; CHECK-NEXT:    [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768)
86 ; CHECK-NEXT:    ret i32 [[MAX]]
88   %conv = fptosi double %in to i32
89   %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
90   %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768)
91   ret i32 %max
94 define i64 @f16_i32(half %in) {
95 ; CHECK-FP-LABEL: @f16_i32(
96 ; CHECK-FP-NEXT:    [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64
97 ; CHECK-FP-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647)
98 ; CHECK-FP-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648)
99 ; CHECK-FP-NEXT:    ret i64 [[MAX]]
101 ; CHECK-FP16-LABEL: @f16_i32(
102 ; CHECK-FP16-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f16(half [[IN:%.*]])
103 ; CHECK-FP16-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
104 ; CHECK-FP16-NEXT:    ret i64 [[TMP2]]
106   %conv = fptosi half %in to i64
107   %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
108   %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)
109   ret i64 %max
112 define i64 @f16_i31(half %in) {
113 ; CHECK-LABEL: @f16_i31(
114 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64
115 ; CHECK-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823)
116 ; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824)
117 ; CHECK-NEXT:    ret i64 [[MAX]]
119   %conv = fptosi half %in to i64
120   %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823)
121   %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824)
122   ret i64 %max
125 define i32 @f16_i16(half %in) {
126 ; CHECK-LABEL: @f16_i16(
127 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32
128 ; CHECK-NEXT:    [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767)
129 ; CHECK-NEXT:    [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768)
130 ; CHECK-NEXT:    ret i32 [[MAX]]
132   %conv = fptosi half %in to i32
133   %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
134   %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768)
135   ret i32 %max
138 define i32 @f16_i8(half %in) {
139 ; CHECK-LABEL: @f16_i8(
140 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32
141 ; CHECK-NEXT:    [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127)
142 ; CHECK-NEXT:    [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128)
143 ; CHECK-NEXT:    ret i32 [[MAX]]
145   %conv = fptosi half %in to i32
146   %min = call i32 @llvm.smin.i32(i32 %conv, i32 127)
147   %max = call i32 @llvm.smax.i32(i32 %min, i32 -128)
148   ret i32 %max
151 define <2 x i64> @v2f32_i32(<2 x float> %in) {
152 ; CHECK-LABEL: @v2f32_i32(
153 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> [[IN:%.*]])
154 ; CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>
155 ; CHECK-NEXT:    ret <2 x i64> [[TMP2]]
157   %conv = fptosi <2 x float> %in to <2 x i64>
158   %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %conv, <2 x i64> <i64 2147483647, i64 2147483647>)
159   %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> <i64 -2147483648, i64 -2147483648>)
160   ret <2 x i64> %max
163 define <4 x i64> @v4f32_i32(<4 x float> %in) {
164 ; CHECK-LABEL: @v4f32_i32(
165 ; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> [[IN:%.*]])
166 ; CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i32> [[TMP1]] to <4 x i64>
167 ; CHECK-NEXT:    ret <4 x i64> [[TMP2]]
169   %conv = fptosi <4 x float> %in to <4 x i64>
170   %min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
171   %max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %min, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
172   ret <4 x i64> %max
175 define <8 x i64> @v8f32_i32(<8 x float> %in) {
176 ; CHECK-LABEL: @v8f32_i32(
177 ; CHECK-NEXT:    [[TMP1:%.*]] = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> [[IN:%.*]])
178 ; CHECK-NEXT:    [[TMP2:%.*]] = sext <8 x i32> [[TMP1]] to <8 x i64>
179 ; CHECK-NEXT:    ret <8 x i64> [[TMP2]]
181   %conv = fptosi <8 x float> %in to <8 x i64>
182   %min = call <8 x i64> @llvm.smin.v8i64(<8 x i64> %conv, <8 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
183   %max = call <8 x i64> @llvm.smax.v8i64(<8 x i64> %min, <8 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
184   ret <8 x i64> %max
187 define <4 x i32> @v4f16_i16(<4 x half> %in) {
188 ; CHECK-FP-LABEL: @v4f16_i16(
189 ; CHECK-FP-NEXT:    [[CONV:%.*]] = fptosi <4 x half> [[IN:%.*]] to <4 x i32>
190 ; CHECK-FP-NEXT:    [[MIN:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[CONV]], <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
191 ; CHECK-FP-NEXT:    [[MAX:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[MIN]], <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
192 ; CHECK-FP-NEXT:    ret <4 x i32> [[MAX]]
194 ; CHECK-FP16-LABEL: @v4f16_i16(
195 ; CHECK-FP16-NEXT:    [[TMP1:%.*]] = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> [[IN:%.*]])
196 ; CHECK-FP16-NEXT:    [[TMP2:%.*]] = sext <4 x i16> [[TMP1]] to <4 x i32>
197 ; CHECK-FP16-NEXT:    ret <4 x i32> [[TMP2]]
199   %conv = fptosi <4 x half> %in to <4 x i32>
200   %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %conv, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
201   %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
202   ret <4 x i32> %max
205 define <8 x i32> @v8f16_i16(<8 x half> %in) {
206 ; CHECK-FP-LABEL: @v8f16_i16(
207 ; CHECK-FP-NEXT:    [[CONV:%.*]] = fptosi <8 x half> [[IN:%.*]] to <8 x i32>
208 ; CHECK-FP-NEXT:    [[MIN:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[CONV]], <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)
209 ; CHECK-FP-NEXT:    [[MAX:%.*]] = call <8 x i32> @llvm.smax.v8i32(<8 x i32> [[MIN]], <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
210 ; CHECK-FP-NEXT:    ret <8 x i32> [[MAX]]
212 ; CHECK-FP16-LABEL: @v8f16_i16(
213 ; CHECK-FP16-NEXT:    [[TMP1:%.*]] = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> [[IN:%.*]])
214 ; CHECK-FP16-NEXT:    [[TMP2:%.*]] = sext <8 x i16> [[TMP1]] to <8 x i32>
215 ; CHECK-FP16-NEXT:    ret <8 x i32> [[TMP2]]
217   %conv = fptosi <8 x half> %in to <8 x i32>
218   %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)
219   %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
220   ret <8 x i32> %max
224 define i64 @f32_i32_extrause1(float %in) {
225 ; CHECK-LABEL: @f32_i32_extrause1(
226 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64
227 ; CHECK-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647)
228 ; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648)
229 ; CHECK-NEXT:    call void @use(i64 [[MIN]])
230 ; CHECK-NEXT:    ret i64 [[MAX]]
232   %conv = fptosi float %in to i64
233   %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
234   %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)
235   call void @use(i64 %min)
236   ret i64 %max
239 define i64 @f32_i32_extrause2(float %in) {
240 ; CHECK-LABEL: @f32_i32_extrause2(
241 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64
242 ; CHECK-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647)
243 ; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648)
244 ; CHECK-NEXT:    call void @use(i64 [[CONV]])
245 ; CHECK-NEXT:    ret i64 [[MAX]]
247   %conv = fptosi float %in to i64
248   %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
249   %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)
250   call void @use(i64 %conv)
251   ret i64 %max
254 define i64 @f32_i32_invertedconsts(float %in) {
255 ; CHECK-LABEL: @f32_i32_invertedconsts(
256 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64
257 ; CHECK-NEXT:    [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 -2147483648)
258 ; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 2147483647)
259 ; CHECK-NEXT:    ret i64 [[MAX]]
261   %conv = fptosi float %in to i64
262   %min = call i64 @llvm.smin.i64(i64 %conv, i64 -2147483648)
263   %max = call i64 @llvm.smax.i64(i64 %min, i64 2147483647)
264   ret i64 %max
267 define i64 @f32_i32_maxmin(float %in) {
268 ; CHECK-LABEL: @f32_i32_maxmin(
269 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[IN:%.*]])
270 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
271 ; CHECK-NEXT:    ret i64 [[TMP2]]
273   %conv = fptosi float %in to i64
274   %max = call i64 @llvm.smax.i64(i64 %conv, i64 -2147483648)
275   %min = call i64 @llvm.smin.i64(i64 %max, i64 2147483647)
276   ret i64 %min
280 declare void @use(i64)
281 declare i64 @llvm.smin.i64(i64, i64)
282 declare i64 @llvm.smax.i64(i64, i64)
283 declare i32 @llvm.smin.i32(i32, i32)
284 declare i32 @llvm.smax.i32(i32, i32)
285 declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)
286 declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)
287 declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
288 declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)
289 declare <8 x i64> @llvm.smin.v8i64(<8 x i64>, <8 x i64>)
290 declare <8 x i64> @llvm.smax.v8i64(<8 x i64>, <8 x i64>)
291 declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
292 declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
293 declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>)
294 declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>)