[flang-commits] [clang] [flang] [llvm] Initial support for vectorization using HVML (Hygon vector math library) (PR #219098)
Xiaomeng Zhang via flang-commits
flang-commits at lists.llvm.org
Sat Oct 10 00:59:49 PDT 2026
https://github.com/JacketPants updated https://github.com/llvm/llvm-project/pull/219098
>From 1147b9f97a14ca27a85d26d40d0daf90dbf6ec2f Mon Sep 17 00:00:00 2001
From: zhangxiaomeng <zhangxiaomeng at hygon.cn>
Date: Wed, 26 Aug 2026 20:18:57 +0800
Subject: [PATCH] Initial support for vectorization using HVML (Hygon vector
math library)
Add the Hygon vector math library (HVML) as a new -fveclib backend, mapping 16 libm functions to hvml_* vector calls, and wire the option through the clang and flang drivers.
---
clang/include/clang/Options/Options.td | 4 +-
clang/lib/Driver/ToolChains/Clang.cpp | 5 +
clang/lib/Driver/ToolChains/CommonArgs.cpp | 1 +
clang/lib/Driver/ToolChains/Flang.cpp | 5 +
clang/test/Driver/autocomplete.c | 1 +
clang/test/Driver/fveclib.c | 15 +
flang/lib/Frontend/CompilerInvocation.cpp | 1 +
flang/test/Driver/fveclib-codegen.f90 | 2 +
flang/test/Driver/fveclib.f90 | 4 +
llvm/docs/Vectorizers.md | 2 +-
llvm/include/llvm/Analysis/VecFuncs.def | 215 +++
.../llvm/Frontend/Driver/CodeGenOptions.h | 3 +-
llvm/include/llvm/IR/RuntimeLibcalls.td | 71 +
llvm/include/llvm/IR/SystemLibraries.h | 3 +-
llvm/lib/Analysis/TargetLibraryInfo.cpp | 12 +
llvm/lib/CodeGen/CommandFlags.cpp | 4 +-
llvm/lib/Frontend/Driver/CodeGenOptions.cpp | 2 +
.../Generic/replace-intrinsics-with-veclib.ll | 11 +
.../LoopVectorize/X86/hvml-calls-finite.ll | 646 +++++++
.../LoopVectorize/X86/hvml-calls.ll | 1681 +++++++++++++++++
.../Transforms/SLPVectorizer/X86/sin-sqrt.ll | 17 +
llvm/test/Transforms/Util/add-TLI-mappings.ll | 20 +
22 files changed, 2719 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/Transforms/LoopVectorize/X86/hvml-calls-finite.ll
create mode 100644 llvm/test/Transforms/LoopVectorize/X86/hvml-calls.ll
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index eb5a009b5628ce..7833acf853def0 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3979,10 +3979,10 @@ def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>,
"Use the given vector functions library.\n"
" Note: -fveclib={ArmPL,SLEEF,libmvec} implies -fno-math-errno.\n"
" Note: -fveclib=libmvec on AArch64 requires GLIBC 2.40 or newer.">,
- Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,none">,
+ Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,HVML,none">,
NormalizedValuesScope<"llvm::driver::VectorLibrary">,
NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF",
- "Darwin_libsystem_m", "ArmPL", "AMDLIBM", "NoLibrary"]>,
+ "Darwin_libsystem_m", "ArmPL", "AMDLIBM", "HVML", "NoLibrary"]>,
MarshallingInfoEnum<CodeGenOpts<"VecLib">, "NoLibrary">;
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
Alias<flax_vector_conversions_EQ>, AliasArgs<["none"]>;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index dabc8c8d964d6e..30a08ca075c622 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6027,6 +6027,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
+ } else if (Name == "HVML") {
+ // HVML is only available on x86_64 (Hygon CPUs are 64-bit only).
+ if (Triple.getArch() != llvm::Triple::x86_64)
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << Name << Triple.getArchName();
} else if (Name == "libmvec") {
if (Triple.getArch() != llvm::Triple::x86 &&
Triple.getArch() != llvm::Triple::x86_64 &&
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 74e27bf8b9cdec..37da8c373c34ad 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1137,6 +1137,7 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
.Case("SLEEF", "sleefgnuabi")
.Case("Darwin_libsystem_m", "Darwin_libsystem_m")
.Case("ArmPL", "ArmPL")
+ .Case("HVML", "HVML")
.Case("none", "none")
.Default(std::nullopt);
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 7e7ac97b8b0e5e..dec4f92aa42983 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -748,6 +748,11 @@ void Flang::addTargetOptions(const ArgList &Args, ArgStringList &CmdArgs,
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
+ } else if (Name == "HVML") {
+ // HVML is only available on x86_64 (Hygon CPUs are 64-bit only).
+ if (Triple.getArch() != llvm::Triple::x86_64)
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << Name << Triple.getArchName();
} else if (Name == "libmvec") {
if (Triple.getArch() != llvm::Triple::x86 &&
Triple.getArch() != llvm::Triple::x86_64 &&
diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c
index 297d2e40d6d83a..678a169a0d0c90 100644
--- a/clang/test/Driver/autocomplete.c
+++ b/clang/test/Driver/autocomplete.c
@@ -84,6 +84,7 @@
// FVECLIBALL-NEXT: AMDLIBM
// FVECLIBALL-NEXT: ArmPL
// FVECLIBALL-NEXT: Darwin_libsystem_m
+// FVECLIBALL-NEXT: HVML
// FVECLIBALL-NEXT: libmvec
// FVECLIBALL-NEXT: MASSV
// FVECLIBALL-NEXT: none
diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c
index c57e9aa7a3cc23..661718f21c014a 100644
--- a/clang/test/Driver/fveclib.c
+++ b/clang/test/Driver/fveclib.c
@@ -3,6 +3,7 @@
// RUN: %clang -### -c --target=x86_64-unknown-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-libmvec %s
// RUN: %clang -### -c --target=aarch64-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-LIBMVEC-AARCH64 %s
// RUN: %clang -### -c --target=x86_64-unknown-linux-gnu -fveclib=AMDLIBM %s 2>&1 | FileCheck --check-prefix=CHECK-AMDLIBM %s
+// RUN: %clang -### -c --target=x86_64-unknown-linux-gnu -fveclib=HVML %s 2>&1 | FileCheck --check-prefix=CHECK-HVML %s
// RUN: %clang -### -c -fveclib=MASSV %s 2>&1 | FileCheck --check-prefix=CHECK-MASSV %s
// RUN: %clang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck --check-prefix=CHECK-DARWIN_LIBSYSTEM_M %s
// RUN: %clang -### -c --target=aarch64 -fveclib=SLEEF %s 2>&1 | FileCheck --check-prefix=CHECK-SLEEF %s
@@ -15,6 +16,7 @@
// CHECK-libmvec: "-fveclib=libmvec"
// CHECK-LIBMVEC-AARCH64: "-fveclib=libmvec"
// CHECK-AMDLIBM: "-fveclib=AMDLIBM"
+// CHECK-HVML: "-fveclib=HVML"
// CHECK-MASSV: "-fveclib=MASSV"
// CHECK-DARWIN_LIBSYSTEM_M: "-fveclib=Darwin_libsystem_m"
// CHECK-SLEEF: "-fveclib=SLEEF"
@@ -25,8 +27,11 @@
// RUN: not %clang --target=x86 -c -fveclib=SLEEF %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
// RUN: not %clang --target=x86 -c -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not %clang --target=x86 -c -fveclib=HVML %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
// RUN: not %clang --target=aarch64 -c -fveclib=SVML %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
// RUN: not %clang --target=aarch64 -c -fveclib=AMDLIBM %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not %clang --target=aarch64 -c -fveclib=HVML %s 2>&1 | FileCheck --check-prefix=CHECK-HVML-ERROR %s
+// CHECK-HVML-ERROR: unsupported option 'HVML' for target 'aarch64'
// CHECK-ERROR: unsupported option {{.*}} for target
// RUN: %clang -fveclib=Accelerate %s -target arm64-apple-ios8.0.0 -### 2>&1 | FileCheck --check-prefix=CHECK-LINK %s
@@ -50,6 +55,9 @@
// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=AMDLIBM -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-AMDLIBM %s
// CHECK-LTO-AMDLIBM: "-plugin-opt=-vector-library=AMDLIBM"
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=HVML -flto %s 2>&1 | FileCheck --check-prefix=CHECK-HVML-LTO %s
+// CHECK-HVML-LTO: "-plugin-opt=-vector-library=HVML"
+
// RUN: %clang -### --target=powerpc64-unknown-linux-gnu -fveclib=MASSV -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-MASSV %s
// CHECK-LTO-MASSV: "-plugin-opt=-vector-library=MASSV"
@@ -80,6 +88,13 @@
// CHECK-ERRNO-AMDLIBM: "-fveclib=AMDLIBM"
// CHECK-ERRNO-AMDLIBM-SAME: "-fmath-errno"
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=HVML %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-HVML %s
+// CHECK-ERRNO-HVML: "-fveclib=HVML"
+// CHECK-ERRNO-HVML-SAME: "-fmath-errno"
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=HVML -fno-math-errno %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO2-HVML %s
+// CHECK-ERRNO2-HVML: "-fveclib=HVML"
+// CHECK-ERRNO2-HVML-NOT: "-fmath-errno"
+
// RUN: %clang -### --target=powerpc64-unknown-linux-gnu -fveclib=MASSV %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-MASSV %s
// CHECK-ERRNO-MASSV: "-fveclib=MASSV"
// CHECK-ERRNO-MASSV-SAME: "-fmath-errno"
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 87a25f3101ddd6..15f2c0d399286d 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -241,6 +241,7 @@ static bool parseVectorLibArg(Fortran::frontend::CodeGenOptions &opts,
.Case("Darwin_libsystem_m", VectorLibrary::Darwin_libsystem_m)
.Case("ArmPL", VectorLibrary::ArmPL)
.Case("AMDLIBM", VectorLibrary::AMDLIBM)
+ .Case("HVML", VectorLibrary::HVML)
.Case("NoLibrary", VectorLibrary::NoLibrary)
.Default(std::nullopt);
if (!val.has_value()) {
diff --git a/flang/test/Driver/fveclib-codegen.f90 b/flang/test/Driver/fveclib-codegen.f90
index 88b31da40167ee..63b38a732f3cc2 100644
--- a/flang/test/Driver/fveclib-codegen.f90
+++ b/flang/test/Driver/fveclib-codegen.f90
@@ -4,6 +4,7 @@
! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=libmvec -march=armv8.2-a+nosve -o - %s | FileCheck %s --check-prefix=LIBMVEC-AARCH64-NEON %}
! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=libmvec -march=armv8.2-a+sve -o - %s | FileCheck %s --check-prefix=LIBMVEC-AARCH64-SVE %}
! RUN: %if x86-registered-target %{ %flang -S -O3 -ffast-math -target x86_64-unknown-linux-gnu -fveclib=AMDLIBM -o - %s | FileCheck %s --check-prefix=AMDLIBM %}
+! RUN: %if x86-registered-target %{ %flang -S -O3 -ffast-math -target x86_64-unknown-linux-gnu -fveclib=HVML -o - %s | FileCheck %s --check-prefix=HVML %}
! RUN: %flang -S -Ofast -fveclib=NoLibrary -o - %s | FileCheck %s --check-prefix=NOLIB
subroutine sb(a, b)
@@ -16,6 +17,7 @@ subroutine sb(a, b)
! LIBMVEC-AARCH64-NEON: _ZGVnN4vv_powf
! LIBMVEC-AARCH64-SVE: _ZGVsMxvv_powf
! AMDLIBM: amd_vrs4_powf
+! HVML: hvml_vs4_pow
! NOLIB: powf
a(i) = a(i) ** b(i)
end do
diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90
index d21e85e486f8d9..3979d541754975 100644
--- a/flang/test/Driver/fveclib.f90
+++ b/flang/test/Driver/fveclib.f90
@@ -7,6 +7,7 @@
! RUN: %flang -### -c --target=aarch64-none-none -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-SLEEF %s
! RUN: %flang -### -c --target=aarch64-none-none -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ARMPL %s
! RUN: %flang -### -c --target=x86_64-unknown-linux-gnu -fveclib=AMDLIBM %s 2>&1 | FileCheck -check-prefix CHECK-AMDLIBM %s
+! RUN: %flang -### -c --target=x86_64-unknown-linux-gnu -fveclib=HVML %s 2>&1 | FileCheck -check-prefix CHECK-HVML %s
! RUN: %flang -### -c --target=aarch64-apple-darwin -fveclib=none %s 2>&1 | FileCheck -check-prefix CHECK-NOLIB-DARWIN %s
! RUN: not %flang -c -fveclib=something %s 2>&1 | FileCheck -check-prefix CHECK-INVALID %s
@@ -18,15 +19,18 @@
! CHECK-SLEEF: "-fveclib=SLEEF"
! CHECK-ARMPL: "-fveclib=ArmPL"
! CHECK-AMDLIBM: "-fveclib=AMDLIBM"
+! CHECK-HVML: "-fveclib=HVML"
! CHECK-NOLIB-DARWIN: "-fveclib=none"
! CHECK-INVALID: error: invalid value 'something' in '-fveclib=something'
! RUN: not %flang --target=x86-none-none -c -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=x86-none-none -c -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=x86-none-none -c -fveclib=HVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=riscv64-none-none -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=aarch64-none-none -c -fveclib=SVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=aarch64-none-none -c -fveclib=AMDLIBM %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=aarch64-none-none -c -fveclib=HVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! CHECK-ERROR: unsupported option {{.*}} for target
! RUN: %flang -fveclib=Accelerate %s -target arm64-apple-ios8.0.0 -### 2>&1 | FileCheck --check-prefix=CHECK-LINK %s
diff --git a/llvm/docs/Vectorizers.md b/llvm/docs/Vectorizers.md
index 2471e88654d3d0..88c2deeed59be9 100644
--- a/llvm/docs/Vectorizers.md
+++ b/llvm/docs/Vectorizers.md
@@ -346,7 +346,7 @@ Many of these math functions are only vectorizable if the file has been built
with a specified target vector library that provides a vector implementation
of that math function. Using clang, this is handled by the "-fveclib" command
line option with one of the following vector libraries:
-"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM"
+"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,HVML"
```console
$ clang ... -fno-math-errno -fveclib=libmvec file.c
diff --git a/llvm/include/llvm/Analysis/VecFuncs.def b/llvm/include/llvm/Analysis/VecFuncs.def
index 14327197cf9d3e..a206fc16f8d3b8 100644
--- a/llvm/include/llvm/Analysis/VecFuncs.def
+++ b/llvm/include/llvm/Analysis/VecFuncs.def
@@ -1995,6 +1995,221 @@ TLI_DEFINE_VECFUNC("llvm.round.f32", "amd_vrs4_roundf", FIXED(4), NOMASK, "_ZGV_
TLI_DEFINE_VECFUNC("llvm.round.f64", "amd_vrd8_round", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
TLI_DEFINE_VECFUNC("llvm.round.f64", "amd_vrd4_round", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
TLI_DEFINE_VECFUNC("llvm.round.f64", "amd_vrd2_round", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+
+// Hygon vector math library (HVML) functions
+#elif defined(TLI_DEFINE_HVML_VECFUNCS)
+
+TLI_DEFINE_VECFUNC("sin", "hvml_vd2_sin", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("sin", "hvml_vd4_sin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("sinf", "hvml_vs4_sin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("sinf", "hvml_vs8_sin", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "hvml_vd2_sin", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "hvml_vd4_sin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "hvml_vs4_sin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "hvml_vs8_sin", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("cos", "hvml_vd2_cos", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("cos", "hvml_vd4_cos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("cosf", "hvml_vs4_cos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("cosf", "hvml_vs8_cos", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "hvml_vd2_cos", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "hvml_vd4_cos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "hvml_vs4_cos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "hvml_vs8_cos", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("log10", "hvml_vd2_log10", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("log10", "hvml_vd4_log10", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("log10f", "hvml_vs4_log10", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("log10f", "hvml_vs8_log10", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.log10.f64", "hvml_vd2_log10", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.log10.f64", "hvml_vd4_log10", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "hvml_vs4_log10", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "hvml_vs8_log10", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__log10_finite", "hvml_vd2_log10", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__log10_finite", "hvml_vd4_log10", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__log10f_finite", "hvml_vs4_log10", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__log10f_finite", "hvml_vs8_log10", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+// Note: the natural log entry point is named "ln" (log2/log10 keep the usual names).
+TLI_DEFINE_VECFUNC("log", "hvml_vd2_ln", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("log", "hvml_vd4_ln", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("logf", "hvml_vs4_ln", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("logf", "hvml_vs8_ln", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.log.f64", "hvml_vd2_ln", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.log.f64", "hvml_vd4_ln", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.log.f32", "hvml_vs4_ln", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.log.f32", "hvml_vs8_ln", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__log_finite", "hvml_vd2_ln", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__log_finite", "hvml_vd4_ln", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__logf_finite", "hvml_vs4_ln", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__logf_finite", "hvml_vs8_ln", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("tan", "hvml_vd2_tan", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("tan", "hvml_vd4_tan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("tanf", "hvml_vs4_tan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("tanf", "hvml_vs8_tan", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.tan.f64", "hvml_vd2_tan", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.tan.f64", "hvml_vd4_tan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.tan.f32", "hvml_vs4_tan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.tan.f32", "hvml_vs8_tan", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("asin", "hvml_vd2_asin", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("asin", "hvml_vd4_asin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("asinf", "hvml_vs4_asin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("asinf", "hvml_vs8_asin", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.asin.f64", "hvml_vd2_asin", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.asin.f64", "hvml_vd4_asin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.asin.f32", "hvml_vs4_asin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.asin.f32", "hvml_vs8_asin", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__asin_finite", "hvml_vd2_asin", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__asin_finite", "hvml_vd4_asin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__asinf_finite", "hvml_vs4_asin", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__asinf_finite", "hvml_vs8_asin", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("acos", "hvml_vd2_acos", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("acos", "hvml_vd4_acos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("acosf", "hvml_vs4_acos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("acosf", "hvml_vs8_acos", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.acos.f64", "hvml_vd2_acos", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.acos.f64", "hvml_vd4_acos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.acos.f32", "hvml_vs4_acos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.acos.f32", "hvml_vs8_acos", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__acos_finite", "hvml_vd2_acos", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__acos_finite", "hvml_vd4_acos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__acosf_finite", "hvml_vs4_acos", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__acosf_finite", "hvml_vs8_acos", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("atan", "hvml_vd2_atan", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("atan", "hvml_vd4_atan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("atanf", "hvml_vs4_atan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("atanf", "hvml_vs8_atan", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.atan.f64", "hvml_vd2_atan", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.atan.f64", "hvml_vd4_atan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.atan.f32", "hvml_vs4_atan", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.atan.f32", "hvml_vs8_atan", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("pow", "hvml_vd2_pow", FIXED(2), NOMASK, "_ZGV_LLVM_N2vv")
+TLI_DEFINE_VECFUNC("pow", "hvml_vd4_pow", FIXED(4), NOMASK, "_ZGV_LLVM_N4vv")
+TLI_DEFINE_VECFUNC("powf", "hvml_vs4_pow", FIXED(4), NOMASK, "_ZGV_LLVM_N4vv")
+TLI_DEFINE_VECFUNC("powf", "hvml_vs8_pow", FIXED(8), NOMASK, "_ZGV_LLVM_N8vv")
+
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "hvml_vd2_pow", FIXED(2), NOMASK, "_ZGV_LLVM_N2vv")
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "hvml_vd4_pow", FIXED(4), NOMASK, "_ZGV_LLVM_N4vv")
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "hvml_vs4_pow", FIXED(4), NOMASK, "_ZGV_LLVM_N4vv")
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "hvml_vs8_pow", FIXED(8), NOMASK, "_ZGV_LLVM_N8vv")
+
+TLI_DEFINE_VECFUNC("__pow_finite", "hvml_vd2_pow", FIXED(2), NOMASK, "_ZGV_LLVM_N2vv")
+TLI_DEFINE_VECFUNC("__pow_finite", "hvml_vd4_pow", FIXED(4), NOMASK, "_ZGV_LLVM_N4vv")
+TLI_DEFINE_VECFUNC("__powf_finite", "hvml_vs4_pow", FIXED(4), NOMASK, "_ZGV_LLVM_N4vv")
+TLI_DEFINE_VECFUNC("__powf_finite", "hvml_vs8_pow", FIXED(8), NOMASK, "_ZGV_LLVM_N8vv")
+
+TLI_DEFINE_VECFUNC("exp", "hvml_vd2_exp", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("exp", "hvml_vd4_exp", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("expf", "hvml_vs4_exp", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("expf", "hvml_vs8_exp", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "hvml_vd2_exp", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "hvml_vd4_exp", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "hvml_vs4_exp", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "hvml_vs8_exp", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__exp_finite", "hvml_vd2_exp", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__exp_finite", "hvml_vd4_exp", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__expf_finite", "hvml_vs4_exp", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__expf_finite", "hvml_vs8_exp", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("sinh", "hvml_vd2_sinh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("sinh", "hvml_vd4_sinh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("sinhf", "hvml_vs4_sinh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("sinhf", "hvml_vs8_sinh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.sinh.f64", "hvml_vd2_sinh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.sinh.f64", "hvml_vd4_sinh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.sinh.f32", "hvml_vs4_sinh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.sinh.f32", "hvml_vs8_sinh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__sinh_finite", "hvml_vd2_sinh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__sinh_finite", "hvml_vd4_sinh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__sinhf_finite", "hvml_vs4_sinh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__sinhf_finite", "hvml_vs8_sinh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("cosh", "hvml_vd2_cosh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("cosh", "hvml_vd4_cosh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("coshf", "hvml_vs4_cosh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("coshf", "hvml_vs8_cosh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.cosh.f64", "hvml_vd2_cosh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.cosh.f64", "hvml_vd4_cosh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.cosh.f32", "hvml_vs4_cosh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.cosh.f32", "hvml_vs8_cosh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__cosh_finite", "hvml_vd2_cosh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__cosh_finite", "hvml_vd4_cosh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__coshf_finite", "hvml_vs4_cosh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__coshf_finite", "hvml_vs8_cosh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("tanh", "hvml_vd2_tanh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("tanh", "hvml_vd4_tanh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("tanhf", "hvml_vs4_tanh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("tanhf", "hvml_vs8_tanh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.tanh.f64", "hvml_vd2_tanh", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.tanh.f64", "hvml_vd4_tanh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.tanh.f32", "hvml_vs4_tanh", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.tanh.f32", "hvml_vs8_tanh", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("exp2", "hvml_vd2_exp2", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("exp2", "hvml_vd4_exp2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("exp2f", "hvml_vs4_exp2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("exp2f", "hvml_vs8_exp2", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.exp2.f64", "hvml_vd2_exp2", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.exp2.f64", "hvml_vd4_exp2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.exp2.f32", "hvml_vs4_exp2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.exp2.f32", "hvml_vs8_exp2", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__exp2_finite", "hvml_vd2_exp2", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__exp2_finite", "hvml_vd4_exp2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__exp2f_finite", "hvml_vs4_exp2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__exp2f_finite", "hvml_vs8_exp2", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("log2", "hvml_vd2_log2", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("log2", "hvml_vd4_log2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("log2f", "hvml_vs4_log2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("log2f", "hvml_vs8_log2", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("llvm.log2.f64", "hvml_vd2_log2", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("llvm.log2.f64", "hvml_vd4_log2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.log2.f32", "hvml_vs4_log2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("llvm.log2.f32", "hvml_vs8_log2", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__log2_finite", "hvml_vd2_log2", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__log2_finite", "hvml_vd4_log2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__log2f_finite", "hvml_vs4_log2", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__log2f_finite", "hvml_vs8_log2", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("sqrt", "hvml_vd2_sqrt", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("sqrt", "hvml_vd4_sqrt", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("sqrtf", "hvml_vs4_sqrt", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("sqrtf", "hvml_vs8_sqrt", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
+TLI_DEFINE_VECFUNC("__sqrt_finite", "hvml_vd2_sqrt", FIXED(2), NOMASK, "_ZGV_LLVM_N2v")
+TLI_DEFINE_VECFUNC("__sqrt_finite", "hvml_vd4_sqrt", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__sqrtf_finite", "hvml_vs4_sqrt", FIXED(4), NOMASK, "_ZGV_LLVM_N4v")
+TLI_DEFINE_VECFUNC("__sqrtf_finite", "hvml_vs8_sqrt", FIXED(8), NOMASK, "_ZGV_LLVM_N8v")
+
#else
#error "Must choose which vector library functions are to be defined."
#endif
diff --git a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
index 77ab477986d31c..293d896fa65ed2 100644
--- a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
+++ b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
@@ -47,7 +47,8 @@ enum class VectorLibrary {
SLEEF, // SLEEF SIMD Library for Evaluating Elementary Functions.
Darwin_libsystem_m, // Use Darwin's libsystem_m vector functions.
ArmPL, // Arm Performance Libraries.
- AMDLIBM // AMD vector math library.
+ AMDLIBM, // AMD vector math library.
+ HVML // Hygon vector math library.
};
LLVM_ABI llvm::VectorLibrary
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 1176b9b5d1a5a0..65d98017060487 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -4577,3 +4577,74 @@ defset list<RuntimeLibcallImpl> AMDLIBM_VECFUNCS = {
def amd_vrd4_round : RuntimeLibcallImpl<ROUND_V4F64>;
def amd_vrd8_round : RuntimeLibcallImpl<ROUND_V8F64>;
}
+
+//===----------------------------------------------------------------------===//
+// Hygon vector math library (HVML) functions
+//===----------------------------------------------------------------------===//
+
+defset list<RuntimeLibcallImpl> HVML_VECFUNCS = {
+ def hvml_vd2_acos : RuntimeLibcallImpl<ACOS_V2F64>;
+ def hvml_vd4_acos : RuntimeLibcallImpl<ACOS_V4F64>;
+ def hvml_vs4_acos : RuntimeLibcallImpl<ACOS_V4F32>;
+ def hvml_vs8_acos : RuntimeLibcallImpl<ACOS_V8F32>;
+ def hvml_vd2_asin : RuntimeLibcallImpl<ASIN_V2F64>;
+ def hvml_vd4_asin : RuntimeLibcallImpl<ASIN_V4F64>;
+ def hvml_vs4_asin : RuntimeLibcallImpl<ASIN_V4F32>;
+ def hvml_vs8_asin : RuntimeLibcallImpl<ASIN_V8F32>;
+ def hvml_vd2_atan : RuntimeLibcallImpl<ATAN_V2F64>;
+ def hvml_vd4_atan : RuntimeLibcallImpl<ATAN_V4F64>;
+ def hvml_vs4_atan : RuntimeLibcallImpl<ATAN_V4F32>;
+ def hvml_vs8_atan : RuntimeLibcallImpl<ATAN_V8F32>;
+ def hvml_vd2_cos : RuntimeLibcallImpl<COS_V2F64>;
+ def hvml_vd4_cos : RuntimeLibcallImpl<COS_V4F64>;
+ def hvml_vs4_cos : RuntimeLibcallImpl<COS_V4F32>;
+ def hvml_vs8_cos : RuntimeLibcallImpl<COS_V8F32>;
+ def hvml_vd2_exp : RuntimeLibcallImpl<EXP_V2F64>;
+ def hvml_vd4_exp : RuntimeLibcallImpl<EXP_V4F64>;
+ def hvml_vs4_exp : RuntimeLibcallImpl<EXP_V4F32>;
+ def hvml_vs8_exp : RuntimeLibcallImpl<EXP_V8F32>;
+ def hvml_vd2_ln : RuntimeLibcallImpl<LOG_V2F64>;
+ def hvml_vd4_ln : RuntimeLibcallImpl<LOG_V4F64>;
+ def hvml_vs4_ln : RuntimeLibcallImpl<LOG_V4F32>;
+ def hvml_vs8_ln : RuntimeLibcallImpl<LOG_V8F32>;
+ def hvml_vd2_log10 : RuntimeLibcallImpl<LOG10_V2F64>;
+ def hvml_vd4_log10 : RuntimeLibcallImpl<LOG10_V4F64>;
+ def hvml_vs4_log10 : RuntimeLibcallImpl<LOG10_V4F32>;
+ def hvml_vs8_log10 : RuntimeLibcallImpl<LOG10_V8F32>;
+ def hvml_vd2_pow : RuntimeLibcallImpl<POW_V2F64>;
+ def hvml_vd4_pow : RuntimeLibcallImpl<POW_V4F64>;
+ def hvml_vs4_pow : RuntimeLibcallImpl<POW_V4F32>;
+ def hvml_vs8_pow : RuntimeLibcallImpl<POW_V8F32>;
+ def hvml_vd2_sin : RuntimeLibcallImpl<SIN_V2F64>;
+ def hvml_vd4_sin : RuntimeLibcallImpl<SIN_V4F64>;
+ def hvml_vs4_sin : RuntimeLibcallImpl<SIN_V4F32>;
+ def hvml_vs8_sin : RuntimeLibcallImpl<SIN_V8F32>;
+ def hvml_vd2_tan : RuntimeLibcallImpl<TAN_V2F64>;
+ def hvml_vd4_tan : RuntimeLibcallImpl<TAN_V4F64>;
+ def hvml_vs4_tan : RuntimeLibcallImpl<TAN_V4F32>;
+ def hvml_vs8_tan : RuntimeLibcallImpl<TAN_V8F32>;
+ def hvml_vd2_sqrt : RuntimeLibcallImpl<SQRT_V2F64>;
+ def hvml_vd4_sqrt : RuntimeLibcallImpl<SQRT_V4F64>;
+ def hvml_vs4_sqrt : RuntimeLibcallImpl<SQRT_V4F32>;
+ def hvml_vs8_sqrt : RuntimeLibcallImpl<SQRT_V8F32>;
+ def hvml_vd2_exp2 : RuntimeLibcallImpl<EXP2_V2F64>;
+ def hvml_vd4_exp2 : RuntimeLibcallImpl<EXP2_V4F64>;
+ def hvml_vs4_exp2 : RuntimeLibcallImpl<EXP2_V4F32>;
+ def hvml_vs8_exp2 : RuntimeLibcallImpl<EXP2_V8F32>;
+ def hvml_vd2_log2 : RuntimeLibcallImpl<LOG2_V2F64>;
+ def hvml_vd4_log2 : RuntimeLibcallImpl<LOG2_V4F64>;
+ def hvml_vs4_log2 : RuntimeLibcallImpl<LOG2_V4F32>;
+ def hvml_vs8_log2 : RuntimeLibcallImpl<LOG2_V8F32>;
+ def hvml_vd2_sinh : RuntimeLibcallImpl<SINH_V2F64>;
+ def hvml_vd4_sinh : RuntimeLibcallImpl<SINH_V4F64>;
+ def hvml_vs4_sinh : RuntimeLibcallImpl<SINH_V4F32>;
+ def hvml_vs8_sinh : RuntimeLibcallImpl<SINH_V8F32>;
+ def hvml_vd2_cosh : RuntimeLibcallImpl<COSH_V2F64>;
+ def hvml_vd4_cosh : RuntimeLibcallImpl<COSH_V4F64>;
+ def hvml_vs4_cosh : RuntimeLibcallImpl<COSH_V4F32>;
+ def hvml_vs8_cosh : RuntimeLibcallImpl<COSH_V8F32>;
+ def hvml_vd2_tanh : RuntimeLibcallImpl<TANH_V2F64>;
+ def hvml_vd4_tanh : RuntimeLibcallImpl<TANH_V4F64>;
+ def hvml_vs4_tanh : RuntimeLibcallImpl<TANH_V4F32>;
+ def hvml_vs8_tanh : RuntimeLibcallImpl<TANH_V8F32>;
+}
diff --git a/llvm/include/llvm/IR/SystemLibraries.h b/llvm/include/llvm/IR/SystemLibraries.h
index 5bdf67642e0e4b..2ac2586b42c7fa 100644
--- a/llvm/include/llvm/IR/SystemLibraries.h
+++ b/llvm/include/llvm/IR/SystemLibraries.h
@@ -26,7 +26,8 @@ enum class VectorLibrary {
SVML, // Intel short vector math library.
SLEEFGNUABI, // SLEEF - SIMD Library for Evaluating Elementary Functions.
ArmPL, // Arm Performance Libraries.
- AMDLIBM // AMD Math Vector library.
+ AMDLIBM, // AMD Math Vector library.
+ HVML // Hygon Vector Math library.
};
} // namespace llvm
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 5ff83f19b2e241..0abb117acc0b6e 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1337,6 +1337,14 @@ const VecDesc VecFuncs_AMDLIBM[] = {
#undef TLI_DEFINE_AMDLIBM_VECFUNCS
};
+const VecDesc VecFuncs_HVML[] = {
+#define TLI_DEFINE_HVML_VECFUNCS
+#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \
+ {SCAL, VEC, VF, MASK, VABI_PREFIX, /* CC = */ std::nullopt},
+#include "llvm/Analysis/VecFuncs.def"
+#undef TLI_DEFINE_HVML_VECFUNCS
+};
+
void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
enum VectorLibrary VecLib, const llvm::Triple &TargetTriple) {
switch (VecLib) {
@@ -1402,6 +1410,10 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
addVectorizableFunctions(VecFuncs_AMDLIBM);
break;
}
+ case VectorLibrary::HVML: {
+ addVectorizableFunctions(VecFuncs_HVML);
+ break;
+ }
case VectorLibrary::NoLibrary:
break;
}
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index db149dd9382035..f93c6180a8ada3 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -451,7 +451,9 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
clEnumValN(VectorLibrary::ArmPL, "ArmPL",
"Arm Performance Libraries"),
clEnumValN(VectorLibrary::AMDLIBM, "AMDLIBM",
- "AMD vector math library")));
+ "AMD vector math library"),
+ clEnumValN(VectorLibrary::HVML, "HVML",
+ "Hygon vector math library")));
CGBINDOPT(VectorLibrary);
static cl::opt<bool> EnableStackSizeSection(
diff --git a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
index d22202598a28dd..9c69fe5de93606 100644
--- a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
+++ b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
@@ -40,6 +40,8 @@ convertDriverVectorLibraryToVectorLibrary(llvm::driver::VectorLibrary VecLib) {
return llvm::VectorLibrary::ArmPL;
case llvm::driver::VectorLibrary::AMDLIBM:
return llvm::VectorLibrary::AMDLIBM;
+ case llvm::driver::VectorLibrary::HVML:
+ return llvm::VectorLibrary::HVML;
}
llvm_unreachable("Unexpected driver::VectorLibrary");
}
diff --git a/llvm/test/CodeGen/Generic/replace-intrinsics-with-veclib.ll b/llvm/test/CodeGen/Generic/replace-intrinsics-with-veclib.ll
index ff9c7486c099e3..0cc076c1cdf460 100644
--- a/llvm/test/CodeGen/Generic/replace-intrinsics-with-veclib.ll
+++ b/llvm/test/CodeGen/Generic/replace-intrinsics-with-veclib.ll
@@ -1,6 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
; RUN: opt -vector-library=SVML -replace-with-veclib -S < %s | FileCheck %s --check-prefixes=COMMON,SVML
; RUN: opt -vector-library=AMDLIBM -replace-with-veclib -S < %s | FileCheck %s --check-prefixes=COMMON,AMDLIBM
+; RUN: opt -vector-library=HVML -replace-with-veclib -S < %s | FileCheck %s --check-prefixes=COMMON,HVML
; RUN: opt -vector-library=LIBMVEC -replace-with-veclib -S < %s | FileCheck %s --check-prefixes=COMMON,LIBMVEC-X86
; RUN: opt -vector-library=MASSV -replace-with-veclib -S < %s | FileCheck %s --check-prefixes=COMMON,MASSV
; RUN: opt -vector-library=Accelerate -replace-with-veclib -S < %s | FileCheck %s --check-prefixes=COMMON,ACCELERATE
@@ -19,6 +20,11 @@ define <4 x double> @exp_v4(<4 x double> %in) {
; AMDLIBM-NEXT: [[TMP1:%.*]] = call <4 x double> @amd_vrd4_exp(<4 x double> [[IN]])
; AMDLIBM-NEXT: ret <4 x double> [[TMP1]]
;
+; HVML-LABEL: define {{[^@]+}}@exp_v4
+; HVML-SAME: (<4 x double> [[IN:%.*]]) {
+; HVML-NEXT: [[TMP1:%.*]] = call <4 x double> @hvml_vd4_exp(<4 x double> [[IN]])
+; HVML-NEXT: ret <4 x double> [[TMP1]]
+;
; LIBMVEC-X86-LABEL: define {{[^@]+}}@exp_v4
; LIBMVEC-X86-SAME: (<4 x double> [[IN:%.*]]) {
; LIBMVEC-X86-NEXT: [[TMP1:%.*]] = call <4 x double> @_ZGVdN4v_exp(<4 x double> [[IN]])
@@ -51,6 +57,11 @@ define <4 x float> @exp_f32(<4 x float> %in) {
; AMDLIBM-NEXT: [[TMP1:%.*]] = call <4 x float> @amd_vrs4_expf(<4 x float> [[IN]])
; AMDLIBM-NEXT: ret <4 x float> [[TMP1]]
;
+; HVML-LABEL: define {{[^@]+}}@exp_f32
+; HVML-SAME: (<4 x float> [[IN:%.*]]) {
+; HVML-NEXT: [[TMP1:%.*]] = call <4 x float> @hvml_vs4_exp(<4 x float> [[IN]])
+; HVML-NEXT: ret <4 x float> [[TMP1]]
+;
; LIBMVEC-X86-LABEL: define {{[^@]+}}@exp_f32
; LIBMVEC-X86-SAME: (<4 x float> [[IN:%.*]]) {
; LIBMVEC-X86-NEXT: [[TMP1:%.*]] = call <4 x float> @_ZGVbN4v_expf(<4 x float> [[IN]])
diff --git a/llvm/test/Transforms/LoopVectorize/X86/hvml-calls-finite.ll b/llvm/test/Transforms/LoopVectorize/X86/hvml-calls-finite.ll
new file mode 100644
index 00000000000000..5f91ab93e8b1b6
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/X86/hvml-calls-finite.ll
@@ -0,0 +1,646 @@
+; RUN: opt -vector-library=HVML -passes=inject-tli-mappings,loop-vectorize -S < %s | FileCheck %s
+
+; Test to verify that when math headers are built with
+; __FINITE_MATH_ONLY__ enabled, causing use of __<func>_finite
+; function versions, vectorization can map these to vector versions.
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @asin_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_f64
+; CHECK: call fast <4 x double> @hvml_vd4_asin(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__asin_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @asin_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_f32
+; CHECK: call fast <4 x float> @hvml_vs4_asin(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__asinf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @acos_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_f64
+; CHECK: call fast <4 x double> @hvml_vd4_acos(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__acos_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @acos_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_f32
+; CHECK: call fast <4 x float> @hvml_vs4_acos(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__acosf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @sinh_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @sinh_f64
+; CHECK: call fast <4 x double> @hvml_vd4_sinh(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__sinh_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @sinh_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @sinh_f32
+; CHECK: call fast <4 x float> @hvml_vs4_sinh(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__sinhf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @cosh_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @cosh_f64
+; CHECK: call fast <4 x double> @hvml_vd4_cosh(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__cosh_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @cosh_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @cosh_f32
+; CHECK: call fast <4 x float> @hvml_vs4_cosh(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__coshf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @exp_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_f64
+; CHECK: call fast <4 x double> @hvml_vd4_exp(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__exp_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @exp_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_f32
+; CHECK: call fast <4 x float> @hvml_vs4_exp(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__expf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @exp2_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @exp2_f64
+; CHECK: call fast <4 x double> @hvml_vd4_exp2(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__exp2_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @exp2_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @exp2_f32
+; CHECK: call fast <4 x float> @hvml_vs4_exp2(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__exp2f_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @log_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @log_f64
+; CHECK: call fast <4 x double> @hvml_vd4_ln(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__log_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @log_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log_f32
+; CHECK: call fast <4 x float> @hvml_vs4_ln(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__logf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @log2_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_f64
+; CHECK: call fast <4 x double> @hvml_vd4_log2(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__log2_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @log2_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_f32
+; CHECK: call fast <4 x float> @hvml_vs4_log2(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__log2f_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @log10_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @log10_f64
+; CHECK: call fast <4 x double> @hvml_vd4_log10(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__log10_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @log10_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log10_f32
+; CHECK: call fast <4 x float> @hvml_vs4_log10(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__log10f_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @pow_f64(ptr nocapture %varray, ptr nocapture readonly %exp) {
+; CHECK-LABEL: @pow_f64
+; CHECK: call fast <4 x double> @hvml_vd4_pow(<4 x double> {{.*}}, <4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %arrayidx = getelementptr inbounds double, ptr %exp, i64 %indvars.iv
+ %tmp1 = load double, ptr %arrayidx, align 4
+ %tmp2 = tail call fast double @__pow_finite(double %conv, double %tmp1)
+ %arrayidx2 = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %tmp2, ptr %arrayidx2, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @pow_f32(ptr nocapture %varray, ptr nocapture readonly %exp) {
+; CHECK-LABEL: @pow_f32
+; CHECK: call fast <4 x float> @hvml_vs4_pow(<4 x float> {{.*}}, <4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %arrayidx = getelementptr inbounds float, ptr %exp, i64 %indvars.iv
+ %tmp1 = load float, ptr %arrayidx, align 4
+ %tmp2 = tail call fast float @__powf_finite(float %conv, float %tmp1)
+ %arrayidx2 = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %tmp2, ptr %arrayidx2, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @sqrt_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @sqrt_f64
+; CHECK: call fast <4 x double> @hvml_vd4_sqrt(<4 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__sqrt_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @sqrt_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @sqrt_f32
+; CHECK: call fast <4 x float> @hvml_vs4_sqrt(<4 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__sqrtf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !4
+
+for.end:
+ ret void
+}
+
+
+define void @asin_vf2_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_vf2_f64
+; CHECK: call fast <2 x double> @hvml_vd2_asin(<2 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__asin_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !1
+
+for.end:
+ ret void
+}
+
+
+define void @acos_vf2_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_vf2_f64
+; CHECK: call fast <2 x double> @hvml_vd2_acos(<2 x double> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call fast double @__acos_finite(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %indvars.iv
+ store double %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !1
+
+for.end:
+ ret void
+}
+
+
+define void @exp_vf8_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_vf8_f32
+; CHECK: call fast <8 x float> @hvml_vs8_exp(<8 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__expf_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !7
+
+for.end:
+ ret void
+}
+
+
+define void @log2_vf8_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_vf8_f32
+; CHECK: call fast <8 x float> @hvml_vs8_log2(<8 x float> {{.*}})
+; CHECK: ret
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %tmp = trunc i64 %indvars.iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call fast float @__log2f_finite(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %indvars.iv
+ store float %call, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !7
+
+for.end:
+ ret void
+}
+
+
+
+!1 = distinct !{!1, !2, !3}
+!4 = distinct !{!4, !5, !6}
+!7 = distinct !{!7, !8, !9}
+!2 = !{!"llvm.loop.vectorize.width", i32 2}
+!3 = !{!"llvm.loop.vectorize.enable"}
+!5 = !{!"llvm.loop.vectorize.width", i32 4}
+!6 = !{!"llvm.loop.vectorize.enable"}
+!8 = !{!"llvm.loop.vectorize.width", i32 8}
+!9 = !{!"llvm.loop.vectorize.enable"}
+
+attributes #0 = { nounwind readnone }
+
+declare double @__asin_finite(double) #0
+declare float @__asinf_finite(float) #0
+declare double @__acos_finite(double) #0
+declare float @__acosf_finite(float) #0
+declare double @__sinh_finite(double) #0
+declare float @__sinhf_finite(float) #0
+declare double @__cosh_finite(double) #0
+declare float @__coshf_finite(float) #0
+declare double @__exp_finite(double) #0
+declare float @__expf_finite(float) #0
+declare double @__exp2_finite(double) #0
+declare float @__exp2f_finite(float) #0
+declare double @__log_finite(double) #0
+declare float @__logf_finite(float) #0
+declare double @__log2_finite(double) #0
+declare float @__log2f_finite(float) #0
+declare double @__log10_finite(double) #0
+declare float @__log10f_finite(float) #0
+declare double @__pow_finite(double, double) #0
+declare float @__powf_finite(float, float) #0
+declare double @__sqrt_finite(double) #0
+declare float @__sqrtf_finite(float) #0
diff --git a/llvm/test/Transforms/LoopVectorize/X86/hvml-calls.ll b/llvm/test/Transforms/LoopVectorize/X86/hvml-calls.ll
new file mode 100644
index 00000000000000..9f1a35603c56fa
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/X86/hvml-calls.ll
@@ -0,0 +1,1681 @@
+; Test that the Hygon vector math library (HVML) vector functions are
+; selected when vectorizing the corresponding scalar math calls, at the
+; fixed vector widths registered in VecFuncs.def. HVML registers 2/4-wide
+; double (hvml_vd2_*/hvml_vd4_*) and 4/8-wide float (hvml_vs4_*/hvml_vs8_*)
+; variants; widths outside that set fall back to the scalar libm intrinsic.
+; RUN: opt -vector-library=HVML -passes=inject-tli-mappings,loop-vectorize,replace-with-veclib -force-vector-width=4 -force-vector-interleave=1 -mattr=avx -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-VF4
+; RUN: opt -vector-library=HVML -passes=inject-tli-mappings,loop-vectorize,replace-with-veclib -force-vector-width=2 -force-vector-interleave=1 -mattr=avx -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-VF2
+; RUN: opt -vector-library=HVML -passes=inject-tli-mappings,loop-vectorize,replace-with-veclib -force-vector-width=8 -force-vector-interleave=1 -mattr=avx -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-VF8
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @sin_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @sin_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_sin(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_sin(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.sin.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @sin(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sin_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @sin_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_sin(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_sin(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.sin.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.sin.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sin_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @sin_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.sin.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_sin(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_sin(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @sinf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sin_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @sin_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.sin.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_sin(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_sin(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.sin.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @cos_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @cos_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_cos(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_cos(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.cos.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @cos(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @cos_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @cos_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_cos(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_cos(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.cos.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.cos.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @cos_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @cos_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.cos.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_cos(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_cos(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @cosf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @cos_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @cos_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.cos.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_cos(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_cos(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.cos.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @tan_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @tan_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_tan(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_tan(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.tan.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @tan(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @tan_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @tan_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_tan(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_tan(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.tan.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.tan.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @tan_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @tan_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.tan.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_tan(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_tan(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @tanf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @tan_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @tan_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.tan.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_tan(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_tan(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.tan.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @asin_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_asin(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_asin(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.asin.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @asin(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @asin_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_asin(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_asin(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.asin.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.asin.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @asin_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.asin.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_asin(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_asin(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @asinf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @asin_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @asin_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.asin.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_asin(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_asin(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.asin.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @acos_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_acos(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_acos(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.acos.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @acos(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @acos_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_acos(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_acos(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.acos.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.acos.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @acos_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.acos.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_acos(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_acos(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @acosf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @acos_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @acos_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.acos.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_acos(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_acos(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.acos.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @atan_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @atan_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_atan(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_atan(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.atan.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @atan(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @atan_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @atan_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_atan(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_atan(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.atan.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.atan.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @atan_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @atan_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.atan.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_atan(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_atan(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @atanf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @atan_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @atan_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.atan.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_atan(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_atan(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.atan.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @sinh_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @sinh_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_sinh(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_sinh(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.sinh.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @sinh(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sinh_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @sinh_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_sinh(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_sinh(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.sinh.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.sinh.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sinh_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @sinh_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.sinh.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_sinh(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_sinh(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @sinhf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sinh_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @sinh_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.sinh.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_sinh(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_sinh(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.sinh.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @cosh_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @cosh_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_cosh(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_cosh(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.cosh.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @cosh(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @cosh_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @cosh_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_cosh(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_cosh(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.cosh.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.cosh.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @cosh_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @cosh_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.cosh.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_cosh(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_cosh(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @coshf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @cosh_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @cosh_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.cosh.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_cosh(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_cosh(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.cosh.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @tanh_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @tanh_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_tanh(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_tanh(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.tanh.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @tanh(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @tanh_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @tanh_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_tanh(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_tanh(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.tanh.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.tanh.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @tanh_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @tanh_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.tanh.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_tanh(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_tanh(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @tanhf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @tanh_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @tanh_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.tanh.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_tanh(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_tanh(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.tanh.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @exp_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_exp(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_exp(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.exp.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @exp(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @exp_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_exp(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_exp(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.exp.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.exp.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @exp_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.exp.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_exp(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_exp(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @expf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @exp_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @exp_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.exp.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_exp(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_exp(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.exp.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @exp2_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @exp2_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_exp2(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_exp2(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.exp2.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @exp2(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @exp2_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @exp2_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_exp2(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_exp2(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.exp2.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.exp2.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @exp2_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @exp2_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_exp2(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_exp2(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @exp2f(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @exp2_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @exp2_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_exp2(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_exp2(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.exp2.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @log_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @log_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_ln(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_ln(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.log.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @log(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @log_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_ln(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_ln(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.log.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.log.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.log.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_ln(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_ln(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @logf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @log_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.log.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_ln(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_ln(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.log.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @log2_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_log2(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_log2(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.log2.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @log2(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log2_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_log2(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_log2(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.log2.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.log2.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log2_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_log2(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_log2(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @log2f(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log2_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @log2_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_log2(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_log2(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.log2.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @log10_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @log10_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_log10(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_log10(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.log10.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @log10(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log10_f64_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @log10_f64_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_log10(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_log10(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x double> @llvm.log10.v8f64(<8 x double> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @llvm.log10.f64(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log10_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @log10_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.log10.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_log10(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_log10(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @log10f(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @log10_f32_intrinsic(ptr nocapture %varray) {
+; CHECK-LABEL: @log10_f32_intrinsic(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.log10.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_log10(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_log10(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @llvm.log10.f32(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+define void @sqrt_f64(ptr nocapture %varray) {
+; CHECK-LABEL: @sqrt_f64(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x double> @hvml_vd2_sqrt(<2 x double> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x double> @hvml_vd4_sqrt(<4 x double> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = tail call double @sqrt(double [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %call = tail call double @sqrt(double %conv)
+ %arrayidx = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @sqrt_f32(ptr nocapture %varray) {
+; CHECK-LABEL: @sqrt_f32(
+; CHECK-VF2: [[TMP5:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> [[TMP4:%.*]])
+; CHECK-VF4: [[TMP5:%.*]] = call <4 x float> @hvml_vs4_sqrt(<4 x float> [[TMP4:%.*]])
+; CHECK-VF8: [[TMP5:%.*]] = call <8 x float> @hvml_vs8_sqrt(<8 x float> [[TMP4:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %call = tail call float @sqrtf(float %conv)
+ %arrayidx = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %call, ptr %arrayidx, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @pow_f64(ptr nocapture %varray, ptr nocapture readonly %exp) {
+; CHECK-LABEL: @pow_f64(
+; CHECK-VF2: [[TMP8:%.*]] = call <2 x double> @hvml_vd2_pow(<2 x double> [[TMP4:%.*]], <2 x double> [[WIDE_LOAD:%.*]])
+; CHECK-VF4: [[TMP8:%.*]] = call <4 x double> @hvml_vd4_pow(<4 x double> [[TMP4:%.*]], <4 x double> [[WIDE_LOAD:%.*]])
+; CHECK-VF8: [[TMP8:%.*]] = call <8 x double> @llvm.pow.v8f64(<8 x double> [[TMP4:%.*]], <8 x double> [[WIDE_LOAD:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %arrayidx = getelementptr inbounds double, ptr %exp, i64 %iv
+ %tmp1 = load double, ptr %arrayidx, align 4
+ %tmp2 = tail call double @pow(double %conv, double %tmp1)
+ %arrayidx2 = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %tmp2, ptr %arrayidx2, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @pow_f64_intrinsic(ptr nocapture %varray, ptr nocapture readonly %exp) {
+; CHECK-LABEL: @pow_f64_intrinsic(
+; CHECK-VF2: [[TMP8:%.*]] = call <2 x double> @hvml_vd2_pow(<2 x double> [[TMP4:%.*]], <2 x double> [[WIDE_LOAD:%.*]])
+; CHECK-VF4: [[TMP8:%.*]] = call <4 x double> @hvml_vd4_pow(<4 x double> [[TMP4:%.*]], <4 x double> [[WIDE_LOAD:%.*]])
+; CHECK-VF8: [[TMP8:%.*]] = call <8 x double> @llvm.pow.v8f64(<8 x double> [[TMP4:%.*]], <8 x double> [[WIDE_LOAD:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to double
+ %arrayidx = getelementptr inbounds double, ptr %exp, i64 %iv
+ %tmp1 = load double, ptr %arrayidx, align 4
+ %tmp2 = tail call double @llvm.pow.f64(double %conv, double %tmp1)
+ %arrayidx2 = getelementptr inbounds double, ptr %varray, i64 %iv
+ store double %tmp2, ptr %arrayidx2, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @pow_f32(ptr nocapture %varray, ptr nocapture readonly %exp) {
+; CHECK-LABEL: @pow_f32(
+; CHECK-VF2: [[TMP8:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[TMP4:%.*]], <2 x float> [[WIDE_LOAD:%.*]])
+; CHECK-VF4: [[TMP8:%.*]] = call <4 x float> @hvml_vs4_pow(<4 x float> [[TMP4:%.*]], <4 x float> [[WIDE_LOAD:%.*]])
+; CHECK-VF8: [[TMP8:%.*]] = call <8 x float> @hvml_vs8_pow(<8 x float> [[TMP4:%.*]], <8 x float> [[WIDE_LOAD:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %arrayidx = getelementptr inbounds float, ptr %exp, i64 %iv
+ %tmp1 = load float, ptr %arrayidx, align 4
+ %tmp2 = tail call float @powf(float %conv, float %tmp1)
+ %arrayidx2 = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %tmp2, ptr %arrayidx2, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+define void @pow_f32_intrinsic(ptr nocapture %varray, ptr nocapture readonly %exp) {
+; CHECK-LABEL: @pow_f32_intrinsic(
+; CHECK-VF2: [[TMP8:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[TMP4:%.*]], <2 x float> [[WIDE_LOAD:%.*]])
+; CHECK-VF4: [[TMP8:%.*]] = call <4 x float> @hvml_vs4_pow(<4 x float> [[TMP4:%.*]], <4 x float> [[WIDE_LOAD:%.*]])
+; CHECK-VF8: [[TMP8:%.*]] = call <8 x float> @hvml_vs8_pow(<8 x float> [[TMP4:%.*]], <8 x float> [[WIDE_LOAD:%.*]])
+; CHECK: ret void
+;
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+ %tmp = trunc i64 %iv to i32
+ %conv = sitofp i32 %tmp to float
+ %arrayidx = getelementptr inbounds float, ptr %exp, i64 %iv
+ %tmp1 = load float, ptr %arrayidx, align 4
+ %tmp2 = tail call float @llvm.pow.f32(float %conv, float %tmp1)
+ %arrayidx2 = getelementptr inbounds float, ptr %varray, i64 %iv
+ store float %tmp2, ptr %arrayidx2, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, 1000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+
+
+attributes #0 = { nounwind readnone }
+
+declare double @sin(double) #0
+declare float @sinf(float) #0
+declare double @cos(double) #0
+declare float @cosf(float) #0
+declare double @tan(double) #0
+declare float @tanf(float) #0
+declare double @asin(double) #0
+declare float @asinf(float) #0
+declare double @acos(double) #0
+declare float @acosf(float) #0
+declare double @atan(double) #0
+declare float @atanf(float) #0
+declare double @sinh(double) #0
+declare float @sinhf(float) #0
+declare double @cosh(double) #0
+declare float @coshf(float) #0
+declare double @tanh(double) #0
+declare float @tanhf(float) #0
+declare double @exp(double) #0
+declare float @expf(float) #0
+declare double @exp2(double) #0
+declare float @exp2f(float) #0
+declare double @log(double) #0
+declare float @logf(float) #0
+declare double @log2(double) #0
+declare float @log2f(float) #0
+declare double @log10(double) #0
+declare float @log10f(float) #0
+declare double @sqrt(double) #0
+declare float @sqrtf(float) #0
+declare double @pow(double, double) #0
+declare float @powf(float, float) #0
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/sin-sqrt.ll b/llvm/test/Transforms/SLPVectorizer/X86/sin-sqrt.ll
index 68fb6c6202ce7f..03f3a1a865d0e4 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/sin-sqrt.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/sin-sqrt.ll
@@ -2,6 +2,7 @@
; RUN: opt < %s -mtriple=x86_64-unknown-linux -mcpu=skylake-avx512 -passes=slp-vectorizer -S | FileCheck %s
; RUN: opt < %s -mtriple=x86_64-unknown-linux -mcpu=skylake-avx512 -passes=inject-tli-mappings,slp-vectorizer -vector-library=SVML -S | FileCheck %s --check-prefix=VECLIB
; RUN: opt < %s -mtriple=x86_64-unknown-linux -mcpu=skylake-avx512 -passes=inject-tli-mappings,slp-vectorizer -vector-library=AMDLIBM -S | FileCheck %s --check-prefix=AMDLIBM
+; RUN: opt < %s -mtriple=x86_64-unknown-linux -mcpu=skylake-avx512 -passes=inject-tli-mappings,slp-vectorizer -vector-library=HVML -S | FileCheck %s --check-prefix=HVML
@src = common global [8 x double] zeroinitializer, align 64
@dst = common global [8 x double] zeroinitializer, align 64
@@ -57,6 +58,22 @@ define void @test() {
; AMDLIBM-NEXT: [[TMP12:%.*]] = fadd fast <2 x double> [[TMP10]], [[TMP11]]
; AMDLIBM-NEXT: store <2 x double> [[TMP12]], ptr @dst, align 8
; AMDLIBM-NEXT: ret void
+;
+; HVML-LABEL: @test(
+; HVML-NEXT: [[TMP1:%.*]] = load <8 x double>, ptr @src, align 8
+; HVML-NEXT: [[TMP2:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> poison, <2 x i32> <i32 2, i32 6>
+; HVML-NEXT: [[TMP3:%.*]] = call fast <2 x double> @hvml_vd2_sin(<2 x double> [[TMP2]])
+; HVML-NEXT: [[TMP4:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> poison, <2 x i32> <i32 3, i32 7>
+; HVML-NEXT: [[TMP5:%.*]] = call fast <2 x double> @hvml_vd2_sin(<2 x double> [[TMP4]])
+; HVML-NEXT: [[TMP6:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> poison, <2 x i32> <i32 0, i32 4>
+; HVML-NEXT: [[TMP7:%.*]] = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> [[TMP6]])
+; HVML-NEXT: [[TMP8:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> poison, <2 x i32> <i32 1, i32 5>
+; HVML-NEXT: [[TMP9:%.*]] = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> [[TMP8]])
+; HVML-NEXT: [[TMP10:%.*]] = fadd fast <2 x double> [[TMP7]], [[TMP5]]
+; HVML-NEXT: [[TMP11:%.*]] = fadd fast <2 x double> [[TMP3]], [[TMP9]]
+; HVML-NEXT: [[TMP12:%.*]] = fadd fast <2 x double> [[TMP10]], [[TMP11]]
+; HVML-NEXT: store <2 x double> [[TMP12]], ptr @dst, align 8
+; HVML-NEXT: ret void
;
%a0 = load double, ptr @src, align 8
%a1 = load double, ptr getelementptr inbounds ([8 x double], ptr @src, i32 0, i64 1), align 8
diff --git a/llvm/test/Transforms/Util/add-TLI-mappings.ll b/llvm/test/Transforms/Util/add-TLI-mappings.ll
index 28d3edfd0ba626..e593821f79b3fc 100644
--- a/llvm/test/Transforms/Util/add-TLI-mappings.ll
+++ b/llvm/test/Transforms/Util/add-TLI-mappings.ll
@@ -7,6 +7,7 @@
; RUN: opt -mtriple=aarch64-unknown-linux-gnu -vector-library=sleefgnuabi -passes=inject-tli-mappings -S < %s | FileCheck %s --check-prefixes=COMMON,SLEEFGNUABI
; RUN: opt -mtriple=riscv64-unknown-linux-gnu -vector-library=sleefgnuabi -passes=inject-tli-mappings -S < %s | FileCheck %s --check-prefixes=COMMON,SLEEFGNUABI_RISCV
; RUN: opt -mtriple=aarch64-unknown-linux-gnu -vector-library=ArmPL -passes=inject-tli-mappings -S < %s | FileCheck %s --check-prefixes=COMMON,ARMPL
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu -vector-library=HVML -passes=inject-tli-mappings -S < %s | FileCheck %s --check-prefixes=COMMON,HVML
; COMMON-LABEL: @llvm.compiler.used = appending global
; SVML-SAME: [6 x ptr] [
@@ -90,6 +91,11 @@
; ARMPL-SAME: ptr @armpl_svlog10_f32_x,
; ARMPL-SAME: ptr @armpl_vldexpq_f64,
; ARMPL-SAME: ptr @armpl_svldexp_f64_x
+; HVML-SAME: [4 x ptr] [
+; HVML-SAME: ptr @hvml_vd2_sin,
+; HVML-SAME: ptr @hvml_vd4_sin,
+; HVML-SAME: ptr @hvml_vs4_log10,
+; HVML-SAME: ptr @hvml_vs8_log10
; COMMON-SAME: ], section "llvm.metadata"
define double @modf_f64(double %in, ptr %iptr) {
@@ -123,6 +129,7 @@ define double @sin_f64(double %in) {
; SLEEFGNUABI: call double @sin(double %{{.*}}) #[[SIN:[0-9]+]]
; SLEEFGNUABI_RISCV: call double @sin(double %{{.*}}) #[[SIN:[0-9]+]]
; ARMPL: call double @sin(double %{{.*}}) #[[SIN:[0-9]+]]
+; HVML: call double @sin(double %{{.*}}) #[[SIN:[0-9]+]]
; No mapping of "sin" to a vector function for Accelerate.
; ACCELERATE-NOT: _ZGV_LLVM_{{.*}}_sin({{.*}})
%call = tail call double @sin(double %in)
@@ -211,6 +218,7 @@ define float @call_llvm.log10.f32(float %in) {
; SLEEFGNUABI: call float @llvm.log10.f32(float %{{.*}}) #[[LOG10:[0-9]+]]
; SLEEFGNUABI_RISCV: call float @llvm.log10.f32(float %{{.*}}) #[[LOG10:[0-9]+]]
; ARMPL: call float @llvm.log10.f32(float %{{.*}}) #[[LOG10:[0-9]+]]
+; HVML: call float @llvm.log10.f32(float %{{.*}}) #[[LOG10:[0-9]+]]
; No mapping of "llvm.log10.f32" to a vector function for SVML.
; SVML-NOT: _ZGV_LLVM_{{.*}}_llvm.log10.f32({{.*}})
; AMDLIBM-NOT: _ZGV_LLVM_{{.*}}_llvm.log10.f32({{.*}})
@@ -304,6 +312,11 @@ declare double @ldexp(double, i32 signext) #0
; ARMPL: declare aarch64_vector_pcs <4 x float> @armpl_vlog10q_f32(<4 x float>)
; ARMPL: declare <vscale x 4 x float> @armpl_svlog10_f32_x(<vscale x 4 x float>, <vscale x 4 x i1>)
+; HVML: declare <2 x double> @hvml_vd2_sin(<2 x double>)
+; HVML: declare <4 x double> @hvml_vd4_sin(<4 x double>)
+; HVML: declare <4 x float> @hvml_vs4_log10(<4 x float>)
+; HVML: declare <8 x float> @hvml_vs8_log10(<8 x float>)
+
attributes #0 = { nounwind readnone }
; SVML: attributes #[[SIN]] = { "vector-function-abi-variant"=
@@ -414,3 +427,10 @@ attributes #0 = { nounwind readnone }
; ARMPL: attributes #[[LOG10]] = { "vector-function-abi-variant"=
; ARMPL-SAME: "_ZGV_LLVM_N4v_llvm.log10.f32(armpl_vlog10q_f32),
; ARMPL-SAME: _ZGVsMxv_llvm.log10.f32(armpl_svlog10_f32_x)" }
+
+; HVML: attributes #[[SIN]] = { "vector-function-abi-variant"=
+; HVML-SAME: "_ZGV_LLVM_N2v_sin(hvml_vd2_sin),
+; HVML-SAME: _ZGV_LLVM_N4v_sin(hvml_vd4_sin)" }
+; HVML: attributes #[[LOG10]] = { "vector-function-abi-variant"=
+; HVML-SAME: "_ZGV_LLVM_N4v_llvm.log10.f32(hvml_vs4_log10),
+; HVML-SAME: _ZGV_LLVM_N8v_llvm.log10.f32(hvml_vs8_log10)" }
More information about the flang-commits
mailing list