Skip to content

Commit 60126e9

Browse files
authored
[CIR][CIRGen][Builtin][Neon] Lower neon_vrnd32x (#1388)
Lower neon_vrnd32x
1 parent e607e3f commit 60126e9

File tree

2 files changed

+158
-6
lines changed

2 files changed

+158
-6
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -2619,6 +2619,14 @@ mlir::Value CIRGenFunction::emitCommonNeonBuiltinExpr(
26192619
: "aarch64.neon.srhadd";
26202620
break;
26212621
}
2622+
case NEON::BI__builtin_neon_vrnd32x_f32:
2623+
case NEON::BI__builtin_neon_vrnd32xq_f32:
2624+
case NEON::BI__builtin_neon_vrnd32x_f64:
2625+
case NEON::BI__builtin_neon_vrnd32xq_f64: {
2626+
intrincsName = "aarch64.neon.frint32x";
2627+
argTypes.push_back(vTy);
2628+
break;
2629+
}
26222630
case NEON::BI__builtin_neon_vshl_v:
26232631
case NEON::BI__builtin_neon_vshlq_v: {
26242632
return builder.create<cir::ShiftOp>(
@@ -4186,12 +4194,6 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
41864194
case NEON::BI__builtin_neon_vrndh_f16: {
41874195
llvm_unreachable("NEON::BI__builtin_neon_vrndh_f16 NYI");
41884196
}
4189-
case NEON::BI__builtin_neon_vrnd32x_f32:
4190-
case NEON::BI__builtin_neon_vrnd32xq_f32:
4191-
case NEON::BI__builtin_neon_vrnd32x_f64:
4192-
case NEON::BI__builtin_neon_vrnd32xq_f64: {
4193-
llvm_unreachable("NEON::BI__builtin_neon_vrnd32xq_f64 NYI");
4194-
}
41954197
case NEON::BI__builtin_neon_vrnd32z_f32:
41964198
case NEON::BI__builtin_neon_vrnd32zq_f32:
41974199
case NEON::BI__builtin_neon_vrnd32z_f64:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 -target-feature +v8.5a \
2+
// RUN: -fclangir -disable-O0-optnone \
3+
// RUN: -flax-vector-conversions=none -emit-cir -o %t.cir %s
4+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
5+
6+
// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 -target-feature +v8.5a \
7+
// RUN: -fclangir -disable-O0-optnone \
8+
// RUN: -flax-vector-conversions=none -emit-llvm -fno-clangir-call-conv-lowering -o - %s \
9+
// RUN: | opt -S -passes=mem2reg,simplifycfg -o %t.ll
10+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
11+
12+
// REQUIRES: aarch64-registered-target || arm-registered-target
13+
14+
// This test mimics clang/test/CodeGen/AArch64/v8.2a-neon-frint3264-intrinsics.c, which eventually
15+
// CIR shall be able to support fully. Since this is going to take some time to converge,
16+
// the unsupported/NYI code is commented out, so that we can incrementally improve this.
17+
// The NYI filecheck used contains the LLVM output from OG codegen that should guide the
18+
// correct result when implementing this into the CIR pipeline.
19+
20+
#include <arm_neon.h>
21+
22+
float32x2_t test_vrnd32x_f32(float32x2_t a) {
23+
return vrnd32x_f32(a);
24+
25+
// CIR-LABEL: vrnd32x_f32
26+
// CIR: [[TMP0:%.*]] = cir.llvm.intrinsic "aarch64.neon.frint32x" {{.*}} : (!cir.vector<!cir.float x 2>) -> !cir.vector<!cir.float x 2>
27+
28+
// LLVM-LABEL: @test_vrnd32x_f32
29+
// LLVM: [[RND:%.*]] = call <2 x float> @llvm.aarch64.neon.frint32x.v2f32(<2 x float> %0)
30+
// LLVM: ret <2 x float> [[RND]]
31+
}
32+
33+
34+
float32x4_t test_vrnd32xq_f32(float32x4_t a) {
35+
return vrnd32xq_f32(a);
36+
37+
// CIR-LABEL: vrnd32xq_f32
38+
// CIR: [[TMP0:%.*]] = cir.llvm.intrinsic "aarch64.neon.frint32x" {{.*}} : (!cir.vector<!cir.float x 4>) -> !cir.vector<!cir.float x 4>
39+
40+
// LLVM-LABEL: @test_vrnd32xq_f32
41+
// LLVM: [[RND:%.*]] = call <4 x float> @llvm.aarch64.neon.frint32x.v4f32(<4 x float> %0)
42+
// LLVM: ret <4 x float> [[RND]]
43+
}
44+
45+
// CHECK-LABEL: test_vrnd32z_f32
46+
// CHECK: [[RND:%.*]] = call <2 x float> @llvm.aarch64.neon.frint32z.v2f32(<2 x float> %a)
47+
// CHECK: ret <2 x float> [[RND]]
48+
// float32x2_t test_vrnd32z_f32(float32x2_t a) {
49+
// return vrnd32z_f32(a);
50+
// }
51+
52+
// CHECK-LABEL: test_vrnd32zq_f32
53+
// CHECK: [[RND:%.*]] = call <4 x float> @llvm.aarch64.neon.frint32z.v4f32(<4 x float> %a)
54+
// CHECK: ret <4 x float> [[RND]]
55+
// float32x4_t test_vrnd32zq_f32(float32x4_t a) {
56+
// return vrnd32zq_f32(a);
57+
// }
58+
59+
// CHECK-LABEL: test_vrnd64x_f32
60+
// CHECK: [[RND:%.*]] = call <2 x float> @llvm.aarch64.neon.frint64x.v2f32(<2 x float> %a)
61+
// CHECK: ret <2 x float> [[RND]]
62+
// float32x2_t test_vrnd64x_f32(float32x2_t a) {
63+
// return vrnd64x_f32(a);
64+
// }
65+
66+
// CHECK-LABEL: test_vrnd64xq_f32
67+
// CHECK: [[RND:%.*]] = call <4 x float> @llvm.aarch64.neon.frint64x.v4f32(<4 x float> %a)
68+
// CHECK: ret <4 x float> [[RND]]
69+
// float32x4_t test_vrnd64xq_f32(float32x4_t a) {
70+
// return vrnd64xq_f32(a);
71+
// }
72+
73+
// CHECK-LABEL: test_vrnd64z_f32
74+
// CHECK: [[RND:%.*]] = call <2 x float> @llvm.aarch64.neon.frint64z.v2f32(<2 x float> %a)
75+
// CHECK: ret <2 x float> [[RND]]
76+
// float32x2_t test_vrnd64z_f32(float32x2_t a) {
77+
// return vrnd64z_f32(a);
78+
// }
79+
80+
// CHECK-LABEL: test_vrnd64zq_f32
81+
// CHECK: [[RND:%.*]] = call <4 x float> @llvm.aarch64.neon.frint64z.v4f32(<4 x float> %a)
82+
// CHECK: ret <4 x float> [[RND]]
83+
// float32x4_t test_vrnd64zq_f32(float32x4_t a) {
84+
// return vrnd64zq_f32(a);
85+
// }
86+
87+
float64x1_t test_vrnd32x_f64(float64x1_t a) {
88+
return vrnd32x_f64(a);
89+
90+
// CIR-LABEL: vrnd32x_f64
91+
// CIR: [[TMP0:%.*]] = cir.llvm.intrinsic "aarch64.neon.frint32x" {{.*}} : (!cir.vector<!cir.double x 1>) -> !cir.vector<!cir.double x 1>
92+
93+
// LLVM-LABEL: @test_vrnd32x_f64
94+
// LLVM: [[RND:%.*]] = call <1 x double> @llvm.aarch64.neon.frint32x.v1f64(<1 x double> %0)
95+
// LLVM: ret <1 x double> [[RND]]
96+
}
97+
98+
99+
float64x2_t test_vrnd32xq_f64(float64x2_t a) {
100+
return vrnd32xq_f64(a);
101+
102+
// CIR-LABEL: vrnd32xq_f64
103+
// CIR: [[TMP0:%.*]] = cir.llvm.intrinsic "aarch64.neon.frint32x" {{.*}} : (!cir.vector<!cir.double x 2>) -> !cir.vector<!cir.double x 2>
104+
105+
// LLVM-LABEL: @test_vrnd32xq_f64
106+
// LLVM: [[RND:%.*]] = call <2 x double> @llvm.aarch64.neon.frint32x.v2f64(<2 x double> %0)
107+
// LLVM: ret <2 x double> [[RND]]
108+
}
109+
110+
// CHECK-LABEL: test_vrnd32z_f64
111+
// CHECK: [[RND:%.*]] = call <1 x double> @llvm.aarch64.neon.frint32z.v1f64(<1 x double> %a)
112+
// CHECK: ret <1 x double> [[RND]]
113+
// float64x1_t test_vrnd32z_f64(float64x1_t a) {
114+
// return vrnd32z_f64(a);
115+
// }
116+
117+
// CHECK-LABEL: test_vrnd32zq_f64
118+
// CHECK: [[RND:%.*]] = call <2 x double> @llvm.aarch64.neon.frint32z.v2f64(<2 x double> %a)
119+
// CHECK: ret <2 x double> [[RND]]
120+
// float64x2_t test_vrnd32zq_f64(float64x2_t a) {
121+
// return vrnd32zq_f64(a);
122+
// }
123+
124+
// CHECK-LABEL: test_vrnd64x_f64
125+
// CHECK: [[RND:%.*]] = call <1 x double> @llvm.aarch64.neon.frint64x.v1f64(<1 x double> %a)
126+
// CHECK: ret <1 x double> [[RND]]
127+
// float64x1_t test_vrnd64x_f64(float64x1_t a) {
128+
// return vrnd64x_f64(a);
129+
// }
130+
131+
// CHECK-LABEL: test_vrnd64xq_f64
132+
// CHECK: [[RND:%.*]] = call <2 x double> @llvm.aarch64.neon.frint64x.v2f64(<2 x double> %a)
133+
// CHECK: ret <2 x double> [[RND]]
134+
// float64x2_t test_vrnd64xq_f64(float64x2_t a) {
135+
// return vrnd64xq_f64(a);
136+
// }
137+
138+
// CHECK-LABEL: test_vrnd64z_f64
139+
// CHECK: [[RND:%.*]] = call <1 x double> @llvm.aarch64.neon.frint64z.v1f64(<1 x double> %a)
140+
// CHECK: ret <1 x double> [[RND]]
141+
// float64x1_t test_vrnd64z_f64(float64x1_t a) {
142+
// return vrnd64z_f64(a);
143+
// }
144+
145+
// CHECK-LABEL: test_vrnd64zq_f64
146+
// CHECK: [[RND:%.*]] = call <2 x double> @llvm.aarch64.neon.frint64z.v2f64(<2 x double> %a)
147+
// CHECK: ret <2 x double> [[RND]]
148+
// float64x2_t test_vrnd64zq_f64(float64x2_t a) {
149+
// return vrnd64zq_f64(a);
150+
// }

0 commit comments

Comments
 (0)