Skip to content

Commit e4872d7

Browse files
committed
[SveEmitter] Add builtins for svlen
The svlen builtins return the number of elements in a vector and are implemented using `llvm.vscale`. Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D78755
1 parent ce7eb72 commit e4872d7

File tree

3 files changed

+131
-0
lines changed

3 files changed

+131
-0
lines changed

clang/include/clang/Basic/arm_sve.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,8 @@ def SVCNTH : SInst<"svcnth", "n", "", MergeNone, "aarch64_sve_cnth", [IsAppendSV
851851
def SVCNTW : SInst<"svcntw", "n", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone]>;
852852
def SVCNTD : SInst<"svcntd", "n", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone]>;
853853

854+
def SVLEN : SInst<"svlen[_{d}]", "nd", "csilUcUsUiUlhfd", MergeNone>;
855+
854856
////////////////////////////////////////////////////////////////////////////////
855857
// Saturating scalar arithmetic
856858

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7956,6 +7956,25 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
79567956
return nullptr;
79577957
case SVE::BI__builtin_sve_svpfalse_b:
79587958
return ConstantInt::getFalse(Ty);
7959+
7960+
case SVE::BI__builtin_sve_svlen_f16:
7961+
case SVE::BI__builtin_sve_svlen_f32:
7962+
case SVE::BI__builtin_sve_svlen_f64:
7963+
case SVE::BI__builtin_sve_svlen_s8:
7964+
case SVE::BI__builtin_sve_svlen_s16:
7965+
case SVE::BI__builtin_sve_svlen_s32:
7966+
case SVE::BI__builtin_sve_svlen_s64:
7967+
case SVE::BI__builtin_sve_svlen_u8:
7968+
case SVE::BI__builtin_sve_svlen_u16:
7969+
case SVE::BI__builtin_sve_svlen_u32:
7970+
case SVE::BI__builtin_sve_svlen_u64: {
7971+
SVETypeFlags TF(Builtin->TypeModifier);
7972+
auto VTy = cast<llvm::VectorType>(getSVEType(TF));
7973+
auto NumEls = llvm::ConstantInt::get(Ty, VTy->getElementCount().Min);
7974+
7975+
Function *F = CGM.getIntrinsic(Intrinsic::vscale, Ty);
7976+
return Builder.CreateMul(NumEls, Builder.CreateCall(F));
7977+
}
79597978
}
79607979

79617980
/// Should not happen
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
3+
4+
#include <arm_sve.h>
5+
6+
#ifdef SVE_OVERLOADED_FORMS
7+
// A simple used,unused... macro, long enough to represent any SVE builtin.
8+
#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
9+
#else
10+
#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
11+
#endif
12+
13+
uint64_t test_svlen_s8(svint8_t op)
14+
{
15+
// CHECK-LABEL: test_svlen_s8
16+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
17+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 4
18+
// CHECK: ret i64 %[[SHL]]
19+
return SVE_ACLE_FUNC(svlen,_s8,,)(op);
20+
}
21+
22+
uint64_t test_svlen_s16(svint16_t op)
23+
{
24+
// CHECK-LABEL: test_svlen_s16
25+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
26+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 3
27+
// CHECK: ret i64 %[[SHL]]
28+
return SVE_ACLE_FUNC(svlen,_s16,,)(op);
29+
}
30+
31+
uint64_t test_svlen_s32(svint32_t op)
32+
{
33+
// CHECK-LABEL: test_svlen_s32
34+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
35+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 2
36+
// CHECK: ret i64 %[[SHL]]
37+
return SVE_ACLE_FUNC(svlen,_s32,,)(op);
38+
}
39+
40+
uint64_t test_svlen_s64(svint64_t op)
41+
{
42+
// CHECK-LABEL: test_svlen_s64
43+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
44+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 1
45+
// CHECK: ret i64 %[[SHL]]
46+
return SVE_ACLE_FUNC(svlen,_s64,,)(op);
47+
}
48+
49+
uint64_t test_svlen_u8(svuint8_t op)
50+
{
51+
// CHECK-LABEL: test_svlen_u8
52+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
53+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 4
54+
// CHECK: ret i64 %[[SHL]]
55+
return SVE_ACLE_FUNC(svlen,_u8,,)(op);
56+
}
57+
58+
uint64_t test_svlen_u16(svuint16_t op)
59+
{
60+
// CHECK-LABEL: test_svlen_u16
61+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
62+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 3
63+
// CHECK: ret i64 %[[SHL]]
64+
return SVE_ACLE_FUNC(svlen,_u16,,)(op);
65+
}
66+
67+
uint64_t test_svlen_u32(svuint32_t op)
68+
{
69+
// CHECK-LABEL: test_svlen_u32
70+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
71+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 2
72+
// CHECK: ret i64 %[[SHL]]
73+
return SVE_ACLE_FUNC(svlen,_u32,,)(op);
74+
}
75+
76+
uint64_t test_svlen_u64(svuint64_t op)
77+
{
78+
// CHECK-LABEL: test_svlen_u64
79+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
80+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 1
81+
// CHECK: ret i64 %[[SHL]]
82+
return SVE_ACLE_FUNC(svlen,_u64,,)(op);
83+
}
84+
85+
uint64_t test_svlen_f16(svfloat16_t op)
86+
{
87+
// CHECK-LABEL: test_svlen_f16
88+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
89+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 3
90+
// CHECK: ret i64 %[[SHL]]
91+
return SVE_ACLE_FUNC(svlen,_f16,,)(op);
92+
}
93+
94+
uint64_t test_svlen_f32(svfloat32_t op)
95+
{
96+
// CHECK-LABEL: test_svlen_f32
97+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
98+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 2
99+
// CHECK: ret i64 %[[SHL]]
100+
return SVE_ACLE_FUNC(svlen,_f32,,)(op);
101+
}
102+
103+
uint64_t test_svlen_f64(svfloat64_t op)
104+
{
105+
// CHECK-LABEL: test_svlen_f64
106+
// CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64()
107+
// CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 1
108+
// CHECK: ret i64 %[[SHL]]
109+
return SVE_ACLE_FUNC(svlen,_f64,,)(op);
110+
}

0 commit comments

Comments
 (0)