comparison clang/test/CodeGen/attr-arm-sve-vector-bits-call.c @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents
children 5f17cb93ff66
comparison
equal deleted inserted replaced
173:0572611fdcc8 207:2e18cbf3894f
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // REQUIRES: aarch64-registered-target
3 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -fallow-half-arguments-and-returns -fno-experimental-new-pass-manager -S -O1 -emit-llvm -o - %s | FileCheck %s
4
5 #include <arm_sve.h>
6
7 #define N __ARM_FEATURE_SVE_BITS
8
9 typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N)));
10 typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N)));
11 typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N)));
12
13 //===----------------------------------------------------------------------===//
14 // Test caller/callee with VLST <-> VLAT
15 //===----------------------------------------------------------------------===//
16
17 // CHECK-LABEL: @sizeless_callee(
18 // CHECK-NEXT: entry:
19 // CHECK-NEXT: ret <vscale x 4 x i32> [[X:%.*]]
20 //
21 svint32_t sizeless_callee(svint32_t x) {
22 return x;
23 }
24
25 // CHECK-LABEL: @fixed_caller(
26 // CHECK-NEXT: entry:
27 // CHECK-NEXT: ret <vscale x 4 x i32> [[X_COERCE:%.*]]
28 //
29 fixed_int32_t fixed_caller(fixed_int32_t x) {
30 return sizeless_callee(x);
31 }
32
33 // CHECK-LABEL: @fixed_callee(
34 // CHECK-NEXT: entry:
35 // CHECK-NEXT: ret <vscale x 4 x i32> [[X_COERCE:%.*]]
36 //
37 fixed_int32_t fixed_callee(fixed_int32_t x) {
38 return x;
39 }
40
41 // CHECK-LABEL: @sizeless_caller(
42 // CHECK-NEXT: entry:
43 // CHECK-NEXT: [[COERCE1:%.*]] = alloca <16 x i32>, align 16
44 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i32>* [[COERCE1]] to <vscale x 4 x i32>*
45 // CHECK-NEXT: store <vscale x 4 x i32> [[X:%.*]], <vscale x 4 x i32>* [[TMP0]], align 16
46 // CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, <16 x i32>* [[COERCE1]], align 16, !tbaa [[TBAA6:![0-9]+]]
47 // CHECK-NEXT: [[CASTSCALABLESVE2:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[TMP1]], i64 0)
48 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE2]]
49 //
50 svint32_t sizeless_caller(svint32_t x) {
51 return fixed_callee(x);
52 }
53
54 //===----------------------------------------------------------------------===//
55 // fixed, fixed
56 //===----------------------------------------------------------------------===//
57
58 // CHECK-LABEL: @call_int32_ff(
59 // CHECK-NEXT: entry:
60 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
61 // CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.sel.nxv4i32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x i32> [[OP1_COERCE:%.*]], <vscale x 4 x i32> [[OP2_COERCE:%.*]])
62 // CHECK-NEXT: ret <vscale x 4 x i32> [[TMP1]]
63 //
64 fixed_int32_t call_int32_ff(svbool_t pg, fixed_int32_t op1, fixed_int32_t op2) {
65 return svsel(pg, op1, op2);
66 }
67
68 // CHECK-LABEL: @call_float64_ff(
69 // CHECK-NEXT: entry:
70 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
71 // CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x double> @llvm.aarch64.sve.sel.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP1_COERCE:%.*]], <vscale x 2 x double> [[OP2_COERCE:%.*]])
72 // CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
73 //
74 fixed_float64_t call_float64_ff(svbool_t pg, fixed_float64_t op1, fixed_float64_t op2) {
75 return svsel(pg, op1, op2);
76 }
77
78 // CHECK-LABEL: @call_bool_ff(
79 // CHECK-NEXT: entry:
80 // CHECK-NEXT: [[OP1:%.*]] = alloca <8 x i8>, align 16
81 // CHECK-NEXT: [[OP2:%.*]] = alloca <8 x i8>, align 16
82 // CHECK-NEXT: [[OP1_ADDR:%.*]] = alloca <8 x i8>, align 16
83 // CHECK-NEXT: [[OP2_ADDR:%.*]] = alloca <8 x i8>, align 16
84 // CHECK-NEXT: [[SAVED_CALL_RVALUE:%.*]] = alloca <vscale x 16 x i1>, align 16
85 // CHECK-NEXT: [[RETVAL_COERCE:%.*]] = alloca <vscale x 16 x i1>, align 16
86 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8>* [[OP1]] to <vscale x 16 x i1>*
87 // CHECK-NEXT: store <vscale x 16 x i1> [[OP1_COERCE:%.*]], <vscale x 16 x i1>* [[TMP0]], align 16
88 // CHECK-NEXT: [[OP11:%.*]] = load <8 x i8>, <8 x i8>* [[OP1]], align 16, !tbaa [[TBAA6]]
89 // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8>* [[OP2]] to <vscale x 16 x i1>*
90 // CHECK-NEXT: store <vscale x 16 x i1> [[OP2_COERCE:%.*]], <vscale x 16 x i1>* [[TMP1]], align 16
91 // CHECK-NEXT: [[OP22:%.*]] = load <8 x i8>, <8 x i8>* [[OP2]], align 16, !tbaa [[TBAA6]]
92 // CHECK-NEXT: store <8 x i8> [[OP11]], <8 x i8>* [[OP1_ADDR]], align 16, !tbaa [[TBAA6]]
93 // CHECK-NEXT: store <8 x i8> [[OP22]], <8 x i8>* [[OP2_ADDR]], align 16, !tbaa [[TBAA6]]
94 // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8>* [[OP1_ADDR]] to <vscale x 16 x i1>*
95 // CHECK-NEXT: [[TMP3:%.*]] = load <vscale x 16 x i1>, <vscale x 16 x i1>* [[TMP2]], align 16, !tbaa [[TBAA6]]
96 // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i8>* [[OP2_ADDR]] to <vscale x 16 x i1>*
97 // CHECK-NEXT: [[TMP5:%.*]] = load <vscale x 16 x i1>, <vscale x 16 x i1>* [[TMP4]], align 16, !tbaa [[TBAA6]]
98 // CHECK-NEXT: [[TMP6:%.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.sel.nxv16i1(<vscale x 16 x i1> [[PG:%.*]], <vscale x 16 x i1> [[TMP3]], <vscale x 16 x i1> [[TMP5]])
99 // CHECK-NEXT: store <vscale x 16 x i1> [[TMP6]], <vscale x 16 x i1>* [[SAVED_CALL_RVALUE]], align 16, !tbaa [[TBAA9:![0-9]+]]
100 // CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = bitcast <vscale x 16 x i1>* [[SAVED_CALL_RVALUE]] to <8 x i8>*
101 // CHECK-NEXT: [[TMP7:%.*]] = load <8 x i8>, <8 x i8>* [[CASTFIXEDSVE]], align 16, !tbaa [[TBAA6]]
102 // CHECK-NEXT: [[RETVAL_0__SROA_CAST:%.*]] = bitcast <vscale x 16 x i1>* [[RETVAL_COERCE]] to <8 x i8>*
103 // CHECK-NEXT: store <8 x i8> [[TMP7]], <8 x i8>* [[RETVAL_0__SROA_CAST]], align 16
104 // CHECK-NEXT: [[TMP8:%.*]] = load <vscale x 16 x i1>, <vscale x 16 x i1>* [[RETVAL_COERCE]], align 16
105 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP8]]
106 //
107 fixed_bool_t call_bool_ff(svbool_t pg, fixed_bool_t op1, fixed_bool_t op2) {
108 return svsel(pg, op1, op2);
109 }
110
111 //===----------------------------------------------------------------------===//
112 // fixed, scalable
113 //===----------------------------------------------------------------------===//
114
115 // CHECK-LABEL: @call_int32_fs(
116 // CHECK-NEXT: entry:
117 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
118 // CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.sel.nxv4i32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x i32> [[OP1_COERCE:%.*]], <vscale x 4 x i32> [[OP2:%.*]])
119 // CHECK-NEXT: ret <vscale x 4 x i32> [[TMP1]]
120 //
121 fixed_int32_t call_int32_fs(svbool_t pg, fixed_int32_t op1, svint32_t op2) {
122 return svsel(pg, op1, op2);
123 }
124
125 // CHECK-LABEL: @call_float64_fs(
126 // CHECK-NEXT: entry:
127 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
128 // CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x double> @llvm.aarch64.sve.sel.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP1_COERCE:%.*]], <vscale x 2 x double> [[OP2:%.*]])
129 // CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
130 //
131 fixed_float64_t call_float64_fs(svbool_t pg, fixed_float64_t op1, svfloat64_t op2) {
132 return svsel(pg, op1, op2);
133 }
134
135 // CHECK-LABEL: @call_bool_fs(
136 // CHECK-NEXT: entry:
137 // CHECK-NEXT: [[OP1:%.*]] = alloca <8 x i8>, align 16
138 // CHECK-NEXT: [[OP1_ADDR:%.*]] = alloca <8 x i8>, align 16
139 // CHECK-NEXT: [[SAVED_CALL_RVALUE:%.*]] = alloca <vscale x 16 x i1>, align 16
140 // CHECK-NEXT: [[RETVAL_COERCE:%.*]] = alloca <vscale x 16 x i1>, align 16
141 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8>* [[OP1]] to <vscale x 16 x i1>*
142 // CHECK-NEXT: store <vscale x 16 x i1> [[OP1_COERCE:%.*]], <vscale x 16 x i1>* [[TMP0]], align 16
143 // CHECK-NEXT: [[OP11:%.*]] = load <8 x i8>, <8 x i8>* [[OP1]], align 16, !tbaa [[TBAA6]]
144 // CHECK-NEXT: store <8 x i8> [[OP11]], <8 x i8>* [[OP1_ADDR]], align 16, !tbaa [[TBAA6]]
145 // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8>* [[OP1_ADDR]] to <vscale x 16 x i1>*
146 // CHECK-NEXT: [[TMP2:%.*]] = load <vscale x 16 x i1>, <vscale x 16 x i1>* [[TMP1]], align 16, !tbaa [[TBAA6]]
147 // CHECK-NEXT: [[TMP3:%.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.sel.nxv16i1(<vscale x 16 x i1> [[PG:%.*]], <vscale x 16 x i1> [[TMP2]], <vscale x 16 x i1> [[OP2:%.*]])
148 // CHECK-NEXT: store <vscale x 16 x i1> [[TMP3]], <vscale x 16 x i1>* [[SAVED_CALL_RVALUE]], align 16, !tbaa [[TBAA9]]
149 // CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = bitcast <vscale x 16 x i1>* [[SAVED_CALL_RVALUE]] to <8 x i8>*
150 // CHECK-NEXT: [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[CASTFIXEDSVE]], align 16, !tbaa [[TBAA6]]
151 // CHECK-NEXT: [[RETVAL_0__SROA_CAST:%.*]] = bitcast <vscale x 16 x i1>* [[RETVAL_COERCE]] to <8 x i8>*
152 // CHECK-NEXT: store <8 x i8> [[TMP4]], <8 x i8>* [[RETVAL_0__SROA_CAST]], align 16
153 // CHECK-NEXT: [[TMP5:%.*]] = load <vscale x 16 x i1>, <vscale x 16 x i1>* [[RETVAL_COERCE]], align 16
154 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP5]]
155 //
156 fixed_bool_t call_bool_fs(svbool_t pg, fixed_bool_t op1, svbool_t op2) {
157 return svsel(pg, op1, op2);
158 }
159
160 //===----------------------------------------------------------------------===//
161 // scalable, scalable
162 //===----------------------------------------------------------------------===//
163
164 // CHECK-LABEL: @call_int32_ss(
165 // CHECK-NEXT: entry:
166 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
167 // CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.sel.nxv4i32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x i32> [[OP1:%.*]], <vscale x 4 x i32> [[OP2:%.*]])
168 // CHECK-NEXT: ret <vscale x 4 x i32> [[TMP1]]
169 //
170 fixed_int32_t call_int32_ss(svbool_t pg, svint32_t op1, svint32_t op2) {
171 return svsel(pg, op1, op2);
172 }
173
174 // CHECK-LABEL: @call_float64_ss(
175 // CHECK-NEXT: entry:
176 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
177 // CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x double> @llvm.aarch64.sve.sel.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP1:%.*]], <vscale x 2 x double> [[OP2:%.*]])
178 // CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
179 //
180 fixed_float64_t call_float64_ss(svbool_t pg, svfloat64_t op1, svfloat64_t op2) {
181 return svsel(pg, op1, op2);
182 }
183
184 // CHECK-LABEL: @call_bool_ss(
185 // CHECK-NEXT: entry:
186 // CHECK-NEXT: [[SAVED_CALL_RVALUE:%.*]] = alloca <vscale x 16 x i1>, align 16
187 // CHECK-NEXT: [[RETVAL_COERCE:%.*]] = alloca <vscale x 16 x i1>, align 16
188 // CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.sel.nxv16i1(<vscale x 16 x i1> [[PG:%.*]], <vscale x 16 x i1> [[OP1:%.*]], <vscale x 16 x i1> [[OP2:%.*]])
189 // CHECK-NEXT: store <vscale x 16 x i1> [[TMP0]], <vscale x 16 x i1>* [[SAVED_CALL_RVALUE]], align 16, !tbaa [[TBAA9]]
190 // CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = bitcast <vscale x 16 x i1>* [[SAVED_CALL_RVALUE]] to <8 x i8>*
191 // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, <8 x i8>* [[CASTFIXEDSVE]], align 16, !tbaa [[TBAA6]]
192 // CHECK-NEXT: [[RETVAL_0__SROA_CAST:%.*]] = bitcast <vscale x 16 x i1>* [[RETVAL_COERCE]] to <8 x i8>*
193 // CHECK-NEXT: store <8 x i8> [[TMP1]], <8 x i8>* [[RETVAL_0__SROA_CAST]], align 16
194 // CHECK-NEXT: [[TMP2:%.*]] = load <vscale x 16 x i1>, <vscale x 16 x i1>* [[RETVAL_COERCE]], align 16
195 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP2]]
196 //
197 fixed_bool_t call_bool_ss(svbool_t pg, svbool_t op1, svbool_t op2) {
198 return svsel(pg, op1, op2);
199 }