Author: Sander de Smalen Date: 2020-05-04T19:50:16+01:00 New Revision: 54fa46aa0a82bd281d0ba31fad69a227de4a622c
URL: https://github.com/llvm/llvm-project/commit/54fa46aa0a82bd281d0ba31fad69a227de4a622c DIFF: https://github.com/llvm/llvm-project/commit/54fa46aa0a82bd281d0ba31fad69a227de4a622c.diff LOG: [SveEmitter] Add builtins for Int & FP reductions This patch adds integer builtins for: - svaddv, svandv, sveorv, svmaxv, svminv, svorv. And FP builtins for: - svadda, svaddv, svmaxv, svmaxnmv, svminv, svminnmv Added: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c Modified: clang/include/clang/Basic/arm_sve.td Removed: ################################################################################ diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index 013357c3de9b..bde26aed43f6 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -705,6 +705,19 @@ defm SVLSR : SInst_SHIFT<"svlsr", "aarch64_sve_lsr", "UcUsUiUl", "UcUsUi">; def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +//////////////////////////////////////////////////////////////////////////////// +// Integer reductions + +def SVADDV_S : SInst<"svaddv[_{d}]", "lPd", "csil", MergeNone, "aarch64_sve_saddv">; +def SVADDV_U : SInst<"svaddv[_{d}]", "nPd", "UcUsUiUl", MergeNone, "aarch64_sve_uaddv">; +def SVANDV : SInst<"svandv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andv">; +def SVEORV : SInst<"sveorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorv">; +def SVMAXV_S : SInst<"svmaxv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_smaxv">; +def SVMAXV_U : SInst<"svmaxv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxv">; +def SVMINV_S : SInst<"svminv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_sminv">; +def SVMINV_U : SInst<"svminv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_uminv">; +def SVORV : SInst<"svorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orv">; + //////////////////////////////////////////////////////////////////////////////// // Integer comparisons @@ -876,6 +889,15 @@ def SVRECPS : SInst<"svrecps[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_fre def SVRSQRTE : SInst<"svrsqrte[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frsqrte_x">; def SVRSQRTS : SInst<"svrsqrts[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frsqrts_x">; +//////////////////////////////////////////////////////////////////////////////// +// Floating-point reductions + +def SVFADDA : SInst<"svadda[_{d}]", "sPsd", "hfd", MergeNone, "aarch64_sve_fadda">; +def SVFADDV : SInst<"svaddv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_faddv">; +def SVFMAXV : SInst<"svmaxv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxv">; +def SVFMAXNMV : SInst<"svmaxnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxnmv">; +def SVFMINV : SInst<"svminv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminv">; +def SVFMINNMV : SInst<"svminnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminnmv">; //////////////////////////////////////////////////////////////////////////////// // Floating-point comparisons diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c new file mode 100644 index 000000000000..6ac6e5d0d618 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c @@ -0,0 +1,38 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +float16_t test_svadda_f16(svbool_t pg, float16_t initial, svfloat16_t op) +{ + // CHECK-LABEL: test_svadda_f16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call half @llvm.aarch64.sve.fadda.nxv8f16(<vscale x 8 x i1> %[[PG]], half %initial, <vscale x 8 x half> %op) + // CHECK: ret half %[[INTRINSIC]] + return SVE_ACLE_FUNC(svadda,_f16,,)(pg, initial, op); +} + +float32_t test_svadda_f32(svbool_t pg, float32_t initial, svfloat32_t op) +{ + // CHECK-LABEL: test_svadda_f32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call float @llvm.aarch64.sve.fadda.nxv4f32(<vscale x 4 x i1> %[[PG]], float %initial, <vscale x 4 x float> %op) + // CHECK: ret float %[[INTRINSIC]] + return SVE_ACLE_FUNC(svadda,_f32,,)(pg, initial, op); +} + +float64_t test_svadda_f64(svbool_t pg, float64_t initial, svfloat64_t op) +{ + // CHECK-LABEL: test_svadda_f64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call double @llvm.aarch64.sve.fadda.nxv2f64(<vscale x 2 x i1> %[[PG]], double %initial, <vscale x 2 x double> %op) + // CHECK: ret double %[[INTRINSIC]] + return SVE_ACLE_FUNC(svadda,_f64,,)(pg, initial, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c new file mode 100644 index 000000000000..0c715f31dbf4 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c @@ -0,0 +1,108 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +int64_t test_svaddv_s8(svbool_t pg, svint8_t op) +{ + // CHECK-LABEL: test_svaddv_s8 + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.saddv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_s8,,)(pg, op); +} + +int64_t test_svaddv_s16(svbool_t pg, svint16_t op) +{ + // CHECK-LABEL: test_svaddv_s16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.saddv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_s16,,)(pg, op); +} + +int64_t test_svaddv_s32(svbool_t pg, svint32_t op) +{ + // CHECK-LABEL: test_svaddv_s32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.saddv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_s32,,)(pg, op); +} + +int64_t test_svaddv_s64(svbool_t pg, svint64_t op) +{ + // CHECK-LABEL: test_svaddv_s64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.saddv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_s64,,)(pg, op); +} + +uint64_t test_svaddv_u8(svbool_t pg, svuint8_t op) +{ + // CHECK-LABEL: test_svaddv_u8 + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.uaddv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_u8,,)(pg, op); +} + +uint64_t test_svaddv_u16(svbool_t pg, svuint16_t op) +{ + // CHECK-LABEL: test_svaddv_u16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.uaddv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_u16,,)(pg, op); +} + +uint64_t test_svaddv_u32(svbool_t pg, svuint32_t op) +{ + // CHECK-LABEL: test_svaddv_u32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.uaddv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_u32,,)(pg, op); +} + +uint64_t test_svaddv_u64(svbool_t pg, svuint64_t op) +{ + // CHECK-LABEL: test_svaddv_u64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.uaddv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_u64,,)(pg, op); +} + +float16_t test_svaddv_f16(svbool_t pg, svfloat16_t op) +{ + // CHECK-LABEL: test_svaddv_f16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call half @llvm.aarch64.sve.faddv.nxv8f16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x half> %op) + // CHECK: ret half %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_f16,,)(pg, op); +} + +float32_t test_svaddv_f32(svbool_t pg, svfloat32_t op) +{ + // CHECK-LABEL: test_svaddv_f32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call float @llvm.aarch64.sve.faddv.nxv4f32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x float> %op) + // CHECK: ret float %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_f32,,)(pg, op); +} + +float64_t test_svaddv_f64(svbool_t pg, svfloat64_t op) +{ + // CHECK-LABEL: test_svaddv_f64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call double @llvm.aarch64.sve.faddv.nxv2f64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x double> %op) + // CHECK: ret double %[[INTRINSIC]] + return SVE_ACLE_FUNC(svaddv,_f64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c new file mode 100644 index 000000000000..eda6afd44de1 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c @@ -0,0 +1,81 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +int8_t test_svandv_s8(svbool_t pg, svint8_t op) +{ + // CHECK-LABEL: test_svandv_s8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.andv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_s8,,)(pg, op); +} + +int16_t test_svandv_s16(svbool_t pg, svint16_t op) +{ + // CHECK-LABEL: test_svandv_s16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.andv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_s16,,)(pg, op); +} + +int32_t test_svandv_s32(svbool_t pg, svint32_t op) +{ + // CHECK-LABEL: test_svandv_s32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.andv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_s32,,)(pg, op); +} + +int64_t test_svandv_s64(svbool_t pg, svint64_t op) +{ + // CHECK-LABEL: test_svandv_s64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.andv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_s64,,)(pg, op); +} + +uint8_t test_svandv_u8(svbool_t pg, svuint8_t op) +{ + // CHECK-LABEL: test_svandv_u8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.andv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_u8,,)(pg, op); +} + +uint16_t test_svandv_u16(svbool_t pg, svuint16_t op) +{ + // CHECK-LABEL: test_svandv_u16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.andv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_u16,,)(pg, op); +} + +uint32_t test_svandv_u32(svbool_t pg, svuint32_t op) +{ + // CHECK-LABEL: test_svandv_u32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.andv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_u32,,)(pg, op); +} + +uint64_t test_svandv_u64(svbool_t pg, svuint64_t op) +{ + // CHECK-LABEL: test_svandv_u64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.andv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svandv,_u64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c new file mode 100644 index 000000000000..cf4447ad52fd --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c @@ -0,0 +1,81 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +int8_t test_sveorv_s8(svbool_t pg, svint8_t op) +{ + // CHECK-LABEL: test_sveorv_s8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.eorv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_s8,,)(pg, op); +} + +int16_t test_sveorv_s16(svbool_t pg, svint16_t op) +{ + // CHECK-LABEL: test_sveorv_s16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.eorv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_s16,,)(pg, op); +} + +int32_t test_sveorv_s32(svbool_t pg, svint32_t op) +{ + // CHECK-LABEL: test_sveorv_s32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.eorv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_s32,,)(pg, op); +} + +int64_t test_sveorv_s64(svbool_t pg, svint64_t op) +{ + // CHECK-LABEL: test_sveorv_s64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.eorv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_s64,,)(pg, op); +} + +uint8_t test_sveorv_u8(svbool_t pg, svuint8_t op) +{ + // CHECK-LABEL: test_sveorv_u8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.eorv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_u8,,)(pg, op); +} + +uint16_t test_sveorv_u16(svbool_t pg, svuint16_t op) +{ + // CHECK-LABEL: test_sveorv_u16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.eorv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_u16,,)(pg, op); +} + +uint32_t test_sveorv_u32(svbool_t pg, svuint32_t op) +{ + // CHECK-LABEL: test_sveorv_u32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.eorv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_u32,,)(pg, op); +} + +uint64_t test_sveorv_u64(svbool_t pg, svuint64_t op) +{ + // CHECK-LABEL: test_sveorv_u64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.eorv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(sveorv,_u64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c new file mode 100644 index 000000000000..1b76fd2a35d2 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c @@ -0,0 +1,38 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +float16_t test_svmaxnmv_f16(svbool_t pg, svfloat16_t op) +{ + // CHECK-LABEL: test_svmaxnmv_f16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call half @llvm.aarch64.sve.fmaxnmv.nxv8f16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x half> %op) + // CHECK: ret half %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxnmv,_f16,,)(pg, op); +} + +float32_t test_svmaxnmv_f32(svbool_t pg, svfloat32_t op) +{ + // CHECK-LABEL: test_svmaxnmv_f32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call float @llvm.aarch64.sve.fmaxnmv.nxv4f32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x float> %op) + // CHECK: ret float %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxnmv,_f32,,)(pg, op); +} + +float64_t test_svmaxnmv_f64(svbool_t pg, svfloat64_t op) +{ + // CHECK-LABEL: test_svmaxnmv_f64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call double @llvm.aarch64.sve.fmaxnmv.nxv2f64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x double> %op) + // CHECK: ret double %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxnmv,_f64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c new file mode 100644 index 000000000000..145fbff7f46c --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c @@ -0,0 +1,108 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +int8_t test_svmaxv_s8(svbool_t pg, svint8_t op) +{ + // CHECK-LABEL: test_svmaxv_s8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.smaxv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_s8,,)(pg, op); +} + +int16_t test_svmaxv_s16(svbool_t pg, svint16_t op) +{ + // CHECK-LABEL: test_svmaxv_s16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.smaxv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_s16,,)(pg, op); +} + +int32_t test_svmaxv_s32(svbool_t pg, svint32_t op) +{ + // CHECK-LABEL: test_svmaxv_s32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.smaxv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_s32,,)(pg, op); +} + +int64_t test_svmaxv_s64(svbool_t pg, svint64_t op) +{ + // CHECK-LABEL: test_svmaxv_s64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.smaxv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_s64,,)(pg, op); +} + +uint8_t test_svmaxv_u8(svbool_t pg, svuint8_t op) +{ + // CHECK-LABEL: test_svmaxv_u8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.umaxv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_u8,,)(pg, op); +} + +uint16_t test_svmaxv_u16(svbool_t pg, svuint16_t op) +{ + // CHECK-LABEL: test_svmaxv_u16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.umaxv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_u16,,)(pg, op); +} + +uint32_t test_svmaxv_u32(svbool_t pg, svuint32_t op) +{ + // CHECK-LABEL: test_svmaxv_u32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.umaxv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_u32,,)(pg, op); +} + +uint64_t test_svmaxv_u64(svbool_t pg, svuint64_t op) +{ + // CHECK-LABEL: test_svmaxv_u64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.umaxv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_u64,,)(pg, op); +} + +float16_t test_svmaxv_f16(svbool_t pg, svfloat16_t op) +{ + // CHECK-LABEL: test_svmaxv_f16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call half @llvm.aarch64.sve.fmaxv.nxv8f16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x half> %op) + // CHECK: ret half %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_f16,,)(pg, op); +} + +float32_t test_svmaxv_f32(svbool_t pg, svfloat32_t op) +{ + // CHECK-LABEL: test_svmaxv_f32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call float @llvm.aarch64.sve.fmaxv.nxv4f32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x float> %op) + // CHECK: ret float %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_f32,,)(pg, op); +} + +float64_t test_svmaxv_f64(svbool_t pg, svfloat64_t op) +{ + // CHECK-LABEL: test_svmaxv_f64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call double @llvm.aarch64.sve.fmaxv.nxv2f64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x double> %op) + // CHECK: ret double %[[INTRINSIC]] + return SVE_ACLE_FUNC(svmaxv,_f64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c new file mode 100644 index 000000000000..7c6904b03c5a --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c @@ -0,0 +1,38 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +float16_t test_svminnmv_f16(svbool_t pg, svfloat16_t op) +{ + // CHECK-LABEL: test_svminnmv_f16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call half @llvm.aarch64.sve.fminnmv.nxv8f16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x half> %op) + // CHECK: ret half %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminnmv,_f16,,)(pg, op); +} + +float32_t test_svminnmv_f32(svbool_t pg, svfloat32_t op) +{ + // CHECK-LABEL: test_svminnmv_f32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call float @llvm.aarch64.sve.fminnmv.nxv4f32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x float> %op) + // CHECK: ret float %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminnmv,_f32,,)(pg, op); +} + +float64_t test_svminnmv_f64(svbool_t pg, svfloat64_t op) +{ + // CHECK-LABEL: test_svminnmv_f64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call double @llvm.aarch64.sve.fminnmv.nxv2f64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x double> %op) + // CHECK: ret double %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminnmv,_f64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c new file mode 100644 index 000000000000..cb3901656c6a --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c @@ -0,0 +1,108 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +int8_t test_svminv_s8(svbool_t pg, svint8_t op) +{ + // CHECK-LABEL: test_svminv_s8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.sminv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_s8,,)(pg, op); +} + +int16_t test_svminv_s16(svbool_t pg, svint16_t op) +{ + // CHECK-LABEL: test_svminv_s16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.sminv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_s16,,)(pg, op); +} + +int32_t test_svminv_s32(svbool_t pg, svint32_t op) +{ + // CHECK-LABEL: test_svminv_s32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.sminv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_s32,,)(pg, op); +} + +int64_t test_svminv_s64(svbool_t pg, svint64_t op) +{ + // CHECK-LABEL: test_svminv_s64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.sminv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_s64,,)(pg, op); +} + +uint8_t test_svminv_u8(svbool_t pg, svuint8_t op) +{ + // CHECK-LABEL: test_svminv_u8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.uminv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_u8,,)(pg, op); +} + +uint16_t test_svminv_u16(svbool_t pg, svuint16_t op) +{ + // CHECK-LABEL: test_svminv_u16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.uminv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_u16,,)(pg, op); +} + +uint32_t test_svminv_u32(svbool_t pg, svuint32_t op) +{ + // CHECK-LABEL: test_svminv_u32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.uminv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_u32,,)(pg, op); +} + +uint64_t test_svminv_u64(svbool_t pg, svuint64_t op) +{ + // CHECK-LABEL: test_svminv_u64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.uminv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_u64,,)(pg, op); +} + +float16_t test_svminv_f16(svbool_t pg, svfloat16_t op) +{ + // CHECK-LABEL: test_svminv_f16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call half @llvm.aarch64.sve.fminv.nxv8f16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x half> %op) + // CHECK: ret half %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_f16,,)(pg, op); +} + +float32_t test_svminv_f32(svbool_t pg, svfloat32_t op) +{ + // CHECK-LABEL: test_svminv_f32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call float @llvm.aarch64.sve.fminv.nxv4f32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x float> %op) + // CHECK: ret float %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_f32,,)(pg, op); +} + +float64_t test_svminv_f64(svbool_t pg, svfloat64_t op) +{ + // CHECK-LABEL: test_svminv_f64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call double @llvm.aarch64.sve.fminv.nxv2f64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x double> %op) + // CHECK: ret double %[[INTRINSIC]] + return SVE_ACLE_FUNC(svminv,_f64,,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c new file mode 100644 index 000000000000..8a512ef8ffe2 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c @@ -0,0 +1,81 @@ +// 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 +// 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 + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +int8_t test_svorv_s8(svbool_t pg, svint8_t op) +{ + // CHECK-LABEL: test_svorv_s8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.orv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_s8,,)(pg, op); +} + +int16_t test_svorv_s16(svbool_t pg, svint16_t op) +{ + // CHECK-LABEL: test_svorv_s16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.orv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_s16,,)(pg, op); +} + +int32_t test_svorv_s32(svbool_t pg, svint32_t op) +{ + // CHECK-LABEL: test_svorv_s32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.orv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_s32,,)(pg, op); +} + +int64_t test_svorv_s64(svbool_t pg, svint64_t op) +{ + // CHECK-LABEL: test_svorv_s64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.orv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_s64,,)(pg, op); +} + +uint8_t test_svorv_u8(svbool_t pg, svuint8_t op) +{ + // CHECK-LABEL: test_svorv_u8 + // CHECK: %[[INTRINSIC:.*]] = call i8 @llvm.aarch64.sve.orv.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %op) + // CHECK: ret i8 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_u8,,)(pg, op); +} + +uint16_t test_svorv_u16(svbool_t pg, svuint16_t op) +{ + // CHECK-LABEL: test_svorv_u16 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i16 @llvm.aarch64.sve.orv.nxv8i16(<vscale x 8 x i1> %[[PG]], <vscale x 8 x i16> %op) + // CHECK: ret i16 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_u16,,)(pg, op); +} + +uint32_t test_svorv_u32(svbool_t pg, svuint32_t op) +{ + // CHECK-LABEL: test_svorv_u32 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i32 @llvm.aarch64.sve.orv.nxv4i32(<vscale x 4 x i1> %[[PG]], <vscale x 4 x i32> %op) + // CHECK: ret i32 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_u32,,)(pg, op); +} + +uint64_t test_svorv_u64(svbool_t pg, svuint64_t op) +{ + // CHECK-LABEL: test_svorv_u64 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: %[[INTRINSIC:.*]] = call i64 @llvm.aarch64.sve.orv.nxv2i64(<vscale x 2 x i1> %[[PG]], <vscale x 2 x i64> %op) + // CHECK: ret i64 %[[INTRINSIC]] + return SVE_ACLE_FUNC(svorv,_u64,,)(pg, op); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits