This commit moves most of the sincos helper functions to the CLC library. It simultaneously vectorizes them with the aim to increase performance for vector types by avoiding scalarization. Some helpers for double types remain as they use various features not yet ready, like 'fract' which in turn relies on 'fmin'; neither of these are in the CLC library. They also use table lookups and type punning which don't translate well to vector versions. As a proof of concept, float and half versions of the sin and cos builtins are now vectorized and use the CLC helpers to do so. They remain in the OpenCL layer but will be simpler to move to the CLC library when the double versions are ready.
50 lines
1.4 KiB
Common Lisp
50 lines
1.4 KiB
Common Lisp
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "sincos_helpers.h"
|
|
#include <clc/clc.h>
|
|
#include <clc/clc_convert.h>
|
|
#include <clc/clcmacro.h>
|
|
#include <clc/math/clc_fabs.h>
|
|
#include <clc/math/clc_sincos_helpers.h>
|
|
#include <clc/math/math.h>
|
|
#include <clc/relational/clc_isinf.h>
|
|
#include <clc/relational/clc_isnan.h>
|
|
#include <clc/relational/clc_select.h>
|
|
|
|
// FP32 and FP16 versions.
|
|
#define __CLC_BODY <sin.inc>
|
|
#include <clc/math/gentype.inc>
|
|
|
|
#ifdef cl_khr_fp64
|
|
|
|
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
|
|
|
_CLC_OVERLOAD _CLC_DEF double sin(double x) {
|
|
double y = fabs(x);
|
|
|
|
double r, rr;
|
|
int regn;
|
|
|
|
if (y < 0x1.0p+47)
|
|
__clc_remainder_piby2_medium(y, &r, &rr, ®n);
|
|
else
|
|
__clc_remainder_piby2_large(y, &r, &rr, ®n);
|
|
|
|
double2 sc = __clc_sincos_piby4(r, rr);
|
|
|
|
int2 s = as_int2(regn & 1 ? sc.hi : sc.lo);
|
|
s.hi ^= ((regn > 1) << 31) ^ ((x < 0.0) << 31);
|
|
|
|
return isinf(x) | isnan(x) ? as_double(QNANBITPATT_DP64) : as_double(s);
|
|
}
|
|
|
|
_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, sin, double);
|
|
|
|
#endif
|