From c0b8c8f0c41b56b60be7f375988ddee88099efbe Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Wed, 5 Jun 2019 01:31:43 +0000 Subject: [PATCH] Initial support for IBM MASS vector library This is the LLVM portion of patch https://reviews.llvm.org/D59881. The clang portion is to follow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362568 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/TargetLibraryInfo.h | 1 + include/llvm/Analysis/VecFuncs.def | 79 +- lib/Analysis/TargetLibraryInfo.cpp | 10 + .../LoopVectorize/PowerPC/massv-altivec.ll | 106 ++ .../LoopVectorize/PowerPC/massv-calls.ll | 1525 +++++++++++++++++ .../LoopVectorize/PowerPC/massv-nobuiltin.ll | 56 + .../PowerPC/massv-unsupported.ll | 108 ++ 7 files changed, 1884 insertions(+), 1 deletion(-) create mode 100644 test/Transforms/LoopVectorize/PowerPC/massv-altivec.ll create mode 100644 test/Transforms/LoopVectorize/PowerPC/massv-calls.ll create mode 100644 test/Transforms/LoopVectorize/PowerPC/massv-nobuiltin.ll create mode 100644 test/Transforms/LoopVectorize/PowerPC/massv-unsupported.ll diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h index a40e04404ff..4b5200f5a83 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.h +++ b/include/llvm/Analysis/TargetLibraryInfo.h @@ -86,6 +86,7 @@ public: enum VectorLibrary { NoLibrary, // Don't use any vector library. Accelerate, // Use Accelerate framework. + MASSV, // IBM MASS vector library. SVML // Intel short vector math library. }; diff --git a/include/llvm/Analysis/VecFuncs.def b/include/llvm/Analysis/VecFuncs.def index 15ff4def300..4c9206266d9 100644 --- a/include/llvm/Analysis/VecFuncs.def +++ b/include/llvm/Analysis/VecFuncs.def @@ -8,7 +8,7 @@ // This .def file will create mappings from scalar math functions to vector // functions along with their vectorization factor. The current support includes -// such mappings for Accelerate framework and SVML library. +// such mappings for Accelerate framework, MASS vector library, and SVML library. #if !(defined(TLI_DEFINE_VECFUNC)) #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF) {SCAL, VEC, VF}, @@ -55,6 +55,82 @@ TLI_DEFINE_VECFUNC("acoshf", "vacoshf", 4) TLI_DEFINE_VECFUNC("atanhf", "vatanhf", 4) +#elif defined(TLI_DEFINE_MASSV_VECFUNCS) +// IBM MASS library's vector Functions + +// Floating-Point Arithmetic and Auxiliary Functions +TLI_DEFINE_VECFUNC("cbrt", "__cbrtd2_massv", 2) +TLI_DEFINE_VECFUNC("cbrtf", "__cbrtf4_massv", 4) +TLI_DEFINE_VECFUNC("pow", "__powd2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.pow.f64", "__powd2_massv", 2) +TLI_DEFINE_VECFUNC("powf", "__powf4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.pow.f32", "__powf4_massv", 4) +TLI_DEFINE_VECFUNC("sqrt", "__sqrtd2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.sqrt.f64", "__sqrtd2_massv", 2) +TLI_DEFINE_VECFUNC("sqrtf", "__sqrtf4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.sqrt.f32", "__sqrtf4_massv", 4) + +// Exponential and Logarithmic Functions +TLI_DEFINE_VECFUNC("exp", "__expd2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.exp.f64", "__expd2_massv", 2) +TLI_DEFINE_VECFUNC("expf", "__expf4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.exp.f32", "__expf4_massv", 4) +TLI_DEFINE_VECFUNC("exp2", "__exp2d2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.exp2.f64", "__exp2d2_massv", 2) +TLI_DEFINE_VECFUNC("exp2f", "__exp2f4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.exp2.f32", "__exp2f4_massv", 4) +TLI_DEFINE_VECFUNC("expm1", "__expm1d2_massv", 2) +TLI_DEFINE_VECFUNC("expm1f", "__expm1f4_massv", 4) +TLI_DEFINE_VECFUNC("log", "__logd2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.log.f64", "__logd2_massv", 2) +TLI_DEFINE_VECFUNC("logf", "__logf4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.log.f32", "__logf4_massv", 4) +TLI_DEFINE_VECFUNC("log1p", "__log1pd2_massv", 2) +TLI_DEFINE_VECFUNC("log1pf", "__log1pf4_massv", 4) +TLI_DEFINE_VECFUNC("log10", "__log10d2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.log10.f64", "__log10d2_massv", 2) +TLI_DEFINE_VECFUNC("log10f", "__log10f4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.log10.f32", "__log10f4_massv", 4) +TLI_DEFINE_VECFUNC("log2", "__log2d2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.log2.f64", "__log2d2_massv", 2) +TLI_DEFINE_VECFUNC("log2f", "__log2f4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.log2.f32", "__log2f4_massv", 4) + +// Trigonometric Functions +TLI_DEFINE_VECFUNC("sin", "__sind2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.sin.f64", "__sind2_massv", 2) +TLI_DEFINE_VECFUNC("sinf", "__sinf4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.sin.f32", "__sinf4_massv", 4) +TLI_DEFINE_VECFUNC("cos", "__cosd2_massv", 2) +TLI_DEFINE_VECFUNC("llvm.cos.f64", "__cosd2_massv", 2) +TLI_DEFINE_VECFUNC("cosf", "__cosf4_massv", 4) +TLI_DEFINE_VECFUNC("llvm.cos.f32", "__cosf4_massv", 4) +TLI_DEFINE_VECFUNC("tan", "__tand2_massv", 2) +TLI_DEFINE_VECFUNC("tanf", "__tanf4_massv", 4) +TLI_DEFINE_VECFUNC("asin", "__asind2_massv", 2) +TLI_DEFINE_VECFUNC("asinf", "__asinf4_massv", 4) +TLI_DEFINE_VECFUNC("acos", "__acosd2_massv", 2) +TLI_DEFINE_VECFUNC("acosf", "__acosf4_massv", 4) +TLI_DEFINE_VECFUNC("atan", "__atand2_massv", 2) +TLI_DEFINE_VECFUNC("atanf", "__atanf4_massv", 4) +TLI_DEFINE_VECFUNC("atan2", "__atan2d2_massv", 2) +TLI_DEFINE_VECFUNC("atan2f", "__atan2f4_massv", 4) + +// Hyperbolic Functions +TLI_DEFINE_VECFUNC("sinh", "__sinhd2_massv", 2) +TLI_DEFINE_VECFUNC("sinhf", "__sinhf4_massv", 4) +TLI_DEFINE_VECFUNC("cosh", "__coshd2_massv", 2) +TLI_DEFINE_VECFUNC("coshf", "__coshf4_massv", 4) +TLI_DEFINE_VECFUNC("tanh", "__tanhd2_massv", 2) +TLI_DEFINE_VECFUNC("tanhf", "__tanhf4_massv", 4) +TLI_DEFINE_VECFUNC("asinh", "__asinhd2_massv", 2) +TLI_DEFINE_VECFUNC("asinhf", "__asinhf4_massv", 4) +TLI_DEFINE_VECFUNC("acosh", "__acoshd2_massv", 2) +TLI_DEFINE_VECFUNC("acoshf", "__acoshf4_massv", 4) +TLI_DEFINE_VECFUNC("atanh", "__atanhd2_massv", 2) +TLI_DEFINE_VECFUNC("atanhf", "__atanhf4_massv", 4) + + #elif defined(TLI_DEFINE_SVML_VECFUNCS) // Intel SVM library's Vector Functions @@ -169,5 +245,6 @@ TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf16", 16) #undef TLI_DEFINE_VECFUNC #undef TLI_DEFINE_ACCELERATE_VECFUNCS +#undef TLI_DEFINE_MASSV_VECFUNCS #undef TLI_DEFINE_SVML_VECFUNCS diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp index e5cb2544f2d..ef139d3257d 100644 --- a/lib/Analysis/TargetLibraryInfo.cpp +++ b/lib/Analysis/TargetLibraryInfo.cpp @@ -23,6 +23,8 @@ static cl::opt ClVectorLibrary( "No vector functions library"), clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate", "Accelerate framework"), + clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV", + "IBM MASS vector library"), clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", "Intel SVML library"))); @@ -1537,6 +1539,14 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( addVectorizableFunctions(VecFuncs); break; } + case MASSV: { + const VecDesc VecFuncs[] = { + #define TLI_DEFINE_MASSV_VECFUNCS + #include "llvm/Analysis/VecFuncs.def" + }; + addVectorizableFunctions(VecFuncs); + break; + } case SVML: { const VecDesc VecFuncs[] = { #define TLI_DEFINE_SVML_VECFUNCS diff --git a/test/Transforms/LoopVectorize/PowerPC/massv-altivec.ll b/test/Transforms/LoopVectorize/PowerPC/massv-altivec.ll new file mode 100644 index 00000000000..c63db5b0b66 --- /dev/null +++ b/test/Transforms/LoopVectorize/PowerPC/massv-altivec.ll @@ -0,0 +1,106 @@ +; RUN: opt -vector-library=MASSV -loop-vectorize -force-vector-interleave=1 -mattr=-altivec -S < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-unknown-linux-gnu" + +declare double @cbrt(double) #0 +declare float @cbrtf(float) #0 + +declare double @atanh(double) #0 +declare float @atanhf(float) #0 + +; MASSV is unsupported for AltiVec. +; Check that massv entries are not generated. +define void @cbrt_f64(double* nocapture %varray) { +; CHECK-LABEL: @cbrt_f64( +; CHECK-NOT: __cbrtd2_massv{{.*}}<2 x double> +; 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 @cbrt(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @cbrt_f32(float* nocapture %varray) { +; CHECK-LABEL: @cbrt_f32( +; CHECK-NOT: __cbrtf4_massv{{.*}}<4 x float> +; 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 @cbrtf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 @atanh_f64(double* nocapture %varray) { +; CHECK-LABEL: @atanh_f64( +; CHECK-NOT: __atanhd2_massv{{.*}}<2 x double> +; 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 @atanh(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @atanh_f32(float* nocapture %varray) { +; CHECK-LABEL: @atanh_f32( +; CHECK-NOT: __atanhf4_massv{{.*}}<2 x double> +; 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 @atanhf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 +} + +attributes #0 = { nounwind } diff --git a/test/Transforms/LoopVectorize/PowerPC/massv-calls.ll b/test/Transforms/LoopVectorize/PowerPC/massv-calls.ll new file mode 100644 index 00000000000..a08c23b5b2d --- /dev/null +++ b/test/Transforms/LoopVectorize/PowerPC/massv-calls.ll @@ -0,0 +1,1525 @@ +; RUN: opt -vector-library=MASSV -loop-vectorize -force-vector-interleave=1 -S < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-unknown-linux-gnu" + +declare double @cbrt(double) #0 +declare float @cbrtf(float) #0 + +declare double @pow(double, double) #0 +declare double @llvm.pow.f64(double, double) #0 +declare float @powf(float, float) #0 +declare float @llvm.pow.f32(float, float) #0 + +declare double @sqrt(double) #0 +declare float @sqrtf(float) #0 + +declare double @exp(double) #0 +declare double @llvm.exp.f64(double) #0 +declare float @expf(float) #0 +declare float @llvm.exp.f32(float) #0 + +declare double @exp2(double) #0 +declare double @llvm.exp2.f64(double) #0 +declare float @exp2f(float) #0 +declare float @llvm.exp2.f32(float) #0 + +declare double @expm1(double) #0 +declare float @expm1f(float) #0 + +declare double @log(double) #0 +declare double @llvm.log.f64(double) #0 +declare float @logf(float) #0 +declare float @llvm.log.f32(float) #0 + +declare double @log1p(double) #0 +declare float @log1pf(float) #0 + +declare double @log10(double) #0 +declare double @llvm.log10.f64(double) #0 +declare float @log10f(float) #0 +declare float @llvm.log10.f32(float) #0 + +declare double @log2(double) #0 +declare double @llvm.log2.f64(double) #0 +declare float @log2f(float) #0 +declare float @llvm.log2.f32(float) #0 + +declare double @sin(double) #0 +declare double @llvm.sin.f64(double) #0 +declare float @sinf(float) #0 +declare float @llvm.sin.f32(float) #0 + +declare double @cos(double) #0 +declare double @llvm.cos.f64(double) #0 +declare float @cosf(float) #0 +declare float @llvm.cos.f32(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 @atan2(double) #0 +declare float @atan2f(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 @asinh(double) #0 +declare float @asinhf(float) #0 + +declare double @acosh(double) #0 +declare float @acoshf(float) #0 + +declare double @atanh(double) #0 +declare float @atanhf(float) #0 + +define void @cbrt_f64(double* nocapture %varray) { +; CHECK-LABEL: @cbrt_f64( +; CHECK: __cbrtd2_massv{{.*}}<2 x double> +; 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 @cbrt(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @cbrt_f32(float* nocapture %varray) { +; CHECK-LABEL: @cbrt_f32( +; CHECK: __cbrtf4_massv{{.*}}<4 x float> +; 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 @cbrtf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray, double* nocapture readonly %exp) { +; CHECK-LABEL: @pow_f64( +; CHECK: __powd2_massv{{.*}}<2 x double> +; 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, double* %exp, i64 %iv + %tmp1 = load double, double* %arrayidx, align 4 + %tmp2 = tail call double @pow(double %conv, double %tmp1) + %arrayidx2 = getelementptr inbounds double, double* %varray, i64 %iv + store double %tmp2, double* %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(double* nocapture %varray, double* nocapture readonly %exp) { +; CHECK-LABEL: @pow_f64_intrinsic( +; CHECK: __powd2_massv{{.*}}<2 x double> +; 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, double* %exp, i64 %iv + %tmp1 = load double, double* %arrayidx, align 4 + %tmp2 = tail call double @llvm.pow.f64(double %conv, double %tmp1) + %arrayidx2 = getelementptr inbounds double, double* %varray, i64 %iv + store double %tmp2, double* %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(float* nocapture %varray, float* nocapture readonly %exp) { +; CHECK-LABEL: @pow_f32( +; CHECK: __powf4_massv{{.*}}<4 x float> +; 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, float* %exp, i64 %iv + %tmp1 = load float, float* %arrayidx, align 4 + %tmp2 = tail call float @powf(float %conv, float %tmp1) + %arrayidx2 = getelementptr inbounds float, float* %varray, i64 %iv + store float %tmp2, float* %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(float* nocapture %varray, float* nocapture readonly %exp) { +; CHECK-LABEL: @pow_f32_intrinsic( +; CHECK: __powf4_massv{{.*}}<4 x float> +; 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, float* %exp, i64 %iv + %tmp1 = load float, float* %arrayidx, align 4 + %tmp2 = tail call float @llvm.pow.f32(float %conv, float %tmp1) + %arrayidx2 = getelementptr inbounds float, float* %varray, i64 %iv + store float %tmp2, float* %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 @sqrt_f64(double* nocapture %varray) { +; CHECK-LABEL: @sqrt_f64( +; CHECK: __sqrtd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @sqrt_f32( +; CHECK: __sqrtf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @exp_f64( +; CHECK: __expd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @exp_f64_intrinsic( +; CHECK: __expd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @exp_f32( +; CHECK: __expf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @exp_f32_intrinsic( +; CHECK: __expf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @exp2_f64( +; CHECK: __exp2d2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @exp2_f64_intrinsic( +; CHECK: __exp2d2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @exp2_f32( +; CHECK: __exp2f4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @exp2_f32_intrinsic( +; CHECK: __exp2f4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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 @expm1_f64(double* nocapture %varray) { +; CHECK-LABEL: @expm1_f64( +; CHECK: __expm1d2_massv{{.*}}<2 x double> +; 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 @expm1(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @expm1_f32(float* nocapture %varray) { +; CHECK-LABEL: @expm1_f32( +; CHECK: __expm1f4_massv{{.*}}<4 x float> +; 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 @expm1f(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @log_f64( +; CHECK: __logd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @log_f64_intrinsic( +; CHECK: __logd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @log_f32( +; CHECK: __logf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @log_f32_intrinsic( +; CHECK: __logf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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 @log1p_f64(double* nocapture %varray) { +; CHECK-LABEL: @log1p_f64( +; CHECK: __log1pd2_massv{{.*}}<2 x double> +; 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 @log1p(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @log1p_f32(float* nocapture %varray) { +; CHECK-LABEL: @log1p_f32( +; CHECK: __log1pf4_massv{{.*}}<4 x float> +; 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 @log1pf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @log10_f64( +; CHECK: __log10d2_massv(<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @log10_f64_intrinsic( +; CHECK: __log10d2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @log10_f32( +; CHECK: __log10f4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @log10_f32_intrinsic( +; CHECK: __log10f4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @log2_f64( +; CHECK: __log2d2_massv(<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @log2_f64_intrinsic( +; CHECK: __log2d2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @log2_f32( +; CHECK: __log2f4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @log2_f32_intrinsic( +; CHECK: __log2f4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @sin_f64( +; CHECK: __sind2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @sin_f64_intrinsic( +; CHECK: __sind2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @sin_f32( +; CHECK: __sinf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @sin_f32_intrinsic( +; CHECK: __sinf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @cos_f64( +; CHECK: __cosd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(double* nocapture %varray) { +; CHECK-LABEL: @cos_f64_intrinsic( +; CHECK: [[TMP5:%.*]] = call <2 x double> @__cosd2_massv(<2 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @cos_f32( +; CHECK: __cosf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(float* nocapture %varray) { +; CHECK-LABEL: @cos_f32_intrinsic( +; CHECK: __cosf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @tan_f64( +; CHECK: __tand2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @tan_f32( +; CHECK: __tanf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @asin_f64( +; CHECK: __asind2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @asin_f32( +; CHECK: __asinf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @acos_f64( +; CHECK: __acosd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @acos_f32( +; CHECK: __acosf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @atan_f64( +; CHECK: __atand2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @atan_f32( +; CHECK: __atanf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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 @atan2_f64(double* nocapture %varray) { +; CHECK-LABEL: @atan2_f64( +; CHECK: __atan2d2_massv{{.*}}<2 x double> +; 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 @atan2(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @atan2_f32(float* nocapture %varray) { +; CHECK-LABEL: @atan2_f32( +; CHECK: __atan2f4_massv{{.*}}<4 x float> +; 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 @atan2f(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @sinh_f64( +; CHECK: __sinhd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @sinh_f32( +; CHECK: __sinhf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @cosh_f64( +; CHECK: __coshd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @cosh_f32( +; CHECK: __coshf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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(double* nocapture %varray) { +; CHECK-LABEL: @tanh_f64( +; CHECK: __tanhd2_massv{{.*}}<2 x double> +; 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, double* %varray, i64 %iv + store double %call, double* %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(float* nocapture %varray) { +; CHECK-LABEL: @tanh_f32( +; CHECK: __tanhf4_massv{{.*}}<4 x float> +; 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, float* %varray, i64 %iv + store float %call, float* %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 @asinh_f64(double* nocapture %varray) { +; CHECK-LABEL: @asinh_f64( +; CHECK: __asinhd2_massv{{.*}}<2 x double> +; 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 @asinh(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @asinh_f32(float* nocapture %varray) { +; CHECK-LABEL: @asinh_f32( +; CHECK: __asinhf4_massv{{.*}}<4 x float> +; 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 @asinhf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 @acosh_f64(double* nocapture %varray) { +; CHECK-LABEL: @acosh_f64( +; CHECK: __acoshd2_massv{{.*}}<2 x double> +; 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 @acosh(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @acosh_f32(float* nocapture %varray) { +; CHECK-LABEL: @acosh_f32( +; CHECK: __acoshf4_massv{{.*}}<4 x float> +; 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 @acoshf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 @atanh_f64(double* nocapture %varray) { +; CHECK-LABEL: @atanh_f64( +; CHECK: __atanhd2_massv{{.*}}<2 x double> +; 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 @atanh(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @atanh_f32(float* nocapture %varray) { +; CHECK-LABEL: @atanh_f32( +; CHECK: __atanhf4_massv{{.*}}<4 x float> +; 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 @atanhf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 +} + +attributes #0 = { nounwind } diff --git a/test/Transforms/LoopVectorize/PowerPC/massv-nobuiltin.ll b/test/Transforms/LoopVectorize/PowerPC/massv-nobuiltin.ll new file mode 100644 index 00000000000..e7503b615f4 --- /dev/null +++ b/test/Transforms/LoopVectorize/PowerPC/massv-nobuiltin.ll @@ -0,0 +1,56 @@ +; RUN: opt -vector-library=MASSV -loop-vectorize -force-vector-interleave=1 -S < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-unknown-linux-gnu" + +declare double @atanh(double) #1 +declare float @atanhf(float) #1 + +; Check that functions marked as nobuiltin are not lowered to massv entries. +define void @atanh_f64(double* nocapture %varray) { +; CHECK-LABEL: @atanh_f64( +; CHECK-NOT: __atanhd2_massv{{.*}}<2 x double> +; 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 @atanh(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 @atanh_f32(float* nocapture %varray) { +; CHECK-LABEL: @atanh_f32( +; CHECK-NOT: __atanhf4_massv{{.*}}<2 x double> +; 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 @atanhf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 +} + +attributes #1 = { nobuiltin nounwind } diff --git a/test/Transforms/LoopVectorize/PowerPC/massv-unsupported.ll b/test/Transforms/LoopVectorize/PowerPC/massv-unsupported.ll new file mode 100644 index 00000000000..f9b4b72a027 --- /dev/null +++ b/test/Transforms/LoopVectorize/PowerPC/massv-unsupported.ll @@ -0,0 +1,108 @@ +; RUN: opt -vector-library=MASSV -loop-vectorize -force-vector-interleave=1 -S < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-unknown-linux-gnu" + +declare double @ceil(double) #0 +declare float @fabsf(float) #0 + +declare double @llvm.sqrt.f64(double) #0 +declare float @llvm.sqrt.f32(float) #0 + +; Vector counterpart of ceil is unsupported in MASSV library. +define void @ceil_f64(double* nocapture %varray) { +; CHECK-LABEL: @ceil_f64( +; CHECK-NOT: __ceild2_massv{{.*}}<2 x double> +; 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 @ceil(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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 +} + +; Vector counterpart of fabs is unsupported in MASSV library. +define void @fabs_f32(float* nocapture %varray) { +; CHECK-LABEL: @fabs_f32( +; CHECK-NOT: __fabsf4_massv{{.*}}<4 x float> +; 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 @fabsf(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 +} + +; sqrt intrinsics are converted to their vector counterpart intrinsics. +; They are not lowered to MASSV entries. +define void @sqrt_f64_intrinsic(double* nocapture %varray) { +; CHECK-LABEL: @sqrt_f64_intrinsic( +; CHECK: llvm.sqrt.v2f64{{.*}}<2 x double> +; 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.sqrt.f64(double %conv) + %arrayidx = getelementptr inbounds double, double* %varray, i64 %iv + store double %call, double* %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_intrinsic(float* nocapture %varray) { +; CHECK-LABEL: @sqrt_f32_intrinsic( +; CHECK: llvm.sqrt.v4f32{{.*}}<4 x float> +; 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.sqrt.f32(float %conv) + %arrayidx = getelementptr inbounds float, float* %varray, i64 %iv + store float %call, float* %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 +} + +attributes #0 = { nounwind } -- 2.40.0