Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / bitcast-function.ll
blobe92d4e5de664af293823542ee59e1db6e64e63e5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -S -passes=instcombine -o - %s | FileCheck %s
3 target datalayout = "e-p:32:32:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v64:64:64-v128:128:128-a0:0:64"
5 define internal <2 x i32> @func_v2i32(<2 x i32> %v) noinline nounwind {
6 ; CHECK-LABEL: define internal <2 x i32> @func_v2i32
7 ; CHECK-SAME: (<2 x i32> [[V:%.*]]) #[[ATTR0:[0-9]+]] {
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    ret <2 x i32> [[V]]
11 entry:
12   ret <2 x i32> %v
15 define internal <2 x float> @func_v2f32(<2 x float> %v) noinline nounwind {
16 ; CHECK-LABEL: define internal <2 x float> @func_v2f32
17 ; CHECK-SAME: (<2 x float> [[V:%.*]]) #[[ATTR0]] {
18 ; CHECK-NEXT:  entry:
19 ; CHECK-NEXT:    ret <2 x float> [[V]]
21 entry:
22   ret <2 x float> %v
25 define internal <4 x float> @func_v4f32(<4 x float> %v) noinline nounwind {
26 ; CHECK-LABEL: define internal <4 x float> @func_v4f32
27 ; CHECK-SAME: (<4 x float> [[V:%.*]]) #[[ATTR0]] {
28 ; CHECK-NEXT:  entry:
29 ; CHECK-NEXT:    ret <4 x float> [[V]]
31 entry:
32   ret <4 x float> %v
35 define internal i32 @func_i32(i32 %v) noinline nounwind {
36 ; CHECK-LABEL: define internal i32 @func_i32
37 ; CHECK-SAME: (i32 [[V:%.*]]) #[[ATTR0]] {
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    ret i32 [[V]]
41 entry:
42   ret i32 %v
45 define internal i64 @func_i64(i64 %v) noinline nounwind {
46 ; CHECK-LABEL: define internal i64 @func_i64
47 ; CHECK-SAME: (i64 [[V:%.*]]) #[[ATTR0]] {
48 ; CHECK-NEXT:  entry:
49 ; CHECK-NEXT:    ret i64 [[V]]
51 entry:
52   ret i64 %v
55 define internal <2 x i64> @func_v2i64(<2 x i64> %v) noinline nounwind {
56 ; CHECK-LABEL: define internal <2 x i64> @func_v2i64
57 ; CHECK-SAME: (<2 x i64> [[V:%.*]]) #[[ATTR0]] {
58 ; CHECK-NEXT:  entry:
59 ; CHECK-NEXT:    ret <2 x i64> [[V]]
61 entry:
62   ret <2 x i64> %v
65 define internal <2 x ptr> @func_v2i32p(<2 x ptr> %v) noinline nounwind {
66 ; CHECK-LABEL: define internal <2 x ptr> @func_v2i32p
67 ; CHECK-SAME: (<2 x ptr> [[V:%.*]]) #[[ATTR0]] {
68 ; CHECK-NEXT:  entry:
69 ; CHECK-NEXT:    ret <2 x ptr> [[V]]
71 entry:
72   ret <2 x ptr> %v
75 ; Valid cases, only bitcast for argument / return type and call underlying function
77 ; Test cast between scalars with same bit sizes
78 ; Sizes match, should only bitcast
79 define void @bitcast_scalar(ptr noalias %source, ptr noalias %dest) nounwind {
80 ; CHECK-LABEL: define void @bitcast_scalar
81 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1:[0-9]+]] {
82 ; CHECK-NEXT:  entry:
83 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SOURCE]], align 8
84 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @func_i32(i32 [[TMP1]]) #[[ATTR1]]
85 ; CHECK-NEXT:    store i32 [[CALL]], ptr [[DEST]], align 8
86 ; CHECK-NEXT:    ret void
88 entry:
89   %tmp = load float, ptr %source, align 8
90   %call = call float @func_i32(float %tmp) nounwind
91   store float %call, ptr %dest, align 8
92   ret void
95 ; Test cast between vectors with same number of elements and bit sizes
96 ; Sizes match, should only bitcast
97 define void @bitcast_vector(ptr noalias %source, ptr noalias %dest) nounwind {
98 ; CHECK-LABEL: define void @bitcast_vector
99 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
100 ; CHECK-NEXT:  entry:
101 ; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i32>, ptr [[SOURCE]], align 8
102 ; CHECK-NEXT:    [[CALL:%.*]] = call <2 x i32> @func_v2i32(<2 x i32> [[TMP1]]) #[[ATTR1]]
103 ; CHECK-NEXT:    store <2 x i32> [[CALL]], ptr [[DEST]], align 8
104 ; CHECK-NEXT:    ret void
106 entry:
107   %tmp = load <2 x float>, ptr %source, align 8
108   %call = call <2 x float> @func_v2i32(<2 x float> %tmp) nounwind
109   store <2 x float> %call, ptr %dest, align 8
110   ret void
113 ; Test cast from vector to scalar with same number of bits
114 ; Sizes match, should only bitcast
115 define void @bitcast_vector_scalar_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
116 ; CHECK-LABEL: define void @bitcast_vector_scalar_same_size
117 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
118 ; CHECK-NEXT:  entry:
119 ; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr [[SOURCE]], align 8
120 ; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_i64(i64 [[TMP1]]) #[[ATTR1]]
121 ; CHECK-NEXT:    store i64 [[CALL]], ptr [[DEST]], align 8
122 ; CHECK-NEXT:    ret void
124 entry:
125   %tmp = load <2 x float>, ptr %source, align 8
126   %call = call <2 x float> @func_i64(<2 x float> %tmp) nounwind
127   store <2 x float> %call, ptr %dest, align 8
128   ret void
131 ; Test cast from scalar to vector with same number of bits
132 define void @bitcast_scalar_vector_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
133 ; CHECK-LABEL: define void @bitcast_scalar_vector_same_size
134 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
135 ; CHECK-NEXT:  entry:
136 ; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x float>, ptr [[SOURCE]], align 8
137 ; CHECK-NEXT:    [[CALL:%.*]] = call <2 x float> @func_v2f32(<2 x float> [[TMP1]]) #[[ATTR1]]
138 ; CHECK-NEXT:    store <2 x float> [[CALL]], ptr [[DEST]], align 8
139 ; CHECK-NEXT:    ret void
141 entry:
142   %tmp = load i64, ptr %source, align 8
143   %call = call i64 @func_v2f32(i64 %tmp) nounwind
144   store i64 %call, ptr %dest, align 8
145   ret void
148 ; Test cast between vectors of pointers
149 define void @bitcast_vector_ptrs_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
150 ; CHECK-LABEL: define void @bitcast_vector_ptrs_same_size
151 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
152 ; CHECK-NEXT:  entry:
153 ; CHECK-NEXT:    [[TMP:%.*]] = load <2 x ptr>, ptr [[SOURCE]], align 8
154 ; CHECK-NEXT:    [[CALL:%.*]] = call <2 x ptr> @func_v2i32p(<2 x ptr> [[TMP]]) #[[ATTR1]]
155 ; CHECK-NEXT:    store <2 x ptr> [[CALL]], ptr [[DEST]], align 8
156 ; CHECK-NEXT:    ret void
158 entry:
159   %tmp = load <2 x ptr>, ptr %source, align 8
160   %call = call <2 x ptr> @func_v2i32p(<2 x ptr> %tmp) nounwind
161   store <2 x ptr> %call, ptr %dest, align 8
162   ret void
165 ; Invalid cases:
167 ; Test cast between scalars with different bit sizes
168 define void @bitcast_mismatch_scalar_size(ptr noalias %source, ptr noalias %dest) nounwind {
169 ; CHECK-LABEL: define void @bitcast_mismatch_scalar_size
170 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
171 ; CHECK-NEXT:  entry:
172 ; CHECK-NEXT:    [[TMP:%.*]] = load float, ptr [[SOURCE]], align 8
173 ; CHECK-NEXT:    [[CALL:%.*]] = call float @func_i64(float [[TMP]]) #[[ATTR1]]
174 ; CHECK-NEXT:    store float [[CALL]], ptr [[DEST]], align 8
175 ; CHECK-NEXT:    ret void
177 entry:
178   %tmp = load float, ptr %source, align 8
179   %call = call float @func_i64(float %tmp) nounwind
180   store float %call, ptr %dest, align 8
181   ret void
184 ; Test cast between vectors with different bit sizes but the
185 ; same number of elements
186 define void @bitcast_mismatch_vector_element_and_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
187 ; CHECK-LABEL: define void @bitcast_mismatch_vector_element_and_bit_size
188 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
189 ; CHECK-NEXT:  entry:
190 ; CHECK-NEXT:    [[TMP:%.*]] = load <2 x float>, ptr [[SOURCE]], align 8
191 ; CHECK-NEXT:    [[CALL:%.*]] = call <2 x float> @func_v2i64(<2 x float> [[TMP]]) #[[ATTR1]]
192 ; CHECK-NEXT:    store <2 x float> [[CALL]], ptr [[DEST]], align 8
193 ; CHECK-NEXT:    ret void
195 entry:
196   %tmp = load <2 x float>, ptr %source, align 8
197   %call = call <2 x float> @func_v2i64(<2 x float> %tmp) nounwind
198   store <2 x float> %call, ptr %dest, align 8
199   ret void
202 ; Test cast between vectors with same number of bits and different
203 ; numbers of elements
204 define void @bitcast_vector_mismatched_number_elements(ptr noalias %source, ptr noalias %dest) nounwind {
205 ; CHECK-LABEL: define void @bitcast_vector_mismatched_number_elements
206 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
207 ; CHECK-NEXT:  entry:
208 ; CHECK-NEXT:    [[TMP:%.*]] = load <4 x float>, ptr [[SOURCE]], align 8
209 ; CHECK-NEXT:    [[CALL:%.*]] = call <4 x float> @func_v2i32(<4 x float> [[TMP]]) #[[ATTR1]]
210 ; CHECK-NEXT:    store <4 x float> [[CALL]], ptr [[DEST]], align 8
211 ; CHECK-NEXT:    ret void
213 entry:
214   %tmp = load <4 x float>, ptr %source, align 8
215   %call = call <4 x float> @func_v2i32(<4 x float> %tmp) nounwind
216   store <4 x float> %call, ptr %dest, align 8
217   ret void
220 ; Test cast between vector and scalar with different number of bits
221 define void @bitcast_vector_scalar_mismatched_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
222 ; CHECK-LABEL: define void @bitcast_vector_scalar_mismatched_bit_size
223 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
224 ; CHECK-NEXT:  entry:
225 ; CHECK-NEXT:    [[TMP:%.*]] = load <4 x float>, ptr [[SOURCE]], align 8
226 ; CHECK-NEXT:    [[CALL:%.*]] = call <4 x float> @func_i64(<4 x float> [[TMP]]) #[[ATTR1]]
227 ; CHECK-NEXT:    store <4 x float> [[CALL]], ptr [[DEST]], align 8
228 ; CHECK-NEXT:    ret void
230 entry:
231   %tmp = load <4 x float>, ptr %source, align 8
232   %call = call <4 x float> @func_i64(<4 x float> %tmp) nounwind
233   store <4 x float> %call, ptr %dest, align 8
234   ret void
237 ; Test cast between vector of pointers and scalar with different number of bits
238 define void @bitcast_vector_ptrs_scalar_mismatched_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
239 ; CHECK-LABEL: define void @bitcast_vector_ptrs_scalar_mismatched_bit_size
240 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
241 ; CHECK-NEXT:  entry:
242 ; CHECK-NEXT:    [[TMP:%.*]] = load <4 x ptr>, ptr [[SOURCE]], align 8
243 ; CHECK-NEXT:    [[CALL:%.*]] = call <4 x ptr> @func_i64(<4 x ptr> [[TMP]]) #[[ATTR1]]
244 ; CHECK-NEXT:    store <4 x ptr> [[CALL]], ptr [[DEST]], align 8
245 ; CHECK-NEXT:    ret void
247 entry:
248   %tmp = load <4 x ptr>, ptr %source, align 8
249   %call = call <4 x ptr> @func_i64(<4 x ptr> %tmp) nounwind
250   store <4 x ptr> %call, ptr %dest, align 8
251   ret void
254 ; Test cast from scalar to vector of pointers with same number of bits
255 ; We don't know the pointer size at this point, so this can't be done
256 define void @bitcast_scalar_vector_ptrs_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
257 ; CHECK-LABEL: define void @bitcast_scalar_vector_ptrs_same_size
258 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
259 ; CHECK-NEXT:  entry:
260 ; CHECK-NEXT:    [[TMP:%.*]] = load i64, ptr [[SOURCE]], align 8
261 ; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_v2i32p(i64 [[TMP]]) #[[ATTR1]]
262 ; CHECK-NEXT:    store i64 [[CALL]], ptr [[DEST]], align 8
263 ; CHECK-NEXT:    ret void
265 entry:
266   %tmp = load i64, ptr %source, align 8
267   %call = call i64 @func_v2i32p(i64 %tmp) nounwind
268   store i64 %call, ptr %dest, align 8
269   ret void
272 ; Test cast between scalar and vector with different number of bits
273 define void @bitcast_scalar_vector_mismatched_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
274 ; CHECK-LABEL: define void @bitcast_scalar_vector_mismatched_bit_size
275 ; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
276 ; CHECK-NEXT:  entry:
277 ; CHECK-NEXT:    [[TMP:%.*]] = load i64, ptr [[SOURCE]], align 8
278 ; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_v4f32(i64 [[TMP]]) #[[ATTR1]]
279 ; CHECK-NEXT:    store i64 [[CALL]], ptr [[DEST]], align 8
280 ; CHECK-NEXT:    ret void
282 entry:
283   %tmp = load i64, ptr %source, align 8
284   %call = call i64 @func_v4f32(i64 %tmp) nounwind
285   store i64 %call, ptr %dest, align 8
286   ret void