Skip to content

Commit 68c3774

Browse files
[Clang][LLVM][AArch64] Add support for FCVTXNT, FCVTLT, {B}FCVTNT intrinsics
This patch adds support in Clang for these assembly instructions FCVTXNT, FCVTLT, {B}FCVTNT By implementing these prototypes: // Variant is available for _f64_f32 svfloat32_t svcvtlt_f32[_f16]_z (svbool_t pg, svfloat16_t op); // Variants are available for: // _f32_f64, _bf16_f32 svfloat16_t svcvtnt_f16[_f32]_z (svfloat16_t even, svbool_t pg, svfloat32_t op); svfloat32_t svcvtxnt_f32[_f64]_z (svfloat32_t even, svbool_t pg, svfloat64_t op); according to the ACLE[1] [1] ARM-software/acle#412
1 parent dc8311f commit 68c3774

File tree

7 files changed

+299
-10
lines changed

7 files changed

+299
-10
lines changed

clang/include/clang/Basic/arm_sve.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,18 @@ def SVCVTXNT_F32_F64 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aar
968968
// SVCVTXNT_X_F32_F64 : Implemented as macro by SveEmitter.cpp
969969
}
970970

971+
let SVETargetGuard = "sve2p2|sme2p2", SMETargetGuard = "sve2p2|sme2p2" in {
972+
973+
def SVCVTNT_Z_F16_F32 : SInst<"svcvtnt_f16[_f32]_z", "hhPd", "f", MergeNone, "aarch64_sve_fcvtnt_z_f16f32", [IsOverloadNone, VerifyRuntimeMode]>;
974+
def SVCVTNT_Z_F32_F64 : SInst<"svcvtnt_f32[_f64]_z", "hhPd", "d", MergeNone, "aarch64_sve_fcvtnt_z_f32f64", [IsOverloadNone, VerifyRuntimeMode]>;
975+
def SVCVTNT_Z_BF16_F32 : SInst<"svcvtnt_bf16[_f32]_z", "$$Pd", "f", MergeNone, "aarch64_sve_fcvtnt_z_bf16f32", [IsOverloadNone, VerifyRuntimeMode]>;
976+
977+
def SVCVTXNT_Z_F32_F64 : SInst<"svcvtxnt_f32[_f64]_z", "MMPd", "d", MergeNone, "aarch64_sve_fcvtxnt_z_f32f64", [IsOverloadNone, VerifyRuntimeMode]>;
978+
979+
def SVCVTLT_Z_F32_F16 : SInst<"svcvtlt_f32[_f16]", "dPh", "f", MergeZeroExp, "aarch64_sve_fcvtlt_f32f16", [IsOverloadNone, VerifyRuntimeMode]>;
980+
def SVCVTLT_Z_F64_F32 : SInst<"svcvtlt_f64[_f32]", "dPh", "d", MergeZeroExp, "aarch64_sve_fcvtlt_f64f32", [IsOverloadNone, VerifyRuntimeMode]>;
981+
982+
}
971983
////////////////////////////////////////////////////////////////////////////////
972984
// Permutations and selection
973985

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -target-feature +sve2p2 -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
3+
// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -target-feature +sve2p2 -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
4+
// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve -target-feature +sve2p2 -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
5+
// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve -target-feature +sve2p2 -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
6+
7+
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2p2 -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
8+
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2p2 -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
9+
// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme -target-feature +sme2p2 -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
10+
// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme -target-feature +sme2p2 -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
11+
12+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2p2 -target-feature +sve2p2 \
13+
// RUN: -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
14+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2p2 -target-feature +sve2p2 \
15+
// RUN: -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
16+
//
17+
// REQUIRES: aarch64-registered-target
18+
19+
#include <arm_sve.h>
20+
21+
#ifdef SVE_OVERLOADED_FORMS
22+
// A simple used,unused... macro, long enough to represent any SVE builtin.
23+
#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
24+
#else
25+
#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
26+
#endif
27+
28+
#if defined __ARM_FEATURE_SME
29+
#define MODE_ATTR __arm_streaming
30+
#else
31+
#define MODE_ATTR
32+
#endif
33+
34+
35+
// CHECK-LABEL: @test_svcvtnt_f16_f32_z(
36+
// CHECK-NEXT: entry:
37+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
38+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x half> @llvm.aarch64.sve.fcvtnt.z.f16f32(<vscale x 8 x half> [[INACTIVE:%.*]], <vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
39+
// CHECK-NEXT: ret <vscale x 8 x half> [[TMP1]]
40+
//
41+
// CPP-CHECK-LABEL: @_Z22test_svcvtnt_f16_f32_zu13__SVFloat16_tu10__SVBool_tu13__SVFloat32_t(
42+
// CPP-CHECK-NEXT: entry:
43+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
44+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x half> @llvm.aarch64.sve.fcvtnt.z.f16f32(<vscale x 8 x half> [[INACTIVE:%.*]], <vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
45+
// CPP-CHECK-NEXT: ret <vscale x 8 x half> [[TMP1]]
46+
//
47+
svfloat16_t test_svcvtnt_f16_f32_z(svfloat16_t inactive, svbool_t pg, svfloat32_t op) MODE_ATTR
48+
{
49+
return SVE_ACLE_FUNC(svcvtnt_f16,_f32,_z,)(inactive, pg, op);
50+
}
51+
52+
// CHECK-LABEL: @test_svcvtnt_bf16_f32_z(
53+
// CHECK-NEXT: entry:
54+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
55+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.fcvtnt.z.bf16f32(<vscale x 8 x bfloat> [[INACTIVE:%.*]], <vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
56+
// CHECK-NEXT: ret <vscale x 8 x bfloat> [[TMP1]]
57+
//
58+
// CPP-CHECK-LABEL: @_Z23test_svcvtnt_bf16_f32_zu14__SVBfloat16_tu10__SVBool_tu13__SVFloat32_t(
59+
// CPP-CHECK-NEXT: entry:
60+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
61+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.fcvtnt.z.bf16f32(<vscale x 8 x bfloat> [[INACTIVE:%.*]], <vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
62+
// CPP-CHECK-NEXT: ret <vscale x 8 x bfloat> [[TMP1]]
63+
//
64+
svbfloat16_t test_svcvtnt_bf16_f32_z(svbfloat16_t inactive, svbool_t pg, svfloat32_t op) MODE_ATTR
65+
{
66+
return SVE_ACLE_FUNC(svcvtnt_bf16,_f32,_z,)(inactive, pg, op);
67+
}
68+
69+
// CHECK-LABEL: @test_svcvtnt_f32_f64_z(
70+
// CHECK-NEXT: entry:
71+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
72+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.fcvtnt.z.f32f64(<vscale x 4 x float> [[INACTIVE:%.*]], <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
73+
// CHECK-NEXT: ret <vscale x 4 x float> [[TMP1]]
74+
//
75+
// CPP-CHECK-LABEL: @_Z22test_svcvtnt_f32_f64_zu13__SVFloat32_tu10__SVBool_tu13__SVFloat64_t(
76+
// CPP-CHECK-NEXT: entry:
77+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
78+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.fcvtnt.z.f32f64(<vscale x 4 x float> [[INACTIVE:%.*]], <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
79+
// CPP-CHECK-NEXT: ret <vscale x 4 x float> [[TMP1]]
80+
//
81+
svfloat32_t test_svcvtnt_f32_f64_z(svfloat32_t inactive, svbool_t pg, svfloat64_t op) MODE_ATTR
82+
{
83+
return SVE_ACLE_FUNC(svcvtnt_f32,_f64,_z,)(inactive, pg, op);
84+
}
85+
86+
87+
88+
// CHECK-LABEL: @test_svcvtxnt_f32_f64_z(
89+
// CHECK-NEXT: entry:
90+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
91+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.fcvtxnt.z.f32f64(<vscale x 4 x float> [[INACTIVE:%.*]], <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
92+
// CHECK-NEXT: ret <vscale x 4 x float> [[TMP1]]
93+
//
94+
// CPP-CHECK-LABEL: @_Z23test_svcvtxnt_f32_f64_zu13__SVFloat32_tu10__SVBool_tu13__SVFloat64_t(
95+
// CPP-CHECK-NEXT: entry:
96+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
97+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.fcvtxnt.z.f32f64(<vscale x 4 x float> [[INACTIVE:%.*]], <vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
98+
// CPP-CHECK-NEXT: ret <vscale x 4 x float> [[TMP1]]
99+
//
100+
svfloat32_t test_svcvtxnt_f32_f64_z(svfloat32_t inactive, svbool_t pg, svfloat64_t op) MODE_ATTR
101+
{
102+
return SVE_ACLE_FUNC(svcvtxnt_f32,_f64,_z,)(inactive, pg, op);
103+
}
104+
105+
// CHECK-LABEL: @test_svcvtlt_f32_f16_z(
106+
// CHECK-NEXT: entry:
107+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
108+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.fcvtlt.f32f16(<vscale x 4 x float> zeroinitializer, <vscale x 4 x i1> [[TMP0]], <vscale x 8 x half> [[OP:%.*]])
109+
// CHECK-NEXT: ret <vscale x 4 x float> [[TMP1]]
110+
//
111+
// CPP-CHECK-LABEL: @_Z22test_svcvtlt_f32_f16_zu10__SVBool_tu13__SVFloat16_t(
112+
// CPP-CHECK-NEXT: entry:
113+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
114+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.fcvtlt.f32f16(<vscale x 4 x float> zeroinitializer, <vscale x 4 x i1> [[TMP0]], <vscale x 8 x half> [[OP:%.*]])
115+
// CPP-CHECK-NEXT: ret <vscale x 4 x float> [[TMP1]]
116+
//
117+
svfloat32_t test_svcvtlt_f32_f16_z(svbool_t pg, svfloat16_t op) MODE_ATTR
118+
{
119+
return SVE_ACLE_FUNC(svcvtlt_f32,_f16,_z,)(pg, op);
120+
}
121+
122+
// CHECK-LABEL: @test_svcvtlt_f64_f32_z(
123+
// CHECK-NEXT: entry:
124+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
125+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.fcvtlt.f64f32(<vscale x 2 x double> zeroinitializer, <vscale x 2 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
126+
// CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
127+
//
128+
// CPP-CHECK-LABEL: @_Z22test_svcvtlt_f64_f32_zu10__SVBool_tu13__SVFloat32_t(
129+
// CPP-CHECK-NEXT: entry:
130+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
131+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.fcvtlt.f64f32(<vscale x 2 x double> zeroinitializer, <vscale x 2 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
132+
// CPP-CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
133+
//
134+
svfloat64_t test_svcvtlt_f64_f32_z(svbool_t pg, svfloat32_t op) MODE_ATTR
135+
{
136+
return SVE_ACLE_FUNC(svcvtlt_f64,_f32,_z,)(pg, op);
137+
}
138+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// NOTE: File has been autogenerated by utils/aarch64_builtins_test_generator.py
2+
// RUN: %clang_cc1 %s -fsyntax-only -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -target-feature +sve2p2 -verify
3+
// RUN: %clang_cc1 %s -fsyntax-only -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2p2 -target-feature +sve -verify
4+
// expected-no-diagnostics
5+
6+
// REQUIRES: aarch64-registered-target
7+
8+
#include <arm_sve.h>
9+
10+
// Properties: guard="sve,(sve2p2|sme2p2)" streaming_guard="sme,(sve2p2|sme2p2)" flags="feature-dependent"
11+
12+
void test(void) {
13+
svbfloat16_t svbfloat16_t_val;
14+
svbool_t svbool_t_val;
15+
svfloat16_t svfloat16_t_val;
16+
svfloat32_t svfloat32_t_val;
17+
svfloat64_t svfloat64_t_val;
18+
19+
svcvtlt_f32_f16_z(svbool_t_val, svfloat16_t_val);
20+
svcvtlt_f32_z(svbool_t_val, svfloat16_t_val);
21+
svcvtlt_f64_f32_z(svbool_t_val, svfloat32_t_val);
22+
svcvtlt_f64_z(svbool_t_val, svfloat32_t_val);
23+
svcvtnt_bf16_f32_z(svbfloat16_t_val, svbool_t_val, svfloat32_t_val);
24+
svcvtnt_bf16_z(svbfloat16_t_val, svbool_t_val, svfloat32_t_val);
25+
svcvtnt_f16_f32_z(svfloat16_t_val, svbool_t_val, svfloat32_t_val);
26+
svcvtnt_f16_z(svfloat16_t_val, svbool_t_val, svfloat32_t_val);
27+
svcvtnt_f32_f64_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
28+
svcvtnt_f32_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
29+
svcvtxnt_f32_f64_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
30+
svcvtxnt_f32_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
31+
}
32+
33+
void test_streaming(void) __arm_streaming{
34+
svbfloat16_t svbfloat16_t_val;
35+
svbool_t svbool_t_val;
36+
svfloat16_t svfloat16_t_val;
37+
svfloat32_t svfloat32_t_val;
38+
svfloat64_t svfloat64_t_val;
39+
40+
svcvtlt_f32_f16_z(svbool_t_val, svfloat16_t_val);
41+
svcvtlt_f32_z(svbool_t_val, svfloat16_t_val);
42+
svcvtlt_f64_f32_z(svbool_t_val, svfloat32_t_val);
43+
svcvtlt_f64_z(svbool_t_val, svfloat32_t_val);
44+
svcvtnt_bf16_f32_z(svbfloat16_t_val, svbool_t_val, svfloat32_t_val);
45+
svcvtnt_bf16_z(svbfloat16_t_val, svbool_t_val, svfloat32_t_val);
46+
svcvtnt_f16_f32_z(svfloat16_t_val, svbool_t_val, svfloat32_t_val);
47+
svcvtnt_f16_z(svfloat16_t_val, svbool_t_val, svfloat32_t_val);
48+
svcvtnt_f32_f64_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
49+
svcvtnt_f32_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
50+
svcvtxnt_f32_f64_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
51+
svcvtxnt_f32_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
52+
}
53+
54+
void test_streaming_compatible(void) __arm_streaming_compatible{
55+
svbfloat16_t svbfloat16_t_val;
56+
svbool_t svbool_t_val;
57+
svfloat16_t svfloat16_t_val;
58+
svfloat32_t svfloat32_t_val;
59+
svfloat64_t svfloat64_t_val;
60+
61+
svcvtlt_f32_f16_z(svbool_t_val, svfloat16_t_val);
62+
svcvtlt_f32_z(svbool_t_val, svfloat16_t_val);
63+
svcvtlt_f64_f32_z(svbool_t_val, svfloat32_t_val);
64+
svcvtlt_f64_z(svbool_t_val, svfloat32_t_val);
65+
svcvtnt_bf16_f32_z(svbfloat16_t_val, svbool_t_val, svfloat32_t_val);
66+
svcvtnt_bf16_z(svbfloat16_t_val, svbool_t_val, svfloat32_t_val);
67+
svcvtnt_f16_f32_z(svfloat16_t_val, svbool_t_val, svfloat32_t_val);
68+
svcvtnt_f16_z(svfloat16_t_val, svbool_t_val, svfloat32_t_val);
69+
svcvtnt_f32_f64_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
70+
svcvtnt_f32_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
71+
svcvtxnt_f32_f64_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
72+
svcvtxnt_f32_z(svfloat32_t_val, svbool_t_val, svfloat64_t_val);
73+
}

llvm/include/llvm/IR/IntrinsicsAArch64.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,6 +2211,7 @@ def int_aarch64_sve_fcvtzs_i64f32 : Builtin_SVCVT<llvm_nxv2i64_ty, llvm_nxv2i1
22112211

22122212
def int_aarch64_sve_fcvt_bf16f32_v2 : Builtin_SVCVT<llvm_nxv8bf16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
22132213
def int_aarch64_sve_fcvtnt_bf16f32_v2 : Builtin_SVCVT<llvm_nxv8bf16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
2214+
def int_aarch64_sve_fcvtnt_z_bf16f32 : Builtin_SVCVT<llvm_nxv8bf16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
22142215

22152216
def int_aarch64_sve_fcvtzu_i32f16 : Builtin_SVCVT<llvm_nxv4i32_ty, llvm_nxv4i1_ty, llvm_nxv8f16_ty>;
22162217
def int_aarch64_sve_fcvtzu_i32f64 : Builtin_SVCVT<llvm_nxv4i32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
@@ -2228,10 +2229,13 @@ def int_aarch64_sve_fcvt_f64f32 : Builtin_SVCVT<llvm_nxv2f64_ty, llvm_nxv2i1
22282229
def int_aarch64_sve_fcvtlt_f32f16 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv4i1_ty, llvm_nxv8f16_ty>;
22292230
def int_aarch64_sve_fcvtlt_f64f32 : Builtin_SVCVT<llvm_nxv2f64_ty, llvm_nxv2i1_ty, llvm_nxv4f32_ty>;
22302231
def int_aarch64_sve_fcvtnt_f16f32 : Builtin_SVCVT<llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
2232+
def int_aarch64_sve_fcvtnt_z_f16f32 : Builtin_SVCVT<llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
22312233
def int_aarch64_sve_fcvtnt_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
2234+
def int_aarch64_sve_fcvtnt_z_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
22322235

2233-
def int_aarch64_sve_fcvtx_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
2234-
def int_aarch64_sve_fcvtxnt_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
2236+
def int_aarch64_sve_fcvtx_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
2237+
def int_aarch64_sve_fcvtxnt_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
2238+
def int_aarch64_sve_fcvtxnt_z_f32f64 : Builtin_SVCVT<llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
22352239

22362240
def int_aarch64_sve_scvtf_f16i32 : Builtin_SVCVT<llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4i32_ty>;
22372241
def int_aarch64_sve_scvtf_f16i64 : Builtin_SVCVT<llvm_nxv8f16_ty, llvm_nxv2i1_ty, llvm_nxv2i64_ty>;

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,17 +4552,17 @@ let Predicates = [HasSVE2p2_or_SME2p2] in {
45524552
defm FCVT_ZPzZ : sve_fp_z2op_p_zd_b_0<"fcvt", "int_aarch64_sve_fcvt">;
45534553

45544554
// SVE2p2 floating-point convert precision down (placing odd), zeroing predicate
4555-
defm FCVTNT_ZPzZ : sve2_fp_convert_down_narrow_z<"fcvtnt">;
4556-
def FCVTXNT_ZPzZ : sve2_fp_convert_precision<0b0010, 0b0, "fcvtxnt", ZPR32, ZPR64, /*destructive*/ true>;
4555+
defm FCVTNT_ZPzZ : sve2_fp_convert_down_narrow_z<"fcvtnt", "int_aarch64_sve_fcvtnt_z">;
4556+
defm FCVTXNT_ZPzZ : sve_float_convert_top<"fcvtxnt", int_aarch64_sve_fcvtxnt_z_f32f64>;
45574557
// Placing even
45584558
defm FCVTX_ZPzZ : sve_fp_z2op_p_zd<"fcvtx", int_aarch64_sve_fcvtx_f32f64>;
45594559

45604560
// SVE2p2 floating-point convert precision up, zeroing predicate
45614561
defm FCVTLT_ZPzZ : sve2_fp_convert_up_long_z<"fcvtlt", "int_aarch64_sve_fcvtlt">;
45624562

45634563
// SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate
4564-
def BFCVTNT_ZPzZ : sve2_fp_convert_precision<0b1010, 0b0, "bfcvtnt", ZPR16, ZPR32, /*destructive*/ true>;
4565-
defm BFCVT_ZPzZ_StoH : sve_fp_z2op_p_zd_bfcvt<"bfcvt", int_aarch64_sve_fcvt_bf16f32_v2>;
4564+
defm BFCVTNT_ZPzZ_StoH : sve_bfloat_convert_top<"bfcvtnt", int_aarch64_sve_fcvtnt_z_bf16f32, 0b0, true>;
4565+
defm BFCVT_ZPzZ_StoH : sve_fp_z2op_p_zd_bfcvt<"bfcvt", int_aarch64_sve_fcvt_bf16f32_v2>;
45664566

45674567
// Floating-point convert to integer, zeroing predicate
45684568
defm FCVTZS_ZPzZ : sve_fp_z2op_p_zd_d<0b0, "fcvtzs", "int_aarch64_sve_fcvtzs", AArch64fcvtzs_mt>;

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,9 +2907,12 @@ multiclass sve2_fp_convert_up_long_z<string asm, string op> {
29072907
defm : SVE_3_Op_UndefZero_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
29082908
}
29092909

2910-
multiclass sve2_fp_convert_down_narrow_z<string asm> {
2910+
multiclass sve2_fp_convert_down_narrow_z<string asm, string op> {
29112911
def _StoH : sve2_fp_convert_precision<0b1000, 0b0, asm, ZPR16, ZPR32, /*destructive*/ true>;
29122912
def _DtoS : sve2_fp_convert_precision<0b1110, 0b0, asm, ZPR32, ZPR64, /*destructive*/ true>;
2913+
2914+
def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2915+
def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
29132916
}
29142917

29152918
//===----------------------------------------------------------------------===//
@@ -9551,10 +9554,16 @@ multiclass sve_bfloat_convert<string asm, SDPatternOperator op, SDPatternOperato
95519554
def : SVE_1_Op_Passthru_Round_Pat<nxv2bf16, ir_op, nxv2i1, nxv2f32, !cast<Instruction>(NAME)>;
95529555
}
95539556

9554-
multiclass sve_bfloat_convert_top<string asm, SDPatternOperator op> {
9555-
def NAME : sve2_fp_convert_precision<0b1010, 0b1, asm, ZPR16, ZPR32>;
9557+
multiclass sve_bfloat_convert_top<string asm, SDPatternOperator ir_op, bit op = true, bit destructive = op> {
9558+
def NAME : sve2_fp_convert_precision<0b1010, op, asm, ZPR16, ZPR32, destructive>;
95569559

9557-
def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv4i1, nxv4f32, !cast<Instruction>(NAME)>;
9560+
def : SVE_3_Op_Pat<nxv8bf16, ir_op, nxv8bf16, nxv4i1, nxv4f32, !cast<Instruction>(NAME)>;
9561+
}
9562+
9563+
multiclass sve_float_convert_top<string asm, SDPatternOperator ir_op> {
9564+
def _StoD : sve2_fp_convert_precision<0b0010, 0b0, asm, ZPR32, ZPR64, /*destructive*/ true>;
9565+
9566+
def : SVE_3_Op_Pat<nxv4f32, ir_op, nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _StoD)>;
95589567
}
95599568

95609569
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)