[libclc] Move fmin & fmax to CLC library (#134218)

This is an alternative to #128506 which doesn't attempt to change the
codegen for fmin and fmax on their way to the CLC library.

The amdgcn and r600 custom definitions of fmin/fmax are now converted to
custom definitions of __clc_fmin and __clc_fmax.

For simplicity, the CLC library doesn't provide vector/scalar versions
of these builtins. The OpenCL layer wraps those up to the vector/vector
versions.

The only codegen change is that non-standard vector/scalar overloads of
fmin/fmax have been removed. We were currently (accidentally,
presumably) providing overloads with mixed elment types such as
fmin(double2, float), fmax(half4, double), etc. The only vector/scalar
overloads in the OpenCL spec are those with scalars of the same element
type as the vector in the first argument.
This commit is contained in:
Fraser Cormack
2025-04-29 10:51:24 +01:00
committed by GitHub
parent f6b6fb89ec
commit 4609b6a3e7
21 changed files with 329 additions and 239 deletions

View File

@@ -1,6 +1,4 @@
cl_khr_int64_extended_atomics/minmax_helpers.ll
math/fmax.cl
math/fmin.cl
mem_fence/fence.cl
synchronization/barrier.cl
workitem/get_global_offset.cl

View File

@@ -1,53 +0,0 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clc.h>
#include <clc/clcmacro.h>
_CLC_DEF _CLC_OVERLOAD float fmax(float x, float y)
{
/* fcanonicalize removes sNaNs and flushes denormals if not enabled.
* Otherwise fmax instruction flushes the values for comparison,
* but outputs original denormal */
x = __builtin_canonicalizef(x);
y = __builtin_canonicalizef(y);
return __builtin_fmaxf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, fmax, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double fmax(double x, double y)
{
x = __builtin_canonicalize(x);
y = __builtin_canonicalize(y);
return __builtin_fmax(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, fmax, double, double)
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half fmax(half x, half y)
{
if (isnan(x))
return y;
if (isnan(y))
return x;
return (y < x) ? x : y;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, fmax, half, half)
#endif
#define __CLC_BODY <../../../generic/lib/math/fmax.inc>
#include <clc/math/gentype.inc>

View File

@@ -1,53 +0,0 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clc.h>
#include <clc/clcmacro.h>
_CLC_DEF _CLC_OVERLOAD float fmin(float x, float y)
{
/* fcanonicalize removes sNaNs and flushes denormals if not enabled.
* Otherwise fmin instruction flushes the values for comparison,
* but outputs original denormal */
x = __builtin_canonicalizef(x);
y = __builtin_canonicalizef(y);
return __builtin_fminf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, fmin, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double fmin(double x, double y)
{
x = __builtin_canonicalize(x);
y = __builtin_canonicalize(y);
return __builtin_fmin(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, fmin, double, double)
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half fmin(half x, half y)
{
if (isnan(x))
return y;
if (isnan(y))
return x;
return (y < x) ? y : x;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, fmin, half, half)
#endif
#define __CLC_BODY <../../../generic/lib/math/fmin.inc>
#include <clc/math/gentype.inc>

View File

@@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef __CLC_MATH_CLC_FMAX_H__
#define __CLC_MATH_CLC_FMAX_H__
#define __CLC_FUNCTION __clc_fmax
#define __CLC_BODY <clc/shared/binary_decl.inc>
#include <clc/math/gentype.inc>
#undef __CLC_BODY
#undef __CLC_FUNCTION
#endif // __CLC_MATH_CLC_FMAX_H__

View File

@@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef __CLC_MATH_CLC_FMIN_H__
#define __CLC_MATH_CLC_FMIN_H__
#define __CLC_FUNCTION __clc_fmin
#define __CLC_BODY <clc/shared/binary_decl.inc>
#include <clc/math/gentype.inc>
#undef __CLC_BODY
#undef __CLC_FUNCTION
#endif // __CLC_MATH_CLC_FMIN_H__

View File

@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE __CLC_FUNCTION(__CLC_GENTYPE x,
__CLC_GENTYPE y);
#ifndef __CLC_SCALAR
_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE __CLC_FUNCTION(__CLC_GENTYPE x,
__CLC_SCALAR_GENTYPE y);
#endif

View File

@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/utils.h>
#ifndef __CLC_FUNCTION
#define __CLC_FUNCTION(x) __CLC_CONCAT(__clc_, x)
#endif
_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE FUNCTION(__CLC_GENTYPE a,
__CLC_GENTYPE b) {
return __CLC_FUNCTION(FUNCTION)(a, b);
}
#ifndef __CLC_SCALAR
_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE FUNCTION(__CLC_GENTYPE a,
__CLC_SCALAR_GENTYPE b) {
return __CLC_FUNCTION(FUNCTION)(a, (__CLC_GENTYPE)b);
}
#endif

View File

@@ -1 +1,3 @@
math/clc_fmax.cl
math/clc_fmin.cl
math/clc_ldexp_override.cl

View File

@@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clcmacro.h>
#include <clc/internal/clc.h>
#include <clc/relational/clc_isnan.h>
_CLC_DEF _CLC_OVERLOAD float __clc_fmax(float x, float y) {
// fcanonicalize removes sNaNs and flushes denormals if not enabled. Otherwise
// fmax instruction flushes the values for comparison, but outputs original
// denormal
x = __builtin_canonicalizef(x);
y = __builtin_canonicalizef(y);
return __builtin_fmaxf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_fmax, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double __clc_fmax(double x, double y) {
x = __builtin_canonicalize(x);
y = __builtin_canonicalize(y);
return __builtin_fmax(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_fmax, double,
double)
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half __clc_fmax(half x, half y) {
if (__clc_isnan(x))
return y;
if (__clc_isnan(y))
return x;
return (y < x) ? x : y;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, __clc_fmax, half, half)
#endif

View File

@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clcmacro.h>
#include <clc/internal/clc.h>
#include <clc/relational/clc_isnan.h>
_CLC_DEF _CLC_OVERLOAD float __clc_fmin(float x, float y) {
// fcanonicalize removes sNaNs and flushes denormals if not enabled. Otherwise
// fmin instruction flushes the values for comparison, but outputs original
// denormal
x = __builtin_canonicalizef(x);
y = __builtin_canonicalizef(y);
return __builtin_fminf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_fmin, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double __clc_fmin(double x, double y) {
x = __builtin_canonicalize(x);
y = __builtin_canonicalize(y);
return __builtin_fmin(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_fmin, double,
double)
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half __clc_fmin(half x, half y) {
if (__clc_isnan(x))
return y;
if (__clc_isnan(y))
return x;
return (y < x) ? y : x;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, __clc_fmin, half, half)
#endif

View File

@@ -42,8 +42,10 @@ math/clc_expm1.cl
math/clc_exp_helper.cl
math/clc_fabs.cl
math/clc_fma.cl
math/clc_fmod.cl
math/clc_fmax.cl
math/clc_fmin.cl
math/clc_floor.cl
math/clc_fmod.cl
math/clc_frexp.cl
math/clc_hypot.cl
math/clc_ldexp.cl

View File

@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clcmacro.h>
#include <clc/internal/clc.h>
#include <clc/relational/clc_isnan.h>
_CLC_DEFINE_BINARY_BUILTIN(float, __clc_fmax, __builtin_fmaxf, float, float);
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEFINE_BINARY_BUILTIN(double, __clc_fmax, __builtin_fmax, double, double);
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half __clc_fmax(half x, half y) {
if (__clc_isnan(x))
return y;
if (__clc_isnan(y))
return x;
return (x < y) ? y : x;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, __clc_fmax, half, half)
#endif

View File

@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clcmacro.h>
#include <clc/internal/clc.h>
#include <clc/relational/clc_isnan.h>
_CLC_DEFINE_BINARY_BUILTIN(float, __clc_fmin, __builtin_fminf, float, float);
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEFINE_BINARY_BUILTIN(double, __clc_fmin, __builtin_fmin, double, double);
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half __clc_fmin(half x, half y) {
if (__clc_isnan(x))
return y;
if (__clc_isnan(y))
return x;
return (y < x) ? y : x;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, __clc_fmin, half, half)
#endif

View File

@@ -1,2 +1,4 @@
math/clc_fmax.cl
math/clc_fmin.cl
math/clc_native_rsqrt.cl
math/clc_rsqrt_override.cl

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clcmacro.h>
#include <clc/internal/clc.h>
#include <clc/math/math.h>
_CLC_DEF _CLC_OVERLOAD float __clc_fmax(float x, float y) {
// Flush denormals if not enabled. Otherwise fmax instruction flushes the
// values for comparison, but outputs original denormal
x = __clc_flush_denormal_if_not_supported(x);
y = __clc_flush_denormal_if_not_supported(y);
return __builtin_fmaxf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_fmax, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double __clc_fmax(double x, double y) {
return __builtin_fmax(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_fmax, double,
double)
#endif

View File

@@ -0,0 +1,33 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clcmacro.h>
#include <clc/internal/clc.h>
#include <clc/math/math.h>
_CLC_DEF _CLC_OVERLOAD float __clc_fmin(float x, float y) {
// fcanonicalize removes sNaNs and flushes denormals if not enabled. Otherwise
// fmin instruction flushes the values for comparison, but outputs original
// denormal
x = __clc_flush_denormal_if_not_supported(x);
y = __clc_flush_denormal_if_not_supported(y);
return __builtin_fminf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_fmin, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double __clc_fmin(double x, double y) {
return __builtin_fmin(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_fmin, double,
double)
#endif

View File

@@ -7,33 +7,8 @@
//===----------------------------------------------------------------------===//
#include <clc/clc.h>
#include <clc/clcmacro.h>
#include <clc/math/clc_fmax.h>
_CLC_DEFINE_BINARY_BUILTIN(float, fmax, __builtin_fmaxf, float, float);
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEFINE_BINARY_BUILTIN(double, fmax, __builtin_fmax, double, double);
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half fmax(half x, half y)
{
if (isnan(x))
return y;
if (isnan(y))
return x;
return (x < y) ? y : x;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, fmax, half, half)
#endif
#define __CLC_BODY <fmax.inc>
#define FUNCTION fmax
#define __CLC_BODY <clc/shared/binary_def_with_scalar_second_arg.inc>
#include <clc/math/gentype.inc>

View File

@@ -7,32 +7,8 @@
//===----------------------------------------------------------------------===//
#include <clc/clc.h>
#include <clc/clcmacro.h>
#include <clc/math/clc_fmin.h>
_CLC_DEFINE_BINARY_BUILTIN(float, fmin, __builtin_fminf, float, float);
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEFINE_BINARY_BUILTIN(double, fmin, __builtin_fmin, double, double);
#endif
#ifdef cl_khr_fp16
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
_CLC_DEF _CLC_OVERLOAD half fmin(half x, half y)
{
if (isnan(x))
return y;
if (isnan(y))
return x;
return (y < x) ? y : x;
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, fmin, half, half)
#endif
#define __CLC_BODY <fmin.inc>
#define FUNCTION fmin
#define __CLC_BODY <clc/shared/binary_def_with_scalar_second_arg.inc>
#include <clc/math/gentype.inc>

View File

@@ -1,5 +1,3 @@
math/fmax.cl
math/fmin.cl
synchronization/barrier.cl
workitem/get_global_offset.cl
workitem/get_group_id.cl

View File

@@ -1,36 +0,0 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clc.h>
#include <clc/clcmacro.h>
#include <clc/math/math.h>
_CLC_DEF _CLC_OVERLOAD float fmax(float x, float y)
{
/* Flush denormals if not enabled. Otherwise fmax instruction flushes
* the values for comparison, but outputs original denormal */
x = __clc_flush_denormal_if_not_supported(x);
y = __clc_flush_denormal_if_not_supported(y);
return __builtin_fmaxf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, fmax, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double fmax(double x, double y)
{
return __builtin_fmax(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, fmax, double, double)
#endif
#define __CLC_BODY <../../../generic/lib/math/fmax.inc>
#include <clc/math/gentype.inc>

View File

@@ -1,37 +0,0 @@
//===----------------------------------------------------------------------===//
//
// 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 <clc/clc.h>
#include <clc/clcmacro.h>
#include <clc/math/math.h>
_CLC_DEF _CLC_OVERLOAD float fmin(float x, float y)
{
/* fcanonicalize removes sNaNs and flushes denormals if not enabled.
* Otherwise fmin instruction flushes the values for comparison,
* but outputs original denormal */
x = __clc_flush_denormal_if_not_supported(x);
y = __clc_flush_denormal_if_not_supported(y);
return __builtin_fminf(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, fmin, float, float)
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
_CLC_DEF _CLC_OVERLOAD double fmin(double x, double y)
{
return __builtin_fmin(x, y);
}
_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, fmin, double, double)
#endif
#define __CLC_BODY <../../../generic/lib/math/fmin.inc>
#include <clc/math/gentype.inc>