diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index 81527d8b98760..a0f12e1bbd2d4 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -2418,4 +2418,9 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in { def SVBFMLSLB_LANE : SInst<"svbfmlslb_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslb_lane", [IsOverloadNone, VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; def SVBFMLSLT_LANE : SInst<"svbfmlslt_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslt_lane", [IsOverloadNone, VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; -} \ No newline at end of file +} + +let SVETargetGuard = "sve2,faminmax", SMETargetGuard = "sme2,faminmax" in { + defm SVAMIN : SInstZPZZ<"svamin", "hfd", "aarch64_sve_famin", "aarch64_sve_famin_u">; + defm SVAMAX : SInstZPZZ<"svamax", "hfd", "aarch64_sve_famax", "aarch64_sve_famax_u">; +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_faminmax.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_faminmax.c new file mode 100644 index 0000000000000..3cf7d99d606f3 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_faminmax.c @@ -0,0 +1,775 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-CPP +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-CPP +// RUN: %clang_cc1 -x c++ -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-CPP + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +faminmax -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +faminmax -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef __ARM_FEATURE_SME +#include "arm_sme.h" +#else +#include "arm_sve.h" +#endif + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +#ifdef __ARM_FEATURE_SME +#define STREAMING __arm_streaming +#else +#define STREAMING +#endif + +// CHECK-LABEL: define dso_local @test_famin_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f16_mu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_f16_m(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f16_xu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_f16_x(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f16_zu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famin_f16_z(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f16_mu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_n_f16_m(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f16_xu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famin_n_f16_x(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f16_zu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famin_n_f16_z(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f32_mu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_f32_m(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f32_xu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_f32_x(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f32_zu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famin_f32_z(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f32_mu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_n_f32_m(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f32_xu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famin_n_f32_x(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f32_zu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famin_n_f32_z(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f64_mu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_f64_m(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f64_xu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_f64_x(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famin_f64_zu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famin_f64_z(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _f64, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f64_mu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_n_f64_m(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f64_xu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famin.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famin_n_f64_x(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famin_n_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famin_n_f64_zu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famin.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famin_n_f64_z(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamin, _n_f64, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f16_mu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_f16_m(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f16_xu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_f16_x(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f16_zu10__SVBool_tu13__SVFloat16_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famax_f16_z(svbool_t pg, svfloat16_t a, svfloat16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f16_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f16_mu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_n_f16_m(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f16, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f16_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f16_xu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv8f16( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat16_t test_famax_n_f16_x(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f16, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f16_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f16_zu10__SVBool_tu13__SVFloat16_tDh( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], half noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, half [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv8f16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat16_t test_famax_n_f16_z(svbool_t pg, svfloat16_t a, float16_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f16, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f32_mu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_f32_m(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f32_xu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_f32_x(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f32_zu10__SVBool_tu13__SVFloat32_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famax_f32_z(svbool_t pg, svfloat32_t a, svfloat32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f32_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f32_mu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_n_f32_m(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f32, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f32_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f32_xu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv4f32( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat32_t test_famax_n_f32_x(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f32, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f32_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f32_zu10__SVBool_tu13__SVFloat32_tf( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], float noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, float [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv4f32( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat32_t test_famax_n_f32_z(svbool_t pg, svfloat32_t a, float32_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f32, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f64_mu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_f64_m(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f64_xu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_f64_x(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z16test_famax_f64_zu10__SVBool_tu13__SVFloat64_tS0_( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[B]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famax_f64_z(svbool_t pg, svfloat64_t a, svfloat64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _f64, _z)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f64_m( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f64_mu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_n_f64_m(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f64, _m)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f64_x( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f64_xu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.famax.u.nxv2f64( [[TMP0]], [[A]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP1]] +// +svfloat64_t test_famax_n_f64_x(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f64, _x)(pg, a, b); +} + +// CHECK-LABEL: define dso_local @test_famax_n_f64_z( +// CHECK-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CHECK-CPP-LABEL: define dso_local @_Z18test_famax_n_f64_zu10__SVBool_tu13__SVFloat64_td( +// CHECK-CPP-SAME: [[PG:%.*]], [[A:%.*]], double noundef [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CPP-NEXT: [[ENTRY:.*:]] +// CHECK-CPP-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG]]) +// CHECK-CPP-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, double [[B]], i64 0 +// CHECK-CPP-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CPP-NEXT: [[TMP1:%.*]] = select [[TMP0]], [[A]], zeroinitializer +// CHECK-CPP-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.famax.nxv2f64( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) +// CHECK-CPP-NEXT: ret [[TMP2]] +// +svfloat64_t test_famax_n_f64_z(svbool_t pg, svfloat64_t a, float64_t b) STREAMING { + return SVE_ACLE_FUNC(svamax, _n_f64, _z)(pg, a, b); +} diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 6727ee69d7b3e..9bce850750f79 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -3785,3 +3785,10 @@ def int_aarch64_sve_pmov_to_vector_lane_zeroing : SVE2_Pred_1VectorArg_Intrinsic def int_aarch64_sme_mopa_nonwide : SME_OuterProduct_Intrinsic; def int_aarch64_sme_mops_nonwide : SME_OuterProduct_Intrinsic; +// SVE2/SME2 - Floating point absolute maximum and minimum + +def int_aarch64_sve_famax : AdvSIMD_Pred2VectorArg_Intrinsic; +def int_aarch64_sve_famax_u : AdvSIMD_Pred2VectorArg_Intrinsic; + +def int_aarch64_sve_famin : AdvSIMD_Pred2VectorArg_Intrinsic; +def int_aarch64_sve_famin_u : AdvSIMD_Pred2VectorArg_Intrinsic; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index af8ddb49b0ac6..4922fb280333b 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4183,9 +4183,11 @@ defm FCVTNT_Z2Z_StoB : sve2_fp8_down_cvt_single<0b11, "fcvtnt", ZZ_s_mul_r>; } // End HasSVE2orSME2, HasFP8 let Predicates = [HasSVE2orSME2, HasFAMINMAX] in { -// FP8 Arithmetic - Predicated Group -defm FAMIN_ZPmZ : sve_fp_2op_p_zds<0b1111, "famin", "", null_frag, DestructiveOther>; -defm FAMAX_ZPmZ : sve_fp_2op_p_zds<0b1110, "famax", "", null_frag, DestructiveOther>; +defm FAMIN_ZPmZ : sve_fp_2op_p_zds<0b1111, "famin", "FAMIN_ZPZZ", int_aarch64_sve_famin, DestructiveBinaryComm>; +defm FAMAX_ZPmZ : sve_fp_2op_p_zds<0b1110, "famax", "FAMAX_ZPZZ", int_aarch64_sve_famax, DestructiveBinaryComm>; + +defm FAMAX_ZPZZ : sve_fp_bin_pred_hfd; +defm FAMIN_ZPZZ : sve_fp_bin_pred_hfd; } // End HasSVE2orSME2, HasFAMINMAX let Predicates = [HasSSVE_FP8FMA] in { diff --git a/llvm/test/CodeGen/AArch64/sve2-intrinsics-faminmax.ll b/llvm/test/CodeGen/AArch64/sve2-intrinsics-faminmax.ll new file mode 100644 index 0000000000000..7d16f8383d968 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve2-intrinsics-faminmax.ll @@ -0,0 +1,115 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mattr=+sve2 < %s | FileCheck %s +; RUN: llc -mattr=+sme2 -force-streaming < %s | FileCheck %s + +target triple = "aarch64-linux" + +define @famin_f16( %pg, %a, %b) #0 { +; CHECK-LABEL: famin_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: famin z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famin.nxv8f16( %pg, %a, %b) + ret %r +} + +define @famin_f32( %pg, %a, %b) #0 { +; CHECK-LABEL: famin_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: famin z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famin.nxv4f32( %pg, %a, %b) + ret %r +} + +define @famin_f64( %pg, %a, %b) #0 { +; CHECK-LABEL: famin_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: famin z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famin.nxv2f64( %pg, %a, %b) + ret %r +} + +define @famin_u_f16( %pg, %a, %b) #0 { +; CHECK-LABEL: famin_u_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: famin z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famin.u.nxv8f16( %pg, %b, %a) + ret %r +} + +define @famin_u_f32( %pg, %a, %b) #0 { +; CHECK-LABEL: famin_u_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: famin z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famin.u.nxv4f32( %pg, %b, %a) + ret %r +} + +define @famin_u_f64( %pg, %a, %b) #0 { +; CHECK-LABEL: famin_u_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: famin z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famin.u.nxv2f64( %pg, %b, %a) + ret %r +} + +define @famax_f16( %pg, %a, %b) #0 { +; CHECK-LABEL: famax_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: famax z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famax.nxv8f16( %pg, %a, %b) + ret %r +} + +define @famax_f32( %pg, %a, %b) #0 { +; CHECK-LABEL: famax_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: famax z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famax.nxv4f32( %pg, %a, %b) + ret %r +} + +define @famax_f64( %pg, %a, %b) #0 { +; CHECK-LABEL: famax_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: famax z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famax.nxv2f64( %pg, %a, %b) + ret %r +} + +define @famax_u_f16( %pg, %a, %b) #0 { +; CHECK-LABEL: famax_u_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: famax z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famax.u.nxv8f16( %pg, %b, %a) + ret %r +} + +define @famax_u_f32( %pg, %a, %b) #0 { +; CHECK-LABEL: famax_u_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: famax z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famax.u.nxv4f32( %pg, %b, %a) + ret %r +} + +define @famax_u_f64( %pg, %a, %b) #0 { +; CHECK-LABEL: famax_u_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: famax z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %r = call @llvm.aarch64.sve.famax.u.nxv2f64( %pg, %b, %a) + ret %r +} + +attributes #0 = { nounwind "target-features" = "+faminmax" }