[libclc] [libclc] Move relational functions to the CLC library (PR #115171)

Fraser Cormack via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 6 08:14:54 PST 2024


https://github.com/frasercrmck updated https://github.com/llvm/llvm-project/pull/115171

>From c8323a91b779163d808507528b1db29b598c30f6 Mon Sep 17 00:00:00 2001
From: Fraser Cormack <fraser at codeplay.com>
Date: Mon, 4 Nov 2024 16:02:56 +0000
Subject: [PATCH] [libclc] Move relational functions to CLC library

The OpenCL relational functions now call their CLC counterparts, and the
CLC relational functions are defined identically to how the OpenCL
functions were defined.

As usual, clspv and spir-v targets bypass these.

No observable changes to any libclc target (measured with llvm-diff).
---
 libclc/clc/include/clc/clc_as_type.h          |  82 ++++++++++
 libclc/clc/include/clc/internal/clc.h         |   3 +
 .../include/clc/relational/binary_decl.inc    |   2 +
 libclc/clc/include/clc/relational/clc_all.h   |  31 ++++
 libclc/clc/include/clc/relational/clc_any.h   |  31 ++++
 .../include/clc/relational/clc_bitselect.h    |  33 ++++
 .../include/clc/relational/clc_bitselect.inc  |  25 +++
 .../clc/include/clc/relational/clc_isequal.h  |  41 +++++
 .../clc/include/clc/relational/clc_isfinite.h |  19 +++
 .../include/clc/relational/clc_isgreater.h    |  19 +++
 .../clc/relational/clc_isgreaterequal.h       |  19 +++
 libclc/clc/include/clc/relational/clc_isinf.h |  41 +++++
 .../clc/include/clc/relational/clc_isless.h   |  19 +++
 .../include/clc/relational/clc_islessequal.h  |  19 +++
 .../clc/relational/clc_islessgreater.h        |  19 +++
 libclc/clc/include/clc/relational/clc_isnan.h |  41 +++++
 .../clc/include/clc/relational/clc_isnormal.h |  19 +++
 .../include/clc/relational/clc_isnotequal.h   |  19 +++
 .../include/clc/relational/clc_isordered.h    |  19 +++
 .../include/clc/relational/clc_isunordered.h  |  19 +++
 .../clc/include/clc/relational/clc_select.h   |  23 +++
 .../clc/include/clc/relational/clc_select.inc |  29 ++++
 .../clc/include/clc/relational/clc_signbit.h  |  19 +++
 .../include/clc/relational/floatn.inc         |   0
 .../clc/include/clc/relational/relational.h   | 145 ++++++++++++++++++
 .../include/clc/relational/unary_decl.inc     |   0
 libclc/clc/lib/generic/SOURCES                |  18 +++
 libclc/clc/lib/generic/relational/clc_all.cl  |  28 ++++
 libclc/clc/lib/generic/relational/clc_any.cl  |  28 ++++
 .../lib/generic/relational/clc_bitselect.cl   |  55 +++++++
 .../lib/generic/relational/clc_bitselect.inc  |  27 ++++
 .../clc/lib/generic/relational/clc_isequal.cl |  44 ++++++
 .../lib/generic/relational/clc_isfinite.cl    |  31 ++++
 .../lib/generic/relational/clc_isgreater.cl   |  39 +++++
 .../generic/relational/clc_isgreaterequal.cl  |  39 +++++
 .../clc/lib/generic/relational/clc_isinf.cl   |  26 ++++
 .../clc/lib/generic/relational/clc_isless.cl  |  37 +++++
 .../lib/generic/relational/clc_islessequal.cl |  39 +++++
 .../generic/relational/clc_islessgreater.cl   |  38 +++++
 .../clc/lib/generic/relational/clc_isnan.cl   |  28 ++++
 .../lib/generic/relational/clc_isnormal.cl    |  31 ++++
 .../lib/generic/relational/clc_isnotequal.cl  |  33 ++++
 .../lib/generic/relational/clc_isordered.cl   |  34 ++++
 .../lib/generic/relational/clc_isunordered.cl |  38 +++++
 .../clc/lib/generic/relational/clc_select.cl  |   7 +
 .../clc/lib/generic/relational/clc_select.inc |  35 +++++
 .../clc/lib/generic/relational/clc_signbit.cl |  33 ++++
 libclc/generic/include/clc/relational/any.h   |   3 +
 .../include/clc/relational/binary_decl.inc    |   1 -
 libclc/generic/lib/math/clc_exp10.cl          |   5 +-
 libclc/generic/lib/math/clc_fma.cl            |   7 +-
 libclc/generic/lib/math/clc_hypot.cl          |   3 +-
 libclc/generic/lib/math/clc_ldexp.cl          |   6 +-
 libclc/generic/lib/math/clc_nextafter.cl      |  49 +++---
 libclc/generic/lib/math/clc_tan.cl            |   5 +-
 libclc/generic/lib/relational/all.cl          |  30 ++--
 libclc/generic/lib/relational/any.cl          |  31 ++--
 libclc/generic/lib/relational/binary_def.inc  |   7 +
 libclc/generic/lib/relational/bitselect.cl    |  10 +-
 libclc/generic/lib/relational/isequal.cl      |  45 +-----
 libclc/generic/lib/relational/isfinite.cl     |  32 +---
 libclc/generic/lib/relational/isgreater.cl    |  38 +----
 .../generic/lib/relational/isgreaterequal.cl  |  37 +----
 libclc/generic/lib/relational/isinf.cl        |  31 +---
 libclc/generic/lib/relational/isless.cl       |  37 +----
 libclc/generic/lib/relational/islessequal.cl  |  37 +----
 .../generic/lib/relational/islessgreater.cl   |  37 +----
 libclc/generic/lib/relational/isnan.cl        |  33 +---
 libclc/generic/lib/relational/isnormal.cl     |  32 +---
 libclc/generic/lib/relational/isnotequal.cl   |  34 +---
 libclc/generic/lib/relational/isordered.cl    |  34 +---
 libclc/generic/lib/relational/isunordered.cl  |  37 +----
 libclc/generic/lib/relational/relational.h    | 117 --------------
 libclc/generic/lib/relational/signbit.cl      |  34 +---
 libclc/generic/lib/relational/unary_def.inc   |   7 +
 75 files changed, 1565 insertions(+), 638 deletions(-)
 create mode 100644 libclc/clc/include/clc/clc_as_type.h
 create mode 100644 libclc/clc/include/clc/relational/binary_decl.inc
 create mode 100644 libclc/clc/include/clc/relational/clc_all.h
 create mode 100644 libclc/clc/include/clc/relational/clc_any.h
 create mode 100644 libclc/clc/include/clc/relational/clc_bitselect.h
 create mode 100644 libclc/clc/include/clc/relational/clc_bitselect.inc
 create mode 100644 libclc/clc/include/clc/relational/clc_isequal.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isfinite.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isgreater.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isgreaterequal.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isinf.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isless.h
 create mode 100644 libclc/clc/include/clc/relational/clc_islessequal.h
 create mode 100644 libclc/clc/include/clc/relational/clc_islessgreater.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isnan.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isnormal.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isnotequal.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isordered.h
 create mode 100644 libclc/clc/include/clc/relational/clc_isunordered.h
 create mode 100644 libclc/clc/include/clc/relational/clc_select.h
 create mode 100644 libclc/clc/include/clc/relational/clc_select.inc
 create mode 100644 libclc/clc/include/clc/relational/clc_signbit.h
 rename libclc/{generic => clc}/include/clc/relational/floatn.inc (100%)
 create mode 100644 libclc/clc/include/clc/relational/relational.h
 rename libclc/{generic => clc}/include/clc/relational/unary_decl.inc (100%)
 create mode 100644 libclc/clc/lib/generic/relational/clc_all.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_any.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_bitselect.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_bitselect.inc
 create mode 100644 libclc/clc/lib/generic/relational/clc_isequal.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isfinite.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isgreater.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isgreaterequal.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isinf.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isless.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_islessequal.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_islessgreater.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isnan.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isnormal.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isnotequal.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isordered.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_isunordered.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_select.cl
 create mode 100644 libclc/clc/lib/generic/relational/clc_select.inc
 create mode 100644 libclc/clc/lib/generic/relational/clc_signbit.cl
 delete mode 100644 libclc/generic/include/clc/relational/binary_decl.inc
 create mode 100644 libclc/generic/lib/relational/binary_def.inc
 delete mode 100644 libclc/generic/lib/relational/relational.h
 create mode 100644 libclc/generic/lib/relational/unary_def.inc

diff --git a/libclc/clc/include/clc/clc_as_type.h b/libclc/clc/include/clc/clc_as_type.h
new file mode 100644
index 00000000000000..966139523e80b2
--- /dev/null
+++ b/libclc/clc/include/clc/clc_as_type.h
@@ -0,0 +1,82 @@
+#ifndef __CLC_CLC_AS_TYPE_H__
+#define __CLC_CLC_AS_TYPE_H__
+
+#define __clc_as_char(x) __builtin_astype(x, char)
+#define __clc_as_uchar(x) __builtin_astype(x, uchar)
+#define __clc_as_short(x) __builtin_astype(x, short)
+#define __clc_as_ushort(x) __builtin_astype(x, ushort)
+#define __clc_as_int(x) __builtin_astype(x, int)
+#define __clc_as_uint(x) __builtin_astype(x, uint)
+#define __clc_as_long(x) __builtin_astype(x, long)
+#define __clc_as_ulong(x) __builtin_astype(x, ulong)
+#define __clc_as_float(x) __builtin_astype(x, float)
+
+#define __clc_as_char2(x) __builtin_astype(x, char2)
+#define __clc_as_uchar2(x) __builtin_astype(x, uchar2)
+#define __clc_as_short2(x) __builtin_astype(x, short2)
+#define __clc_as_ushort2(x) __builtin_astype(x, ushort2)
+#define __clc_as_int2(x) __builtin_astype(x, int2)
+#define __clc_as_uint2(x) __builtin_astype(x, uint2)
+#define __clc_as_long2(x) __builtin_astype(x, long2)
+#define __clc_as_ulong2(x) __builtin_astype(x, ulong2)
+#define __clc_as_float2(x) __builtin_astype(x, float2)
+
+#define __clc_as_char3(x) __builtin_astype(x, char3)
+#define __clc_as_uchar3(x) __builtin_astype(x, uchar3)
+#define __clc_as_short3(x) __builtin_astype(x, short3)
+#define __clc_as_ushort3(x) __builtin_astype(x, ushort3)
+#define __clc_as_int3(x) __builtin_astype(x, int3)
+#define __clc_as_uint3(x) __builtin_astype(x, uint3)
+#define __clc_as_long3(x) __builtin_astype(x, long3)
+#define __clc_as_ulong3(x) __builtin_astype(x, ulong3)
+#define __clc_as_float3(x) __builtin_astype(x, float3)
+
+#define __clc_as_char4(x) __builtin_astype(x, char4)
+#define __clc_as_uchar4(x) __builtin_astype(x, uchar4)
+#define __clc_as_short4(x) __builtin_astype(x, short4)
+#define __clc_as_ushort4(x) __builtin_astype(x, ushort4)
+#define __clc_as_int4(x) __builtin_astype(x, int4)
+#define __clc_as_uint4(x) __builtin_astype(x, uint4)
+#define __clc_as_long4(x) __builtin_astype(x, long4)
+#define __clc_as_ulong4(x) __builtin_astype(x, ulong4)
+#define __clc_as_float4(x) __builtin_astype(x, float4)
+
+#define __clc_as_char8(x) __builtin_astype(x, char8)
+#define __clc_as_uchar8(x) __builtin_astype(x, uchar8)
+#define __clc_as_short8(x) __builtin_astype(x, short8)
+#define __clc_as_ushort8(x) __builtin_astype(x, ushort8)
+#define __clc_as_int8(x) __builtin_astype(x, int8)
+#define __clc_as_uint8(x) __builtin_astype(x, uint8)
+#define __clc_as_long8(x) __builtin_astype(x, long8)
+#define __clc_as_ulong8(x) __builtin_astype(x, ulong8)
+#define __clc_as_float8(x) __builtin_astype(x, float8)
+
+#define __clc_as_char16(x) __builtin_astype(x, char16)
+#define __clc_as_uchar16(x) __builtin_astype(x, uchar16)
+#define __clc_as_short16(x) __builtin_astype(x, short16)
+#define __clc_as_ushort16(x) __builtin_astype(x, ushort16)
+#define __clc_as_int16(x) __builtin_astype(x, int16)
+#define __clc_as_uint16(x) __builtin_astype(x, uint16)
+#define __clc_as_long16(x) __builtin_astype(x, long16)
+#define __clc_as_ulong16(x) __builtin_astype(x, ulong16)
+#define __clc_as_float16(x) __builtin_astype(x, float16)
+
+#ifdef cl_khr_fp64
+#define __clc_as_double(x) __builtin_astype(x, double)
+#define __clc_as_double2(x) __builtin_astype(x, double2)
+#define __clc_as_double3(x) __builtin_astype(x, double3)
+#define __clc_as_double4(x) __builtin_astype(x, double4)
+#define __clc_as_double8(x) __builtin_astype(x, double8)
+#define __clc_as_double16(x) __builtin_astype(x, double16)
+#endif
+
+#ifdef cl_khr_fp16
+#define __clc_as_half(x) __builtin_astype(x, half)
+#define __clc_as_half2(x) __builtin_astype(x, half2)
+#define __clc_as_half3(x) __builtin_astype(x, half3)
+#define __clc_as_half4(x) __builtin_astype(x, half4)
+#define __clc_as_half8(x) __builtin_astype(x, half8)
+#define __clc_as_half16(x) __builtin_astype(x, half16)
+#endif
+
+#endif // __CLC_CLC_AS_TYPE_H__
diff --git a/libclc/clc/include/clc/internal/clc.h b/libclc/clc/include/clc/internal/clc.h
index c3bdfd754105f7..f448c6c50ba526 100644
--- a/libclc/clc/include/clc/internal/clc.h
+++ b/libclc/clc/include/clc/internal/clc.h
@@ -21,6 +21,9 @@
 /* 6.1 Supported Data Types */
 #include <clc/clctypes.h>
 
+/* 6.2.4.2 Reinterpreting Types Using __clc_as_type() and __clc_as_typen() */
+#include <clc/clc_as_type.h>
+
 #pragma OPENCL EXTENSION all : disable
 
 #endif // __CLC_INTERNAL_CLC_H_
diff --git a/libclc/clc/include/clc/relational/binary_decl.inc b/libclc/clc/include/clc/relational/binary_decl.inc
new file mode 100644
index 00000000000000..2e4b4fde1efe8f
--- /dev/null
+++ b/libclc/clc/include/clc/relational/binary_decl.inc
@@ -0,0 +1,2 @@
+_CLC_OVERLOAD _CLC_DECL __CLC_INTN __CLC_FUNCTION(__CLC_FLOATN a,
+                                                  __CLC_FLOATN b);
diff --git a/libclc/clc/include/clc/relational/clc_all.h b/libclc/clc/include/clc/relational/clc_all.h
new file mode 100644
index 00000000000000..bf068105aa1be1
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_all.h
@@ -0,0 +1,31 @@
+#ifndef __CLC_RELATIONAL_CLC_ALL_H__
+#define __CLC_RELATIONAL_CLC_ALL_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible all
+#define __clc_all all
+#else
+
+#include <clc/clcfunc.h>
+
+#define _CLC_ALL_DECL(TYPE) _CLC_OVERLOAD _CLC_DECL int __clc_all(TYPE v);
+
+#define _CLC_VECTOR_ALL_DECL(TYPE)                                             \
+  _CLC_ALL_DECL(TYPE)                                                          \
+  _CLC_ALL_DECL(TYPE##2)                                                       \
+  _CLC_ALL_DECL(TYPE##3)                                                       \
+  _CLC_ALL_DECL(TYPE##4)                                                       \
+  _CLC_ALL_DECL(TYPE##8)                                                       \
+  _CLC_ALL_DECL(TYPE##16)
+
+_CLC_VECTOR_ALL_DECL(char)
+_CLC_VECTOR_ALL_DECL(short)
+_CLC_VECTOR_ALL_DECL(int)
+_CLC_VECTOR_ALL_DECL(long)
+
+#undef _CLC_ALL_DECL
+#undef _CLC_VECTOR_ALL_DECL
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ALL_H__
diff --git a/libclc/clc/include/clc/relational/clc_any.h b/libclc/clc/include/clc/relational/clc_any.h
new file mode 100644
index 00000000000000..f947b77e08341f
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_any.h
@@ -0,0 +1,31 @@
+#ifndef __CLC_RELATIONAL_CLC_ANY_H__
+#define __CLC_RELATIONAL_CLC_ANY_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible any
+#define __clc_any any
+#else
+
+#include <clc/clcfunc.h>
+
+#define _CLC_ANY_DECL(TYPE) _CLC_OVERLOAD _CLC_DECL int __clc_any(TYPE v);
+
+#define _CLC_VECTOR_ANY_DECL(TYPE)                                             \
+  _CLC_ANY_DECL(TYPE)                                                          \
+  _CLC_ANY_DECL(TYPE##2)                                                       \
+  _CLC_ANY_DECL(TYPE##3)                                                       \
+  _CLC_ANY_DECL(TYPE##4)                                                       \
+  _CLC_ANY_DECL(TYPE##8)                                                       \
+  _CLC_ANY_DECL(TYPE##16)
+
+_CLC_VECTOR_ANY_DECL(char)
+_CLC_VECTOR_ANY_DECL(short)
+_CLC_VECTOR_ANY_DECL(int)
+_CLC_VECTOR_ANY_DECL(long)
+
+#undef _CLC_ANY_DECL
+#undef _CLC_VECTOR_ANY_DECL
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ANY_H__
diff --git a/libclc/clc/include/clc/relational/clc_bitselect.h b/libclc/clc/include/clc/relational/clc_bitselect.h
new file mode 100644
index 00000000000000..53fae6a7a2dcba
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_bitselect.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __CLC_RELATIONAL_CLC_BITSELECT_H__
+#define __CLC_RELATIONAL_CLC_BITSELECT_H__
+
+#define __CLC_BODY <clc/relational/clc_bitselect.inc>
+#include <clc/math/gentype.inc>
+#define __CLC_BODY <clc/relational/clc_bitselect.inc>
+#include <clc/integer/gentype.inc>
+
+#undef __CLC_BODY
+
+#endif // __CLC_RELATIONAL_CLC_BITSELECT_H__
diff --git a/libclc/clc/include/clc/relational/clc_bitselect.inc b/libclc/clc/include/clc/relational/clc_bitselect.inc
new file mode 100644
index 00000000000000..14d5bea6dbe7d9
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_bitselect.inc
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE __clc_bitselect(__CLC_GENTYPE x,
+                                                      __CLC_GENTYPE y,
+                                                      __CLC_GENTYPE z);
diff --git a/libclc/clc/include/clc/relational/clc_isequal.h b/libclc/clc/include/clc/relational/clc_isequal.h
new file mode 100644
index 00000000000000..3a36ea24fd2994
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isequal.h
@@ -0,0 +1,41 @@
+#ifndef __CLC_RELATIONAL_CLC_ISEQUAL_H__
+#define __CLC_RELATIONAL_CLC_ISEQUAL_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isequal
+#define __clc_isequal isequal
+#else
+
+#include <clc/clcfunc.h>
+
+#define _CLC_ISEQUAL_DECL(TYPE, RETTYPE)                                       \
+  _CLC_OVERLOAD _CLC_DECL RETTYPE __clc_isequal(TYPE x, TYPE y);
+
+#define _CLC_VECTOR_ISEQUAL_DECL(TYPE, RETTYPE)                                \
+  _CLC_ISEQUAL_DECL(TYPE##2, RETTYPE##2)                                       \
+  _CLC_ISEQUAL_DECL(TYPE##3, RETTYPE##3)                                       \
+  _CLC_ISEQUAL_DECL(TYPE##4, RETTYPE##4)                                       \
+  _CLC_ISEQUAL_DECL(TYPE##8, RETTYPE##8)                                       \
+  _CLC_ISEQUAL_DECL(TYPE##16, RETTYPE##16)
+
+_CLC_ISEQUAL_DECL(float, int)
+_CLC_VECTOR_ISEQUAL_DECL(float, int)
+
+#ifdef cl_khr_fp64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+_CLC_ISEQUAL_DECL(double, int)
+_CLC_VECTOR_ISEQUAL_DECL(double, long)
+#endif
+
+#ifdef cl_khr_fp16
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+_CLC_ISEQUAL_DECL(half, int)
+_CLC_VECTOR_ISEQUAL_DECL(half, short)
+#endif
+
+#undef _CLC_ISEQUAL_DECL
+#undef _CLC_VECTOR_ISEQUAL_DECL
+
+#endif
+
+#endif //  __CLC_RELATIONAL_CLC_ISEQUAL_H__
diff --git a/libclc/clc/include/clc/relational/clc_isfinite.h b/libclc/clc/include/clc/relational/clc_isfinite.h
new file mode 100644
index 00000000000000..3ed276e07a2f10
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isfinite.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISFINITE_H__
+#define __CLC_RELATIONAL_CLC_ISFINITE_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isfinite
+#define __clc_isfinite isfinite
+#else
+
+#define __CLC_FUNCTION __clc_isfinite
+#define __CLC_BODY <clc/relational/unary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISFINITE_H__
diff --git a/libclc/clc/include/clc/relational/clc_isgreater.h b/libclc/clc/include/clc/relational/clc_isgreater.h
new file mode 100644
index 00000000000000..b51d59aeb54998
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isgreater.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISGREATER_H__
+#define __CLC_RELATIONAL_CLC_ISGREATER_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isgreater
+#define __clc_isgreater isgreater
+#else
+
+#define __CLC_FUNCTION __clc_isgreater
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISGREATER_H__
diff --git a/libclc/clc/include/clc/relational/clc_isgreaterequal.h b/libclc/clc/include/clc/relational/clc_isgreaterequal.h
new file mode 100644
index 00000000000000..b7ffce151847fd
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isgreaterequal.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISGREATEREQUAL_H__
+#define __CLC_RELATIONAL_CLC_ISGREATEREQUAL_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isgreaterequal
+#define __clc_isgreaterequal isgreaterequal
+#else
+
+#define __CLC_FUNCTION __clc_isgreaterequal
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISGREATEREQUAL_H__
diff --git a/libclc/clc/include/clc/relational/clc_isinf.h b/libclc/clc/include/clc/relational/clc_isinf.h
new file mode 100644
index 00000000000000..c33ef9bb9527d3
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isinf.h
@@ -0,0 +1,41 @@
+#ifndef __CLC_RELATIONAL_CLC_ISINF_H__
+#define __CLC_RELATIONAL_CLC_ISINF_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isinf
+#define __clc_isinf isinf
+#else
+
+#include <clc/clcfunc.h>
+
+#define _CLC_ISINF_DECL(RET_TYPE, ARG_TYPE)                                    \
+  _CLC_OVERLOAD _CLC_DECL RET_TYPE __clc_isinf(ARG_TYPE);
+
+#define _CLC_VECTOR_ISINF_DECL(RET_TYPE, ARG_TYPE)                             \
+  _CLC_ISINF_DECL(RET_TYPE##2, ARG_TYPE##2)                                    \
+  _CLC_ISINF_DECL(RET_TYPE##3, ARG_TYPE##3)                                    \
+  _CLC_ISINF_DECL(RET_TYPE##4, ARG_TYPE##4)                                    \
+  _CLC_ISINF_DECL(RET_TYPE##8, ARG_TYPE##8)                                    \
+  _CLC_ISINF_DECL(RET_TYPE##16, ARG_TYPE##16)
+
+_CLC_ISINF_DECL(int, float)
+_CLC_VECTOR_ISINF_DECL(int, float)
+
+#ifdef cl_khr_fp64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+_CLC_ISINF_DECL(int, double)
+_CLC_VECTOR_ISINF_DECL(long, double)
+#endif
+
+#ifdef cl_khr_fp16
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+_CLC_ISINF_DECL(int, half)
+_CLC_VECTOR_ISINF_DECL(short, half)
+#endif
+
+#undef _CLC_ISINF_DECL
+#undef _CLC_VECTOR_ISINF_DECL
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISINF_H__
diff --git a/libclc/clc/include/clc/relational/clc_isless.h b/libclc/clc/include/clc/relational/clc_isless.h
new file mode 100644
index 00000000000000..c6950aa61ad908
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isless.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISLESS_H__
+#define __CLC_RELATIONAL_CLC_ISLESS_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isless
+#define __clc_isless isless
+#else
+
+#define __CLC_FUNCTION __clc_isless
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISLESS_H__
diff --git a/libclc/clc/include/clc/relational/clc_islessequal.h b/libclc/clc/include/clc/relational/clc_islessequal.h
new file mode 100644
index 00000000000000..7efac163e106a2
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_islessequal.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISLESSEQUAL_H__
+#define __CLC_RELATIONAL_CLC_ISLESSEQUAL_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible islessequal
+#define __clc_islessequal islessequal
+#else
+
+#define __CLC_FUNCTION __clc_islessequal
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISLESSEQUAL_H__
diff --git a/libclc/clc/include/clc/relational/clc_islessgreater.h b/libclc/clc/include/clc/relational/clc_islessgreater.h
new file mode 100644
index 00000000000000..df3c5e513c86ce
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_islessgreater.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISLESSGREATER_H__
+#define __CLC_RELATIONAL_CLC_ISLESSGREATER_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible islessgreater
+#define __clc_islessgreater islessgreater
+#else
+
+#define __CLC_FUNCTION __clc_islessgreater
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISLESSGREATER_H__
diff --git a/libclc/clc/include/clc/relational/clc_isnan.h b/libclc/clc/include/clc/relational/clc_isnan.h
new file mode 100644
index 00000000000000..08351eb5515f9c
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isnan.h
@@ -0,0 +1,41 @@
+#ifndef __CLC_RELATIONAL_CLC_ISNAN_H__
+#define __CLC_RELATIONAL_CLC_ISNAN_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isnan
+#define __clc_isnan isnan
+#else
+
+#include <clc/clcfunc.h>
+
+#define _CLC_ISNAN_DECL(RET_TYPE, ARG_TYPE)                                    \
+  _CLC_OVERLOAD _CLC_DECL RET_TYPE __clc_isnan(ARG_TYPE);
+
+#define _CLC_VECTOR_ISNAN_DECL(RET_TYPE, ARG_TYPE)                             \
+  _CLC_ISNAN_DECL(RET_TYPE##2, ARG_TYPE##2)                                    \
+  _CLC_ISNAN_DECL(RET_TYPE##3, ARG_TYPE##3)                                    \
+  _CLC_ISNAN_DECL(RET_TYPE##4, ARG_TYPE##4)                                    \
+  _CLC_ISNAN_DECL(RET_TYPE##8, ARG_TYPE##8)                                    \
+  _CLC_ISNAN_DECL(RET_TYPE##16, ARG_TYPE##16)
+
+_CLC_ISNAN_DECL(int, float)
+_CLC_VECTOR_ISNAN_DECL(int, float)
+
+#ifdef cl_khr_fp64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+_CLC_ISNAN_DECL(int, double)
+_CLC_VECTOR_ISNAN_DECL(long, double)
+#endif
+
+#ifdef cl_khr_fp16
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+_CLC_ISNAN_DECL(int, half)
+_CLC_VECTOR_ISNAN_DECL(short, half)
+#endif
+
+#undef _CLC_ISNAN_DECL
+#undef _CLC_VECTOR_ISNAN_DECL
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISNAN_H__
diff --git a/libclc/clc/include/clc/relational/clc_isnormal.h b/libclc/clc/include/clc/relational/clc_isnormal.h
new file mode 100644
index 00000000000000..48ee6b83a5711b
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isnormal.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISNORMAL_H__
+#define __CLC_RELATIONAL_CLC_ISNORMAL_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isnormal
+#define __clc_isnormal isnormal
+#else
+
+#define __CLC_FUNCTION __clc_isnormal
+#define __CLC_BODY <clc/relational/unary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISNORMAL_H__
diff --git a/libclc/clc/include/clc/relational/clc_isnotequal.h b/libclc/clc/include/clc/relational/clc_isnotequal.h
new file mode 100644
index 00000000000000..55c1bd91b2dd5d
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isnotequal.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISNOTEQUAL_H__
+#define __CLC_RELATIONAL_CLC_ISNOTEQUAL_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isnotequal
+#define __clc_isnotequal isnotequal
+#else
+
+#define __CLC_FUNCTION __clc_isnotequal
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISNOTEQUAL_H__
diff --git a/libclc/clc/include/clc/relational/clc_isordered.h b/libclc/clc/include/clc/relational/clc_isordered.h
new file mode 100644
index 00000000000000..5ce2bfe334027f
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isordered.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISORDERED_H__
+#define __CLC_RELATIONAL_CLC_ISORDERED_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isordered
+#define __clc_isordered isordered
+#else
+
+#define __CLC_FUNCTION __clc_isordered
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISORDERED_H__
diff --git a/libclc/clc/include/clc/relational/clc_isunordered.h b/libclc/clc/include/clc/relational/clc_isunordered.h
new file mode 100644
index 00000000000000..305d2b4e9131ff
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_isunordered.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_ISUNORDERED_H__
+#define __CLC_RELATIONAL_CLC_ISUNORDERED_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible isunordered
+#define __clc_isunordered isunordered
+#else
+
+#define __CLC_FUNCTION __clc_isunordered
+#define __CLC_BODY <clc/relational/binary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_ISUNORDERED_H__
diff --git a/libclc/clc/include/clc/relational/clc_select.h b/libclc/clc/include/clc/relational/clc_select.h
new file mode 100644
index 00000000000000..ddea7c528ec74a
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_select.h
@@ -0,0 +1,23 @@
+#ifndef __CLC_RELATIONAL_CLC_SELECT_H__
+#define __CLC_RELATIONAL_CLC_SELECT_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible select
+#define __clc_select select
+#else
+
+/* Duplciate these so we don't have to distribute utils.h */
+#define __CLC_CONCAT(x, y) x##y
+#define __CLC_XCONCAT(x, y) __CLC_CONCAT(x, y)
+
+#define __CLC_BODY <clc/relational/clc_select.inc>
+#include <clc/math/gentype.inc>
+#define __CLC_BODY <clc/relational/clc_select.inc>
+#include <clc/integer/gentype.inc>
+
+#undef __CLC_CONCAT
+#undef __CLC_XCONCAT
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_SELECT_H__
diff --git a/libclc/clc/include/clc/relational/clc_select.inc b/libclc/clc/include/clc/relational/clc_select.inc
new file mode 100644
index 00000000000000..abf0e0fa436003
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_select.inc
@@ -0,0 +1,29 @@
+#ifdef __CLC_SCALAR
+#define __CLC_VECSIZE
+#endif
+
+#if __CLC_FPSIZE == 64
+#define __CLC_S_GENTYPE __CLC_XCONCAT(long, __CLC_VECSIZE)
+#define __CLC_U_GENTYPE __CLC_XCONCAT(ulong, __CLC_VECSIZE)
+#elif __CLC_FPSIZE == 32
+#define __CLC_S_GENTYPE __CLC_XCONCAT(int, __CLC_VECSIZE)
+#define __CLC_U_GENTYPE __CLC_XCONCAT(uint, __CLC_VECSIZE)
+#elif __CLC_FPSIZE == 16
+#define __CLC_S_GENTYPE __CLC_XCONCAT(short, __CLC_VECSIZE)
+#define __CLC_U_GENTYPE __CLC_XCONCAT(ushort, __CLC_VECSIZE)
+#endif
+
+_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE __clc_select(__CLC_GENTYPE x,
+                                                   __CLC_GENTYPE y,
+                                                   __CLC_S_GENTYPE z);
+_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE __clc_select(__CLC_GENTYPE x,
+                                                   __CLC_GENTYPE y,
+                                                   __CLC_U_GENTYPE z);
+
+#ifdef __CLC_FPSIZE
+#undef __CLC_S_GENTYPE
+#undef __CLC_U_GENTYPE
+#endif
+#ifdef __CLC_SCALAR
+#undef __CLC_VECSIZE
+#endif
diff --git a/libclc/clc/include/clc/relational/clc_signbit.h b/libclc/clc/include/clc/relational/clc_signbit.h
new file mode 100644
index 00000000000000..45a7112c9eb969
--- /dev/null
+++ b/libclc/clc/include/clc/relational/clc_signbit.h
@@ -0,0 +1,19 @@
+#ifndef __CLC_RELATIONAL_CLC_SIGNBIT_H__
+#define __CLC_RELATIONAL_CLC_SIGNBIT_H__
+
+#if defined(CLC_CLSPV) || defined(CLC_SPIRV)
+// clspv and spir-v targets provide their own OpenCL-compatible signbit
+#define __clc_signbit signbit
+#else
+
+#define __CLC_FUNCTION __clc_signbit
+#define __CLC_BODY <clc/relational/unary_decl.inc>
+
+#include <clc/relational/floatn.inc>
+
+#undef __CLC_BODY
+#undef __CLC_FUNCTION
+
+#endif
+
+#endif // __CLC_RELATIONAL_CLC_SIGNBIT_H__
diff --git a/libclc/generic/include/clc/relational/floatn.inc b/libclc/clc/include/clc/relational/floatn.inc
similarity index 100%
rename from libclc/generic/include/clc/relational/floatn.inc
rename to libclc/clc/include/clc/relational/floatn.inc
diff --git a/libclc/clc/include/clc/relational/relational.h b/libclc/clc/include/clc/relational/relational.h
new file mode 100644
index 00000000000000..54241b6493c8e7
--- /dev/null
+++ b/libclc/clc/include/clc/relational/relational.h
@@ -0,0 +1,145 @@
+#ifndef __CLC_RELATIONAL_RELATIONAL_H__
+#define __CLC_RELATIONAL_RELATIONAL_H__
+
+/*
+ * Contains relational macros that have to return 1 for scalar and -1 for vector
+ * when the result is true.
+ */
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_NAME,  \
+                                            ARG_TYPE)                          \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) {                       \
+    return BUILTIN_NAME(x);                                                    \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_VEC2(RET_TYPE, FUNCTION, ARG_TYPE)        \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) {                       \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.lo), FUNCTION(x.hi)} !=            \
+                      (RET_TYPE)0);                                            \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_VEC3(RET_TYPE, FUNCTION, ARG_TYPE)        \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) {                       \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.s0), FUNCTION(x.s1),               \
+                                 FUNCTION(x.s2)} != (RET_TYPE)0);              \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_VEC4(RET_TYPE, FUNCTION, ARG_TYPE)        \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) {                       \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.s0), FUNCTION(x.s1),               \
+                                 FUNCTION(x.s2),                               \
+                                 FUNCTION(x.s3)} != (RET_TYPE)0);              \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_VEC8(RET_TYPE, FUNCTION, ARG_TYPE)        \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) {                       \
+    return (                                                                   \
+        RET_TYPE)((RET_TYPE){FUNCTION(x.s0), FUNCTION(x.s1), FUNCTION(x.s2),   \
+                             FUNCTION(x.s3), FUNCTION(x.s4), FUNCTION(x.s5),   \
+                             FUNCTION(x.s6), FUNCTION(x.s7)} != (RET_TYPE)0);  \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_VEC16(RET_TYPE, FUNCTION, ARG_TYPE)       \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) {                       \
+    return (                                                                   \
+        RET_TYPE)((RET_TYPE){FUNCTION(x.s0), FUNCTION(x.s1), FUNCTION(x.s2),   \
+                             FUNCTION(x.s3), FUNCTION(x.s4), FUNCTION(x.s5),   \
+                             FUNCTION(x.s6), FUNCTION(x.s7), FUNCTION(x.s8),   \
+                             FUNCTION(x.s9), FUNCTION(x.sa), FUNCTION(x.sb),   \
+                             FUNCTION(x.sc), FUNCTION(x.sd), FUNCTION(x.se),   \
+                             FUNCTION(x.sf)} != (RET_TYPE)0);                  \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(RET_TYPE, FUNCTION, ARG_TYPE)     \
+  _CLC_DEFINE_RELATIONAL_UNARY_VEC2(RET_TYPE##2, FUNCTION, ARG_TYPE##2)        \
+  _CLC_DEFINE_RELATIONAL_UNARY_VEC3(RET_TYPE##3, FUNCTION, ARG_TYPE##3)        \
+  _CLC_DEFINE_RELATIONAL_UNARY_VEC4(RET_TYPE##4, FUNCTION, ARG_TYPE##4)        \
+  _CLC_DEFINE_RELATIONAL_UNARY_VEC8(RET_TYPE##8, FUNCTION, ARG_TYPE##8)        \
+  _CLC_DEFINE_RELATIONAL_UNARY_VEC16(RET_TYPE##16, FUNCTION, ARG_TYPE##16)
+
+#define _CLC_DEFINE_RELATIONAL_UNARY(RET_TYPE, FUNCTION, BUILTIN_FUNCTION,     \
+                                     ARG_TYPE)                                 \
+  _CLC_DEFINE_RELATIONAL_UNARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_FUNCTION,    \
+                                      ARG_TYPE)                                \
+  _CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(RET_TYPE, FUNCTION, ARG_TYPE)
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_NAME, \
+                                             ARG0_TYPE, ARG1_TYPE)             \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return BUILTIN_NAME(x, y);                                                 \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC(RET_TYPE, FUNCTION, ARG0_TYPE,       \
+                                          ARG1_TYPE)                           \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.lo, y.lo),                         \
+                                 FUNCTION(x.hi, y.hi)} != (RET_TYPE)0);        \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC2(RET_TYPE, FUNCTION, ARG0_TYPE,      \
+                                           ARG1_TYPE)                          \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.lo, y.lo),                         \
+                                 FUNCTION(x.hi, y.hi)} != (RET_TYPE)0);        \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC3(RET_TYPE, FUNCTION, ARG0_TYPE,      \
+                                           ARG1_TYPE)                          \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1),   \
+                                 FUNCTION(x.s2, y.s2)} != (RET_TYPE)0);        \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC4(RET_TYPE, FUNCTION, ARG0_TYPE,      \
+                                           ARG1_TYPE)                          \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1),   \
+                                 FUNCTION(x.s2, y.s2),                         \
+                                 FUNCTION(x.s3, y.s3)} != (RET_TYPE)0);        \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC8(RET_TYPE, FUNCTION, ARG0_TYPE,      \
+                                           ARG1_TYPE)                          \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1),   \
+                                 FUNCTION(x.s2, y.s2), FUNCTION(x.s3, y.s3),   \
+                                 FUNCTION(x.s4, y.s4), FUNCTION(x.s5, y.s5),   \
+                                 FUNCTION(x.s6, y.s6),                         \
+                                 FUNCTION(x.s7, y.s7)} != (RET_TYPE)0);        \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC16(RET_TYPE, FUNCTION, ARG0_TYPE,     \
+                                            ARG1_TYPE)                         \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) {         \
+    return (RET_TYPE)((RET_TYPE){FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1),   \
+                                 FUNCTION(x.s2, y.s2), FUNCTION(x.s3, y.s3),   \
+                                 FUNCTION(x.s4, y.s4), FUNCTION(x.s5, y.s5),   \
+                                 FUNCTION(x.s6, y.s6), FUNCTION(x.s7, y.s7),   \
+                                 FUNCTION(x.s8, y.s8), FUNCTION(x.s9, y.s9),   \
+                                 FUNCTION(x.sa, y.sa), FUNCTION(x.sb, y.sb),   \
+                                 FUNCTION(x.sc, y.sc), FUNCTION(x.sd, y.sd),   \
+                                 FUNCTION(x.se, y.se),                         \
+                                 FUNCTION(x.sf, y.sf)} != (RET_TYPE)0);        \
+  }
+
+#define _CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(RET_TYPE, FUNCTION, ARG0_TYPE,   \
+                                              ARG1_TYPE)                       \
+  _CLC_DEFINE_RELATIONAL_BINARY_VEC2(RET_TYPE##2, FUNCTION, ARG0_TYPE##2,      \
+                                     ARG1_TYPE##2)                             \
+  _CLC_DEFINE_RELATIONAL_BINARY_VEC3(RET_TYPE##3, FUNCTION, ARG0_TYPE##3,      \
+                                     ARG1_TYPE##3)                             \
+  _CLC_DEFINE_RELATIONAL_BINARY_VEC4(RET_TYPE##4, FUNCTION, ARG0_TYPE##4,      \
+                                     ARG1_TYPE##4)                             \
+  _CLC_DEFINE_RELATIONAL_BINARY_VEC8(RET_TYPE##8, FUNCTION, ARG0_TYPE##8,      \
+                                     ARG1_TYPE##8)                             \
+  _CLC_DEFINE_RELATIONAL_BINARY_VEC16(RET_TYPE##16, FUNCTION, ARG0_TYPE##16,   \
+                                      ARG1_TYPE##16)
+
+#define _CLC_DEFINE_RELATIONAL_BINARY(RET_TYPE, FUNCTION, BUILTIN_FUNCTION,    \
+                                      ARG0_TYPE, ARG1_TYPE)                    \
+  _CLC_DEFINE_RELATIONAL_BINARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_FUNCTION,   \
+                                       ARG0_TYPE, ARG1_TYPE)                   \
+  _CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(RET_TYPE, FUNCTION, ARG0_TYPE,         \
+                                        ARG1_TYPE)
+
+#endif // __CLC_RELATIONAL_RELATIONAL_H__
diff --git a/libclc/generic/include/clc/relational/unary_decl.inc b/libclc/clc/include/clc/relational/unary_decl.inc
similarity index 100%
rename from libclc/generic/include/clc/relational/unary_decl.inc
rename to libclc/clc/include/clc/relational/unary_decl.inc
diff --git a/libclc/clc/lib/generic/SOURCES b/libclc/clc/lib/generic/SOURCES
index bcf715ff376078..d7ffaaf6dc3f42 100644
--- a/libclc/clc/lib/generic/SOURCES
+++ b/libclc/clc/lib/generic/SOURCES
@@ -1,6 +1,24 @@
 geometric/clc_dot.cl
 integer/clc_abs.cl
 integer/clc_abs_diff.cl
+relational/clc_all.cl
+relational/clc_any.cl
+relational/clc_bitselect.cl
+relational/clc_isequal.cl
+relational/clc_isfinite.cl
+relational/clc_isgreater.cl
+relational/clc_isgreaterequal.cl
+relational/clc_isinf.cl
+relational/clc_isless.cl
+relational/clc_islessequal.cl
+relational/clc_islessgreater.cl
+relational/clc_isnan.cl
+relational/clc_isnormal.cl
+relational/clc_isnotequal.cl
+relational/clc_isordered.cl
+relational/clc_isunordered.cl
+relational/clc_select.cl
+relational/clc_signbit.cl
 shared/clc_clamp.cl
 shared/clc_max.cl
 shared/clc_min.cl
diff --git a/libclc/clc/lib/generic/relational/clc_all.cl b/libclc/clc/lib/generic/relational/clc_all.cl
new file mode 100644
index 00000000000000..e371126d144f06
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_all.cl
@@ -0,0 +1,28 @@
+#include <clc/internal/clc.h>
+
+#define _CLC_ALL(v) (((v) >> ((sizeof(v) * 8) - 1)) & 0x1)
+#define _CLC_ALL2(v) (_CLC_ALL((v).s0) & _CLC_ALL((v).s1))
+#define _CLC_ALL3(v) (_CLC_ALL2((v)) & _CLC_ALL((v).s2))
+#define _CLC_ALL4(v) (_CLC_ALL3((v)) & _CLC_ALL((v).s3))
+#define _CLC_ALL8(v)                                                           \
+  (_CLC_ALL4((v)) & _CLC_ALL((v).s4) & _CLC_ALL((v).s5) & _CLC_ALL((v).s6) &   \
+   _CLC_ALL((v).s7))
+#define _CLC_ALL16(v)                                                          \
+  (_CLC_ALL8((v)) & _CLC_ALL((v).s8) & _CLC_ALL((v).s9) & _CLC_ALL((v).sA) &   \
+   _CLC_ALL((v).sB) & _CLC_ALL((v).sC) & _CLC_ALL((v).sD) & _CLC_ALL((v).sE) & \
+   _CLC_ALL((v).sf))
+
+#define ALL_ID(TYPE) _CLC_OVERLOAD _CLC_DEF int __clc_all(TYPE v)
+
+#define ALL_VECTORIZE(TYPE)                                                    \
+  ALL_ID(TYPE) { return _CLC_ALL(v); }                                         \
+  ALL_ID(TYPE##2) { return _CLC_ALL2(v); }                                     \
+  ALL_ID(TYPE##3) { return _CLC_ALL3(v); }                                     \
+  ALL_ID(TYPE##4) { return _CLC_ALL4(v); }                                     \
+  ALL_ID(TYPE##8) { return _CLC_ALL8(v); }                                     \
+  ALL_ID(TYPE##16) { return _CLC_ALL16(v); }
+
+ALL_VECTORIZE(char)
+ALL_VECTORIZE(short)
+ALL_VECTORIZE(int)
+ALL_VECTORIZE(long)
diff --git a/libclc/clc/lib/generic/relational/clc_any.cl b/libclc/clc/lib/generic/relational/clc_any.cl
new file mode 100644
index 00000000000000..e69f2113c94f55
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_any.cl
@@ -0,0 +1,28 @@
+#include <clc/internal/clc.h>
+
+#define _CLC_ANY(v) (((v) >> ((sizeof(v) * 8) - 1)) & 0x1)
+#define _CLC_ANY2(v) (_CLC_ANY((v).s0) | _CLC_ANY((v).s1))
+#define _CLC_ANY3(v) (_CLC_ANY2((v)) | _CLC_ANY((v).s2))
+#define _CLC_ANY4(v) (_CLC_ANY3((v)) | _CLC_ANY((v).s3))
+#define _CLC_ANY8(v)                                                           \
+  (_CLC_ANY4((v)) | _CLC_ANY((v).s4) | _CLC_ANY((v).s5) | _CLC_ANY((v).s6) |   \
+   _CLC_ANY((v).s7))
+#define _CLC_ANY16(v)                                                          \
+  (_CLC_ANY8((v)) | _CLC_ANY((v).s8) | _CLC_ANY((v).s9) | _CLC_ANY((v).sA) |   \
+   _CLC_ANY((v).sB) | _CLC_ANY((v).sC) | _CLC_ANY((v).sD) | _CLC_ANY((v).sE) | \
+   _CLC_ANY((v).sf))
+
+#define ANY_ID(TYPE) _CLC_OVERLOAD _CLC_DEF int __clc_any(TYPE v)
+
+#define ANY_VECTORIZE(TYPE)                                                    \
+  ANY_ID(TYPE) { return _CLC_ANY(v); }                                         \
+  ANY_ID(TYPE##2) { return _CLC_ANY2(v); }                                     \
+  ANY_ID(TYPE##3) { return _CLC_ANY3(v); }                                     \
+  ANY_ID(TYPE##4) { return _CLC_ANY4(v); }                                     \
+  ANY_ID(TYPE##8) { return _CLC_ANY8(v); }                                     \
+  ANY_ID(TYPE##16) { return _CLC_ANY16(v); }
+
+ANY_VECTORIZE(char)
+ANY_VECTORIZE(short)
+ANY_VECTORIZE(int)
+ANY_VECTORIZE(long)
diff --git a/libclc/clc/lib/generic/relational/clc_bitselect.cl b/libclc/clc/lib/generic/relational/clc_bitselect.cl
new file mode 100644
index 00000000000000..66b28af71b38d3
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_bitselect.cl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014,2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <clc/clcmacro.h>
+#include <clc/internal/clc.h>
+
+#define __CLC_BODY <clc_bitselect.inc>
+#include <clc/integer/gentype.inc>
+#undef __CLC_BODY
+
+#define FLOAT_BITSELECT(f_type, i_type, width)                                 \
+  _CLC_OVERLOAD _CLC_DEF f_type##width __clc_bitselect(                        \
+      f_type##width x, f_type##width y, f_type##width z) {                     \
+    return __clc_as_##f_type##width(__clc_bitselect(                           \
+        __clc_as_##i_type##width(x), __clc_as_##i_type##width(y),              \
+        __clc_as_##i_type##width(z)));                                         \
+  }
+
+FLOAT_BITSELECT(float, uint, )
+FLOAT_BITSELECT(float, uint, 2)
+FLOAT_BITSELECT(float, uint, 3)
+FLOAT_BITSELECT(float, uint, 4)
+FLOAT_BITSELECT(float, uint, 8)
+FLOAT_BITSELECT(float, uint, 16)
+
+#ifdef cl_khr_fp64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+FLOAT_BITSELECT(double, ulong, )
+FLOAT_BITSELECT(double, ulong, 2)
+FLOAT_BITSELECT(double, ulong, 3)
+FLOAT_BITSELECT(double, ulong, 4)
+FLOAT_BITSELECT(double, ulong, 8)
+FLOAT_BITSELECT(double, ulong, 16)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_bitselect.inc b/libclc/clc/lib/generic/relational/clc_bitselect.inc
new file mode 100644
index 00000000000000..dc906ef6bee0bd
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_bitselect.inc
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014,2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_bitselect(__CLC_GENTYPE x,
+                                                     __CLC_GENTYPE y,
+                                                     __CLC_GENTYPE z) {
+  return ((x) ^ ((z) & ((y) ^ (x))));
+}
diff --git a/libclc/clc/lib/generic/relational/clc_isequal.cl b/libclc/clc/lib/generic/relational/clc_isequal.cl
new file mode 100644
index 00000000000000..7664df7767cb3f
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isequal.cl
@@ -0,0 +1,44 @@
+#include <clc/internal/clc.h>
+
+#define _CLC_DEFINE_ISEQUAL(RET_TYPE, FUNCTION, ARG1_TYPE, ARG2_TYPE)          \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x, ARG2_TYPE y) {         \
+    return (x == y);                                                           \
+  }
+
+_CLC_DEFINE_ISEQUAL(int, __clc_isequal, float, float)
+_CLC_DEFINE_ISEQUAL(int2, __clc_isequal, float2, float2)
+_CLC_DEFINE_ISEQUAL(int3, __clc_isequal, float3, float3)
+_CLC_DEFINE_ISEQUAL(int4, __clc_isequal, float4, float4)
+_CLC_DEFINE_ISEQUAL(int8, __clc_isequal, float8, float8)
+_CLC_DEFINE_ISEQUAL(int16, __clc_isequal, float16, float16)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isequal(double) returns an int, but the vector
+// versions return long.
+_CLC_DEFINE_ISEQUAL(int, __clc_isequal, double, double)
+_CLC_DEFINE_ISEQUAL(long2, __clc_isequal, double2, double2)
+_CLC_DEFINE_ISEQUAL(long3, __clc_isequal, double3, double3)
+_CLC_DEFINE_ISEQUAL(long4, __clc_isequal, double4, double4)
+_CLC_DEFINE_ISEQUAL(long8, __clc_isequal, double8, double8)
+_CLC_DEFINE_ISEQUAL(long16, __clc_isequal, double16, double16)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isequal(half) returns an int, but the vector
+// versions return short.
+_CLC_DEFINE_ISEQUAL(int, __clc_isequal, half, half)
+_CLC_DEFINE_ISEQUAL(short2, __clc_isequal, half2, half2)
+_CLC_DEFINE_ISEQUAL(short3, __clc_isequal, half3, half3)
+_CLC_DEFINE_ISEQUAL(short4, __clc_isequal, half4, half4)
+_CLC_DEFINE_ISEQUAL(short8, __clc_isequal, half8, half8)
+_CLC_DEFINE_ISEQUAL(short16, __clc_isequal, half16, half16)
+
+#endif
+
+#undef _CLC_DEFINE_ISEQUAL
diff --git a/libclc/clc/lib/generic/relational/clc_isfinite.cl b/libclc/clc/lib/generic/relational/clc_isfinite.cl
new file mode 100644
index 00000000000000..c3def5dc5f0d51
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isfinite.cl
@@ -0,0 +1,31 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+_CLC_DEFINE_RELATIONAL_UNARY(int, __clc_isfinite, __builtin_isfinite, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isfinite(double) returns an int, but the vector
+// versions return long.
+_CLC_DEF _CLC_OVERLOAD int __clc_isfinite(double x) {
+  return __builtin_isfinite(x);
+}
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, __clc_isfinite, double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isfinite(half) returns an int, but the vector
+// versions return short.
+_CLC_DEF _CLC_OVERLOAD int __clc_isfinite(half x) {
+  return __builtin_isfinite(x);
+}
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, __clc_isfinite, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isgreater.cl b/libclc/clc/lib/generic/relational/clc_isgreater.cl
new file mode 100644
index 00000000000000..39fb6b07fb1859
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isgreater.cl
@@ -0,0 +1,39 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+// Note: It would be nice to use __builtin_isgreater with vector inputs, but it
+// seems to only take scalar values as input, which will produce incorrect
+// output for vector input types.
+
+_CLC_DEFINE_RELATIONAL_BINARY(int, __clc_isgreater, __builtin_isgreater, float,
+                              float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isgreater(double, double) returns an int, but the
+// vector versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isgreater(double x, double y) {
+  return __builtin_isgreater(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_isgreater, double, double)
+
+#endif
+
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isgreater(half, half) returns an int, but the
+// vector versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isgreater(half x, half y) {
+  return __builtin_isgreater(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_isgreater, half, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isgreaterequal.cl b/libclc/clc/lib/generic/relational/clc_isgreaterequal.cl
new file mode 100644
index 00000000000000..ccf7c881a5549b
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isgreaterequal.cl
@@ -0,0 +1,39 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+// Note: It would be nice to use __builtin_isgreaterequal with vector inputs,
+// but it seems to only take scalar values as input, which will produce
+// incorrect output for vector input types.
+
+_CLC_DEFINE_RELATIONAL_BINARY(int, __clc_isgreaterequal,
+                              __builtin_isgreaterequal, float, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isgreaterequal(double, double) returns an int,
+// but the vector versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isgreaterequal(double x, double y) {
+  return __builtin_isgreaterequal(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_isgreaterequal, double,
+                                      double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isgreaterequal(half, half) returns an int, but
+// the vector versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isgreaterequal(half x, half y) {
+  return __builtin_isgreaterequal(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_isgreaterequal, half, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isinf.cl b/libclc/clc/lib/generic/relational/clc_isinf.cl
new file mode 100644
index 00000000000000..afe29122f36a3e
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isinf.cl
@@ -0,0 +1,26 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+_CLC_DEFINE_RELATIONAL_UNARY(int, __clc_isinf, __builtin_isinf, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isinf(double) returns an int, but the vector
+// versions return long.
+_CLC_DEF _CLC_OVERLOAD int __clc_isinf(double x) { return __builtin_isinf(x); }
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, __clc_isinf, double)
+#endif
+
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isinf(half) returns an int, but the vector
+// versions return short.
+_CLC_DEF _CLC_OVERLOAD int __clc_isinf(half x) { return __builtin_isinf(x); }
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, __clc_isinf, half)
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isless.cl b/libclc/clc/lib/generic/relational/clc_isless.cl
new file mode 100644
index 00000000000000..1204a5057d8640
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isless.cl
@@ -0,0 +1,37 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+// Note: It would be nice to use __builtin_isless with vector inputs, but it
+// seems to only take scalar values as input, which will produce incorrect
+// output for vector input types.
+
+_CLC_DEFINE_RELATIONAL_BINARY(int, __clc_isless, __builtin_isless, float, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isless(double, double) returns an int, but the
+// vector versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isless(double x, double y) {
+  return __builtin_isless(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_isless, double, double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isless(half, half) returns an int, but the vector
+// versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isless(half x, half y) {
+  return __builtin_isless(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_isless, half, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_islessequal.cl b/libclc/clc/lib/generic/relational/clc_islessequal.cl
new file mode 100644
index 00000000000000..6fde763263e2b0
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_islessequal.cl
@@ -0,0 +1,39 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+// Note: It would be nice to use __builtin_islessequal with vector inputs, but
+// it seems to only take scalar values as input, which will produce incorrect
+// output for vector input types.
+
+_CLC_DEFINE_RELATIONAL_BINARY(int, __clc_islessequal, __builtin_islessequal,
+                              float, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_islessequal(double, double) returns an int, but
+// the vector versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_islessequal(double x, double y) {
+  return __builtin_islessequal(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_islessequal, double, double)
+
+#endif
+
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_islessequal(half, half) returns an int, but the
+// vector versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_islessequal(half x, half y) {
+  return __builtin_islessequal(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_islessequal, half, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_islessgreater.cl b/libclc/clc/lib/generic/relational/clc_islessgreater.cl
new file mode 100644
index 00000000000000..5106c9f460e2ca
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_islessgreater.cl
@@ -0,0 +1,38 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+// Note: It would be nice to use __builtin_islessgreater with vector inputs, but
+// it seems to only take scalar values as input, which will produce incorrect
+// output for vector input types.
+
+_CLC_DEFINE_RELATIONAL_BINARY(int, __clc_islessgreater, __builtin_islessgreater,
+                              float, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_islessgreater(double, double) returns an int, but
+// the vector versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_islessgreater(double x, double y) {
+  return __builtin_islessgreater(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_islessgreater, double, double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_islessgreater(half, half) returns an int, but the
+// vector versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_islessgreater(half x, half y) {
+  return __builtin_islessgreater(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_islessgreater, half, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isnan.cl b/libclc/clc/lib/generic/relational/clc_isnan.cl
new file mode 100644
index 00000000000000..fb30cd5419214b
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isnan.cl
@@ -0,0 +1,28 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+_CLC_DEFINE_RELATIONAL_UNARY(int, __clc_isnan, __builtin_isnan, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isnan(double) returns an int, but the vector
+// versions return long.
+_CLC_DEF _CLC_OVERLOAD int __clc_isnan(double x) { return __builtin_isnan(x); }
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, __clc_isnan, double)
+
+#endif
+
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isnan(half) returns an int, but the vector
+// versions return short.
+_CLC_DEF _CLC_OVERLOAD int __clc_isnan(half x) { return __builtin_isnan(x); }
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, __clc_isnan, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isnormal.cl b/libclc/clc/lib/generic/relational/clc_isnormal.cl
new file mode 100644
index 00000000000000..e0da8cc0756f42
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isnormal.cl
@@ -0,0 +1,31 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+_CLC_DEFINE_RELATIONAL_UNARY(int, __clc_isnormal, __builtin_isnormal, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isnormal(double) returns an int, but the vector
+// versions return long.
+_CLC_DEF _CLC_OVERLOAD int __clc_isnormal(double x) {
+  return __builtin_isnormal(x);
+}
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, __clc_isnormal, double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isnormal(half) returns an int, but the vector
+// versions return short.
+_CLC_DEF _CLC_OVERLOAD int __clc_isnormal(half x) {
+  return __builtin_isnormal(x);
+}
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, __clc_isnormal, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_isnotequal.cl b/libclc/clc/lib/generic/relational/clc_isnotequal.cl
new file mode 100644
index 00000000000000..9f90713b2da508
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isnotequal.cl
@@ -0,0 +1,33 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+#define _CLC_DEFINE_ISNOTEQUAL(RET_TYPE, FUNCTION, ARG1_TYPE, ARG2_TYPE)       \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x, ARG2_TYPE y) {         \
+    return (x != y);                                                           \
+  }
+
+_CLC_DEFINE_ISNOTEQUAL(int, __clc_isnotequal, float, float)
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(int, __clc_isnotequal, float, float)
+
+#ifdef cl_khr_fp64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isnotequal(double, double) returns an int, but
+// the vector versions return long.
+
+_CLC_DEFINE_ISNOTEQUAL(int, __clc_isnotequal, double, double)
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_isnotequal, double, double)
+
+#endif
+#ifdef cl_khr_fp16
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isnotequal(half, half) returns an int, but the
+// vector versions return short.
+
+_CLC_DEFINE_ISNOTEQUAL(int, __clc_isnotequal, half, half)
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_isnotequal, half, half)
+
+#endif
+
+#undef _CLC_DEFINE_ISNOTEQUAL
diff --git a/libclc/clc/lib/generic/relational/clc_isordered.cl b/libclc/clc/lib/generic/relational/clc_isordered.cl
new file mode 100644
index 00000000000000..6183d1ddf918f5
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isordered.cl
@@ -0,0 +1,34 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/clc_isequal.h>
+#include <clc/relational/relational.h>
+
+#define _CLC_DEFINE_ISORDERED(RET_TYPE, FUNCTION, ARG1_TYPE, ARG2_TYPE)        \
+  _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x, ARG2_TYPE y) {         \
+    return __clc_isequal(x, x) && __clc_isequal(y, y);                         \
+  }
+
+_CLC_DEFINE_ISORDERED(int, __clc_isordered, float, float)
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(int, __clc_isordered, float, float)
+
+#ifdef cl_khr_fp64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isordered(double, double) returns an int, but the
+// vector versions return long.
+
+_CLC_DEFINE_ISORDERED(int, __clc_isordered, double, double)
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_isordered, double, double)
+
+#endif
+#ifdef cl_khr_fp16
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isordered(half, half) returns an int, but the
+// vector versions return short.
+
+_CLC_DEFINE_ISORDERED(int, __clc_isordered, half, half)
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_isordered, half, half)
+
+#endif
+
+#undef _CLC_DEFINE_ISORDERED
diff --git a/libclc/clc/lib/generic/relational/clc_isunordered.cl b/libclc/clc/lib/generic/relational/clc_isunordered.cl
new file mode 100644
index 00000000000000..dbbec031a65e58
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_isunordered.cl
@@ -0,0 +1,38 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+// Note: It would be nice to use __builtin_isunordered with vector inputs, but
+// it seems to only take scalar values as input, which will produce incorrect
+// output for vector input types.
+
+_CLC_DEFINE_RELATIONAL_BINARY(int, __clc_isunordered, __builtin_isunordered,
+                              float, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_isunordered(double, double) returns an int, but
+// the vector versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isunordered(double x, double y) {
+  return __builtin_isunordered(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, __clc_isunordered, double, double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_isunordered(half, half) returns an int, but the
+// vector versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_isunordered(half x, half y) {
+  return __builtin_isunordered(x, y);
+}
+
+_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, __clc_isunordered, half, half)
+
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_select.cl b/libclc/clc/lib/generic/relational/clc_select.cl
new file mode 100644
index 00000000000000..bb016ed2993e7e
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_select.cl
@@ -0,0 +1,7 @@
+#include <clc/internal/clc.h>
+#include <clc/utils.h>
+
+#define __CLC_BODY <clc_select.inc>
+#include <clc/math/gentype.inc>
+#define __CLC_BODY <clc_select.inc>
+#include <clc/integer/gentype.inc>
diff --git a/libclc/clc/lib/generic/relational/clc_select.inc b/libclc/clc/lib/generic/relational/clc_select.inc
new file mode 100644
index 00000000000000..47db80672a02c2
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_select.inc
@@ -0,0 +1,35 @@
+#ifdef __CLC_SCALAR
+#define __CLC_VECSIZE
+#endif
+
+#if __CLC_FPSIZE == 64
+#define __CLC_S_GENTYPE __CLC_XCONCAT(long, __CLC_VECSIZE)
+#define __CLC_U_GENTYPE __CLC_XCONCAT(ulong, __CLC_VECSIZE)
+#elif __CLC_FPSIZE == 32
+#define __CLC_S_GENTYPE __CLC_XCONCAT(int, __CLC_VECSIZE)
+#define __CLC_U_GENTYPE __CLC_XCONCAT(uint, __CLC_VECSIZE)
+#elif __CLC_FPSIZE == 16
+#define __CLC_S_GENTYPE __CLC_XCONCAT(short, __CLC_VECSIZE)
+#define __CLC_U_GENTYPE __CLC_XCONCAT(ushort, __CLC_VECSIZE)
+#endif
+
+_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_select(__CLC_GENTYPE x,
+                                                  __CLC_GENTYPE y,
+                                                  __CLC_S_GENTYPE z) {
+  return z ? y : x;
+}
+
+_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_select(__CLC_GENTYPE x,
+                                                  __CLC_GENTYPE y,
+                                                  __CLC_U_GENTYPE z) {
+  return z ? y : x;
+}
+
+#ifdef __CLC_FPSIZE
+#undef __CLC_S_GENTYPE
+#undef __CLC_U_GENTYPE
+#endif
+
+#ifdef __CLC_SCALAR
+#undef __CLC_VECSIZE
+#endif
diff --git a/libclc/clc/lib/generic/relational/clc_signbit.cl b/libclc/clc/lib/generic/relational/clc_signbit.cl
new file mode 100644
index 00000000000000..b1b294379e5a82
--- /dev/null
+++ b/libclc/clc/lib/generic/relational/clc_signbit.cl
@@ -0,0 +1,33 @@
+#include <clc/internal/clc.h>
+#include <clc/relational/relational.h>
+
+_CLC_DEFINE_RELATIONAL_UNARY(int, __clc_signbit, __builtin_signbitf, float)
+
+#ifdef cl_khr_fp64
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// The scalar version of __clc_signbit(double) returns an int, but the vector
+// versions return long.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_signbit(double x) {
+  return __builtin_signbit(x);
+}
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, __clc_signbit, double)
+
+#endif
+#ifdef cl_khr_fp16
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// The scalar version of __clc_signbit(half) returns an int, but the vector
+// versions return short.
+
+_CLC_DEF _CLC_OVERLOAD int __clc_signbit(half x) {
+  return __builtin_signbit(x);
+}
+
+_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, __clc_signbit, half)
+
+#endif
diff --git a/libclc/generic/include/clc/relational/any.h b/libclc/generic/include/clc/relational/any.h
index 4687ed263793e5..3989796262dd36 100644
--- a/libclc/generic/include/clc/relational/any.h
+++ b/libclc/generic/include/clc/relational/any.h
@@ -14,3 +14,6 @@ _CLC_VECTOR_ANY_DECL(char)
 _CLC_VECTOR_ANY_DECL(short)
 _CLC_VECTOR_ANY_DECL(int)
 _CLC_VECTOR_ANY_DECL(long)
+
+#undef _CLC_ANY_DECL
+#undef _CLC_VECTOR_ANY_DECL
diff --git a/libclc/generic/include/clc/relational/binary_decl.inc b/libclc/generic/include/clc/relational/binary_decl.inc
deleted file mode 100644
index c9e4aee839a17c..00000000000000
--- a/libclc/generic/include/clc/relational/binary_decl.inc
+++ /dev/null
@@ -1 +0,0 @@
-_CLC_OVERLOAD _CLC_DECL __CLC_INTN __CLC_FUNCTION(__CLC_FLOATN a, __CLC_FLOATN b);
diff --git a/libclc/generic/lib/math/clc_exp10.cl b/libclc/generic/lib/math/clc_exp10.cl
index 01e6fd652004a9..6ea8743e39c5f7 100644
--- a/libclc/generic/lib/math/clc_exp10.cl
+++ b/libclc/generic/lib/math/clc_exp10.cl
@@ -22,6 +22,7 @@
 
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
+#include <clc/relational/clc_isnan.h>
 
 #include "config.h"
 #include "math.h"
@@ -62,7 +63,7 @@ _CLC_DEF _CLC_OVERLOAD float __clc_exp10(float x)
     const float R_LOG10_2_BY_64_TL = 0x1.04d426p-18f; // log2/(64 * log10) tail : 0.00000388665057
     const float R_LN10 = 0x1.26bb1cp+1f;
 
-    int return_nan = isnan(x);
+    int return_nan = __clc_isnan(x);
     int return_inf = x > X_MAX;
     int return_zero = x < X_MIN;
 
@@ -138,7 +139,7 @@ _CLC_DEF _CLC_OVERLOAD double __clc_exp10(double x)
     z2 = ldexp(z2, m);
     z2 = small_value ? z3: z2;
 
-    z2 = isnan(x) ? x : z2;
+    z2 = __clc_isnan(x) ? x : z2;
 
     z2 = x > X_MAX ? as_double(PINFBITPATT_DP64) : z2;
     z2 = x < X_MIN ? 0.0 : z2;
diff --git a/libclc/generic/lib/math/clc_fma.cl b/libclc/generic/lib/math/clc_fma.cl
index 4013360bcd0612..15de4c8032a932 100644
--- a/libclc/generic/lib/math/clc_fma.cl
+++ b/libclc/generic/lib/math/clc_fma.cl
@@ -23,6 +23,8 @@
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
 #include <clc/integer/clc_abs.h>
+#include <clc/relational/clc_isinf.h>
+#include <clc/relational/clc_isnan.h>
 #include <clc/shared/clc_max.h>
 
 #include "config.h"
@@ -36,11 +38,12 @@ struct fp {
 
 _CLC_DEF _CLC_OVERLOAD float __clc_sw_fma(float a, float b, float c) {
   /* special cases */
-  if (isnan(a) || isnan(b) || isnan(c) || isinf(a) || isinf(b))
+  if (__clc_isnan(a) || __clc_isnan(b) || __clc_isnan(c) || __clc_isinf(a) ||
+      __clc_isinf(b))
     return mad(a, b, c);
 
   /* If only c is inf, and both a,b are regular numbers, the result is c*/
-  if (isinf(c))
+  if (__clc_isinf(c))
     return c;
 
   a = __clc_flush_denormal_if_not_supported(a);
diff --git a/libclc/generic/lib/math/clc_hypot.cl b/libclc/generic/lib/math/clc_hypot.cl
index abc000770ae3f3..a17e661603fa67 100644
--- a/libclc/generic/lib/math/clc_hypot.cl
+++ b/libclc/generic/lib/math/clc_hypot.cl
@@ -23,6 +23,7 @@
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
 #include <clc/integer/clc_abs.h>
+#include <clc/relational/clc_isnan.h>
 #include <clc/shared/clc_clamp.h>
 #include <math/clc_hypot.h>
 
@@ -88,7 +89,7 @@ _CLC_DEF _CLC_OVERLOAD double __clc_hypot(double x, double y) {
 
   // Check for NaN
   // c = x != x | y != y;
-  c = isnan(x) | isnan(y);
+  c = __clc_isnan(x) | __clc_isnan(y);
   r = c ? as_double(QNANBITPATT_DP64) : r;
 
   // If either is Inf, we must return Inf
diff --git a/libclc/generic/lib/math/clc_ldexp.cl b/libclc/generic/lib/math/clc_ldexp.cl
index ccb37631706b80..6d3721588df813 100644
--- a/libclc/generic/lib/math/clc_ldexp.cl
+++ b/libclc/generic/lib/math/clc_ldexp.cl
@@ -24,6 +24,8 @@
 #include "math.h"
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
+#include <clc/relational/clc_isinf.h>
+#include <clc/relational/clc_isnan.h>
 #include <clc/shared/clc_clamp.h>
 
 _CLC_DEF _CLC_OVERLOAD float __clc_ldexp(float x, int n) {
@@ -90,7 +92,7 @@ _CLC_DEF _CLC_OVERLOAD float __clc_ldexp(float x, int n) {
   val_ui = dexp == 0 ? dval_ui : val_ui;
   val_f = as_float(val_ui);
 
-  val_f = isnan(x) | isinf(x) | val_x == 0 ? x : val_f;
+  val_f = __clc_isnan(x) | __clc_isinf(x) | val_x == 0 ? x : val_f;
   return val_f;
 }
 
@@ -123,7 +125,7 @@ _CLC_DEF _CLC_OVERLOAD double __clc_ldexp(double x, int n) {
   mr = v == 0x7ff ? as_double(s | PINFBITPATT_DP64) : mr;
   mr = v < -53 ? as_double(s) : mr;
 
-  mr = ((n == 0) | isinf(x) | (x == 0)) ? x : mr;
+  mr = ((n == 0) | __clc_isinf(x) | (x == 0)) ? x : mr;
   return mr;
 }
 
diff --git a/libclc/generic/lib/math/clc_nextafter.cl b/libclc/generic/lib/math/clc_nextafter.cl
index ccb7624d20c56f..623eb11c18c3b1 100644
--- a/libclc/generic/lib/math/clc_nextafter.cl
+++ b/libclc/generic/lib/math/clc_nextafter.cl
@@ -1,41 +1,44 @@
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
+#include <clc/relational/clc_isnan.h>
 
 // This file provides OpenCL C implementations of nextafter for
 // targets that don't support the clang builtin.
 
 #define AS_TYPE(x) as_##x
 
-#define NEXTAFTER(FLOAT_TYPE, UINT_TYPE, INT_TYPE)                      \
-_CLC_OVERLOAD _CLC_DEF FLOAT_TYPE __clc_nextafter(FLOAT_TYPE x, FLOAT_TYPE y) { \
-  const UINT_TYPE sign_bit                                        \
-   = (UINT_TYPE)1 << (sizeof(INT_TYPE) * 8 - 1);                  \
-  const UINT_TYPE sign_bit_mask = sign_bit - 1;                   \
-  INT_TYPE ix = AS_TYPE(INT_TYPE)(x);                             \
-  INT_TYPE ax = ix & sign_bit_mask;                               \
-  INT_TYPE mx = sign_bit - ix;                                    \
-  mx = ix < 0 ? mx : ix;                                          \
-  INT_TYPE iy = AS_TYPE(INT_TYPE)(y);                             \
-  INT_TYPE ay = iy & sign_bit_mask;                               \
-  INT_TYPE my = sign_bit - iy;                                    \
-  my = iy < 0 ? my : iy;                                          \
-  INT_TYPE t = mx + (mx < my ? 1 : -1);                           \
-  INT_TYPE r = sign_bit - t;                                      \
-  r = t < 0 ? r : t;                                              \
-  r = isnan(x) ? ix : r;                                          \
-  r = isnan(y) ? iy : r;                                          \
-  r = ((ax | ay) == 0 | ix == iy) ? iy : r;                       \
-  return AS_TYPE(FLOAT_TYPE)(r);                                  \
-}
+#define NEXTAFTER(FLOAT_TYPE, UINT_TYPE, INT_TYPE)                             \
+  _CLC_OVERLOAD _CLC_DEF FLOAT_TYPE __clc_nextafter(FLOAT_TYPE x,              \
+                                                    FLOAT_TYPE y) {            \
+    const UINT_TYPE sign_bit = (UINT_TYPE)1 << (sizeof(INT_TYPE) * 8 - 1);     \
+    const UINT_TYPE sign_bit_mask = sign_bit - 1;                              \
+    INT_TYPE ix = AS_TYPE(INT_TYPE)(x);                                        \
+    INT_TYPE ax = ix & sign_bit_mask;                                          \
+    INT_TYPE mx = sign_bit - ix;                                               \
+    mx = ix < 0 ? mx : ix;                                                     \
+    INT_TYPE iy = AS_TYPE(INT_TYPE)(y);                                        \
+    INT_TYPE ay = iy & sign_bit_mask;                                          \
+    INT_TYPE my = sign_bit - iy;                                               \
+    my = iy < 0 ? my : iy;                                                     \
+    INT_TYPE t = mx + (mx < my ? 1 : -1);                                      \
+    INT_TYPE r = sign_bit - t;                                                 \
+    r = t < 0 ? r : t;                                                         \
+    r = __clc_isnan(x) ? ix : r;                                               \
+    r = __clc_isnan(y) ? iy : r;                                               \
+    r = ((ax | ay) == 0 | ix == iy) ? iy : r;                                  \
+    return AS_TYPE(FLOAT_TYPE)(r);                                             \
+  }
 
 NEXTAFTER(float, uint, int)
-_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_nextafter, float, float)
+_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_nextafter, float,
+                      float)
 
 #ifdef cl_khr_fp64
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
 
 NEXTAFTER(double, ulong, long)
-_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_nextafter, double, double)
+_CLC_BINARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_nextafter, double,
+                      double)
 #endif
 
 #ifdef cl_khr_fp16
diff --git a/libclc/generic/lib/math/clc_tan.cl b/libclc/generic/lib/math/clc_tan.cl
index d14ab71740501a..4daaee59b10d2d 100644
--- a/libclc/generic/lib/math/clc_tan.cl
+++ b/libclc/generic/lib/math/clc_tan.cl
@@ -22,6 +22,8 @@
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
 #include <clc/math/clc_fabs.h>
+#include <clc/relational/clc_isinf.h>
+#include <clc/relational/clc_isnan.h>
 
 #include "math.h"
 #include "sincos_helpers.h"
@@ -64,7 +66,8 @@ _CLC_DEF _CLC_OVERLOAD double __clc_tan(double x) {
   int2 t = as_int2(regn & 1 ? tt.y : tt.x);
   t.hi ^= (x < 0.0) << 31;
 
-  return isnan(x) || isinf(x) ? as_double(QNANBITPATT_DP64) : as_double(t);
+  return __clc_isnan(x) || __clc_isinf(x) ? as_double(QNANBITPATT_DP64)
+                                          : as_double(t);
 }
 _CLC_UNARY_VECTORIZE(_CLC_DEF _CLC_OVERLOAD, double, __clc_tan, double);
 
diff --git a/libclc/generic/lib/relational/all.cl b/libclc/generic/lib/relational/all.cl
index 607d7a9c68c488..e4af0fc514f691 100644
--- a/libclc/generic/lib/relational/all.cl
+++ b/libclc/generic/lib/relational/all.cl
@@ -1,27 +1,15 @@
 #include <clc/clc.h>
+#include <clc/relational/clc_all.h>
 
-#define _CLC_ALL(v) (((v) >> ((sizeof(v) * 8) - 1)) & 0x1)
-#define _CLC_ALL2(v) (_CLC_ALL((v).s0) & _CLC_ALL((v).s1))
-#define _CLC_ALL3(v) (_CLC_ALL2((v)) & _CLC_ALL((v).s2))
-#define _CLC_ALL4(v) (_CLC_ALL3((v)) & _CLC_ALL((v).s3))
-#define _CLC_ALL8(v) (_CLC_ALL4((v)) & _CLC_ALL((v).s4) & _CLC_ALL((v).s5) \
-                                     & _CLC_ALL((v).s6) & _CLC_ALL((v).s7))
-#define _CLC_ALL16(v) (_CLC_ALL8((v)) & _CLC_ALL((v).s8) & _CLC_ALL((v).s9) \
-                                      & _CLC_ALL((v).sA) & _CLC_ALL((v).sB) \
-                                      & _CLC_ALL((v).sC) & _CLC_ALL((v).sD) \
-                                      & _CLC_ALL((v).sE) & _CLC_ALL((v).sf))
+#define ALL_ID(TYPE) _CLC_OVERLOAD _CLC_DEF int all(TYPE v)
 
-
-#define ALL_ID(TYPE) \
-  _CLC_OVERLOAD _CLC_DEF int all(TYPE v)
-
-#define ALL_VECTORIZE(TYPE) \
-  ALL_ID(TYPE) { return _CLC_ALL(v); } \
-  ALL_ID(TYPE##2) { return _CLC_ALL2(v); } \
-  ALL_ID(TYPE##3) { return _CLC_ALL3(v); } \
-  ALL_ID(TYPE##4) { return _CLC_ALL4(v); } \
-  ALL_ID(TYPE##8) { return _CLC_ALL8(v); } \
-  ALL_ID(TYPE##16) { return _CLC_ALL16(v); }
+#define ALL_VECTORIZE(TYPE)                                                    \
+  ALL_ID(TYPE) { return __clc_all(v); }                                        \
+  ALL_ID(TYPE##2) { return __clc_all(v); }                                     \
+  ALL_ID(TYPE##3) { return __clc_all(v); }                                     \
+  ALL_ID(TYPE##4) { return __clc_all(v); }                                     \
+  ALL_ID(TYPE##8) { return __clc_all(v); }                                     \
+  ALL_ID(TYPE##16) { return __clc_all(v); }
 
 ALL_VECTORIZE(char)
 ALL_VECTORIZE(short)
diff --git a/libclc/generic/lib/relational/any.cl b/libclc/generic/lib/relational/any.cl
index 4d372102021b96..3d975bd6d9df9b 100644
--- a/libclc/generic/lib/relational/any.cl
+++ b/libclc/generic/lib/relational/any.cl
@@ -1,30 +1,17 @@
 #include <clc/clc.h>
+#include <clc/relational/clc_any.h>
 
-#define _CLC_ANY(v) (((v) >> ((sizeof(v) * 8) - 1)) & 0x1)
-#define _CLC_ANY2(v) (_CLC_ANY((v).s0) | _CLC_ANY((v).s1))
-#define _CLC_ANY3(v) (_CLC_ANY2((v)) | _CLC_ANY((v).s2))
-#define _CLC_ANY4(v) (_CLC_ANY3((v)) | _CLC_ANY((v).s3))
-#define _CLC_ANY8(v) (_CLC_ANY4((v)) | _CLC_ANY((v).s4) | _CLC_ANY((v).s5) \
-                                     | _CLC_ANY((v).s6) | _CLC_ANY((v).s7))
-#define _CLC_ANY16(v) (_CLC_ANY8((v)) | _CLC_ANY((v).s8) | _CLC_ANY((v).s9) \
-                                      | _CLC_ANY((v).sA) | _CLC_ANY((v).sB) \
-                                      | _CLC_ANY((v).sC) | _CLC_ANY((v).sD) \
-                                      | _CLC_ANY((v).sE) | _CLC_ANY((v).sf))
+#define ANY_ID(TYPE) _CLC_OVERLOAD _CLC_DEF int any(TYPE v)
 
-
-#define ANY_ID(TYPE) \
-  _CLC_OVERLOAD _CLC_DEF int any(TYPE v)
-
-#define ANY_VECTORIZE(TYPE) \
-  ANY_ID(TYPE) { return _CLC_ANY(v); } \
-  ANY_ID(TYPE##2) { return _CLC_ANY2(v); } \
-  ANY_ID(TYPE##3) { return _CLC_ANY3(v); } \
-  ANY_ID(TYPE##4) { return _CLC_ANY4(v); } \
-  ANY_ID(TYPE##8) { return _CLC_ANY8(v); } \
-  ANY_ID(TYPE##16) { return _CLC_ANY16(v); }
+#define ANY_VECTORIZE(TYPE)                                                    \
+  ANY_ID(TYPE) { return __clc_any(v); }                                        \
+  ANY_ID(TYPE##2) { return __clc_any(v); }                                     \
+  ANY_ID(TYPE##3) { return __clc_any(v); }                                     \
+  ANY_ID(TYPE##4) { return __clc_any(v); }                                     \
+  ANY_ID(TYPE##8) { return __clc_any(v); }                                     \
+  ANY_ID(TYPE##16) { return __clc_any(v); }
 
 ANY_VECTORIZE(char)
 ANY_VECTORIZE(short)
 ANY_VECTORIZE(int)
 ANY_VECTORIZE(long)
-
diff --git a/libclc/generic/lib/relational/binary_def.inc b/libclc/generic/lib/relational/binary_def.inc
new file mode 100644
index 00000000000000..3ed68be142d005
--- /dev/null
+++ b/libclc/generic/lib/relational/binary_def.inc
@@ -0,0 +1,7 @@
+#include <clc/utils.h>
+
+#define __CLC_FUNCTION(x) __CLC_CONCAT(__clc_, x)
+
+_CLC_OVERLOAD _CLC_DECL __CLC_INTN FUNCTION(__CLC_FLOATN a, __CLC_FLOATN b) {
+  return __CLC_FUNCTION(FUNCTION)(a, b);
+}
diff --git a/libclc/generic/lib/relational/bitselect.cl b/libclc/generic/lib/relational/bitselect.cl
index d2a7a920606782..a470447f1fb91a 100644
--- a/libclc/generic/lib/relational/bitselect.cl
+++ b/libclc/generic/lib/relational/bitselect.cl
@@ -22,15 +22,17 @@
 
 #include <clc/clc.h>
 #include <clc/clcmacro.h>
+#include <clc/relational/clc_bitselect.h>
 
 #define __CLC_BODY <bitselect.inc>
 #include <clc/integer/gentype.inc>
 #undef __CLC_BODY
 
-#define FLOAT_BITSELECT(f_type, i_type, width) \
-  _CLC_OVERLOAD _CLC_DEF f_type##width bitselect(f_type##width x, f_type##width y, f_type##width z) { \
-  return as_##f_type##width(bitselect(as_##i_type##width(x), as_##i_type##width(y), as_##i_type##width(z))); \
-}
+#define FLOAT_BITSELECT(f_type, i_type, width)                                 \
+  _CLC_OVERLOAD _CLC_DEF f_type##width bitselect(                              \
+      f_type##width x, f_type##width y, f_type##width z) {                     \
+    return __clc_bitselect(x, y, z);                                           \
+  }
 
 FLOAT_BITSELECT(float, uint, )
 FLOAT_BITSELECT(float, uint, 2)
diff --git a/libclc/generic/lib/relational/isequal.cl b/libclc/generic/lib/relational/isequal.cl
index 3f14f945bfd337..4ed545f4563eb3 100644
--- a/libclc/generic/lib/relational/isequal.cl
+++ b/libclc/generic/lib/relational/isequal.cl
@@ -1,44 +1,7 @@
 #include <clc/clc.h>
+#include <clc/relational/clc_isequal.h>
 
-#define _CLC_DEFINE_ISEQUAL(RET_TYPE, FUNCTION, ARG1_TYPE, ARG2_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x, ARG2_TYPE y) { \
-  return (x == y); \
-} \
+#define FUNCTION isequal
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_ISEQUAL(int, isequal, float, float)
-_CLC_DEFINE_ISEQUAL(int2, isequal, float2, float2)
-_CLC_DEFINE_ISEQUAL(int3, isequal, float3, float3)
-_CLC_DEFINE_ISEQUAL(int4, isequal, float4, float4)
-_CLC_DEFINE_ISEQUAL(int8, isequal, float8, float8)
-_CLC_DEFINE_ISEQUAL(int16, isequal, float16, float16)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isequal(double) returns an int, but the vector versions
-// return long.
-_CLC_DEFINE_ISEQUAL(int, isequal, double, double)
-_CLC_DEFINE_ISEQUAL(long2, isequal, double2, double2)
-_CLC_DEFINE_ISEQUAL(long3, isequal, double3, double3)
-_CLC_DEFINE_ISEQUAL(long4, isequal, double4, double4)
-_CLC_DEFINE_ISEQUAL(long8, isequal, double8, double8)
-_CLC_DEFINE_ISEQUAL(long16, isequal, double16, double16)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isequal(half) returns an int, but the vector versions
-// return short.
-_CLC_DEFINE_ISEQUAL(int, isequal, half, half)
-_CLC_DEFINE_ISEQUAL(short2, isequal, half2, half2)
-_CLC_DEFINE_ISEQUAL(short3, isequal, half3, half3)
-_CLC_DEFINE_ISEQUAL(short4, isequal, half4, half4)
-_CLC_DEFINE_ISEQUAL(short8, isequal, half8, half8)
-_CLC_DEFINE_ISEQUAL(short16, isequal, half16, half16)
-
-#endif
-
-#undef _CLC_DEFINE_ISEQUAL
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isfinite.cl b/libclc/generic/lib/relational/isfinite.cl
index 15b92fa41296e6..d73bf6e5309947 100644
--- a/libclc/generic/lib/relational/isfinite.cl
+++ b/libclc/generic/lib/relational/isfinite.cl
@@ -1,31 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isfinite.h>
 
-_CLC_DEFINE_RELATIONAL_UNARY(int, isfinite, __builtin_isfinite, float)
+#define FUNCTION isfinite
+#define __CLC_BODY "unary_def.inc"
 
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isfinite(double) returns an int, but the vector versions
-// return long.
-_CLC_DEF _CLC_OVERLOAD int isfinite(double x) {
-  return __builtin_isfinite(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, isfinite, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isfinite(half) returns an int, but the vector versions
-// return short.
-_CLC_DEF _CLC_OVERLOAD int isfinite(half x) {
-  return __builtin_isfinite(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, isfinite, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isgreater.cl b/libclc/generic/lib/relational/isgreater.cl
index 167d6f213552ba..c4f7b43588d151 100644
--- a/libclc/generic/lib/relational/isgreater.cl
+++ b/libclc/generic/lib/relational/isgreater.cl
@@ -1,37 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isgreater.h>
 
-//Note: It would be nice to use __builtin_isgreater with vector inputs, but it seems to only take scalar values as
-//      input, which will produce incorrect output for vector input types.
+#define FUNCTION isgreater
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_RELATIONAL_BINARY(int, isgreater, __builtin_isgreater, float, float)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isgreater(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int isgreater(double x, double y){
-	return __builtin_isgreater(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, isgreater, double, double)
-
-#endif
-
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isgreater(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int isgreater(half x, half y){
-	return __builtin_isgreater(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, isgreater, half, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isgreaterequal.cl b/libclc/generic/lib/relational/isgreaterequal.cl
index 128a1d0de4eccf..28473393a761f9 100644
--- a/libclc/generic/lib/relational/isgreaterequal.cl
+++ b/libclc/generic/lib/relational/isgreaterequal.cl
@@ -1,36 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isgreaterequal.h>
 
-//Note: It would be nice to use __builtin_isgreaterequal with vector inputs, but it seems to only take scalar values as
-//      input, which will produce incorrect output for vector input types.
+#define FUNCTION isgreaterequal
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_RELATIONAL_BINARY(int, isgreaterequal, __builtin_isgreaterequal, float, float)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isgreaterequal(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int isgreaterequal(double x, double y){
-	return __builtin_isgreaterequal(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, isgreaterequal, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isgreaterequal(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int isgreaterequal(half x, half y){
-	return __builtin_isgreaterequal(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, isgreaterequal, half, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isinf.cl b/libclc/generic/lib/relational/isinf.cl
index 96aae4aa700e41..f6816659c6e84c 100644
--- a/libclc/generic/lib/relational/isinf.cl
+++ b/libclc/generic/lib/relational/isinf.cl
@@ -1,30 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isinf.h>
 
-_CLC_DEFINE_RELATIONAL_UNARY(int, isinf, __builtin_isinf, float)
+#define FUNCTION isinf
+#define __CLC_BODY "unary_def.inc"
 
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isinf(double) returns an int, but the vector versions
-// return long.
-_CLC_DEF _CLC_OVERLOAD int isinf(double x) {
-  return __builtin_isinf(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, isinf, double)
-#endif
-
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isinf(half) returns an int, but the vector versions
-// return short.
-_CLC_DEF _CLC_OVERLOAD int isinf(half x) {
-  return __builtin_isinf(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, isinf, half)
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isless.cl b/libclc/generic/lib/relational/isless.cl
index 1dbf7676060b37..ea79ce4f3fe19c 100644
--- a/libclc/generic/lib/relational/isless.cl
+++ b/libclc/generic/lib/relational/isless.cl
@@ -1,36 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isless.h>
 
-//Note: It would be nice to use __builtin_isless with vector inputs, but it seems to only take scalar values as
-//      input, which will produce incorrect output for vector input types.
+#define FUNCTION isless
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_RELATIONAL_BINARY(int, isless, __builtin_isless, float, float)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isless(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int isless(double x, double y){
-	return __builtin_isless(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, isless, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isless(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int isless(half x, half y){
-	return __builtin_isless(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, isless, half, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/islessequal.cl b/libclc/generic/lib/relational/islessequal.cl
index db64bea5dcd354..9b09577074aa0c 100644
--- a/libclc/generic/lib/relational/islessequal.cl
+++ b/libclc/generic/lib/relational/islessequal.cl
@@ -1,36 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_islessequal.h>
 
-//Note: It would be nice to use __builtin_islessequal with vector inputs, but it seems to only take scalar values as
-//      input, which will produce incorrect output for vector input types.
+#define FUNCTION islessequal
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_RELATIONAL_BINARY(int, islessequal, __builtin_islessequal, float, float)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of islessequal(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int islessequal(double x, double y){
-	return __builtin_islessequal(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, islessequal, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of islessequal(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int islessequal(half x, half y){
-	return __builtin_islessequal(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, islessequal, half, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/islessgreater.cl b/libclc/generic/lib/relational/islessgreater.cl
index 9e9b11ec9b6b1e..08f7c955182974 100644
--- a/libclc/generic/lib/relational/islessgreater.cl
+++ b/libclc/generic/lib/relational/islessgreater.cl
@@ -1,36 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_islessgreater.h>
 
-//Note: It would be nice to use __builtin_islessgreater with vector inputs, but it seems to only take scalar values as
-//      input, which will produce incorrect output for vector input types.
+#define FUNCTION islessgreater
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_RELATIONAL_BINARY(int, islessgreater, __builtin_islessgreater, float, float)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of islessgreater(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int islessgreater(double x, double y){
-	return __builtin_islessgreater(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, islessgreater, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of islessgreater(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int islessgreater(half x, half y){
-	return __builtin_islessgreater(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, islessgreater, half, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isnan.cl b/libclc/generic/lib/relational/isnan.cl
index 3d3104783b7e54..c61343722f9c86 100644
--- a/libclc/generic/lib/relational/isnan.cl
+++ b/libclc/generic/lib/relational/isnan.cl
@@ -1,32 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isnan.h>
 
-_CLC_DEFINE_RELATIONAL_UNARY(int, isnan, __builtin_isnan, float)
+#define FUNCTION isnan
+#define __CLC_BODY "unary_def.inc"
 
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isnan(double) returns an int, but the vector versions
-// return long.
-_CLC_DEF _CLC_OVERLOAD int isnan(double x) {
-  return __builtin_isnan(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, isnan, double)
-
-#endif
-
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isnan(half) returns an int, but the vector versions
-// return short.
-_CLC_DEF _CLC_OVERLOAD int isnan(half x) {
-  return __builtin_isnan(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, isnan, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isnormal.cl b/libclc/generic/lib/relational/isnormal.cl
index a3dbf661c61835..de2bd6ad20e925 100644
--- a/libclc/generic/lib/relational/isnormal.cl
+++ b/libclc/generic/lib/relational/isnormal.cl
@@ -1,31 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isnormal.h>
 
-_CLC_DEFINE_RELATIONAL_UNARY(int, isnormal, __builtin_isnormal, float)
+#define FUNCTION isnormal
+#define __CLC_BODY "unary_def.inc"
 
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isnormal(double) returns an int, but the vector versions
-// return long.
-_CLC_DEF _CLC_OVERLOAD int isnormal(double x) {
-  return __builtin_isnormal(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, isnormal, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isnormal(half) returns an int, but the vector versions
-// return short.
-_CLC_DEF _CLC_OVERLOAD int isnormal(half x) {
-  return __builtin_isnormal(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, isnormal, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isnotequal.cl b/libclc/generic/lib/relational/isnotequal.cl
index afd293dda01dbe..c04752b0d15b4d 100644
--- a/libclc/generic/lib/relational/isnotequal.cl
+++ b/libclc/generic/lib/relational/isnotequal.cl
@@ -1,33 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isnotequal.h>
 
-#define _CLC_DEFINE_ISNOTEQUAL(RET_TYPE, FUNCTION, ARG1_TYPE, ARG2_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x, ARG2_TYPE y) { \
-  return (x != y); \
-} \
+#define FUNCTION isnotequal
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_ISNOTEQUAL(int, isnotequal, float, float)
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(int, isnotequal, float, float)
-
-#ifdef cl_khr_fp64
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isnotequal(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEFINE_ISNOTEQUAL(int, isnotequal, double, double)
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, isnotequal, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isnotequal(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEFINE_ISNOTEQUAL(int, isnotequal, half, half)
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, isnotequal, half, half)
-
-#endif
-
-#undef _CLC_DEFINE_ISNOTEQUAL
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isordered.cl b/libclc/generic/lib/relational/isordered.cl
index cedd05f6e0492d..347fc2df8a3b60 100644
--- a/libclc/generic/lib/relational/isordered.cl
+++ b/libclc/generic/lib/relational/isordered.cl
@@ -1,33 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isordered.h>
 
-#define _CLC_DEFINE_ISORDERED(RET_TYPE, FUNCTION, ARG1_TYPE, ARG2_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x, ARG2_TYPE y) { \
-  return isequal(x, x) && isequal(y, y); \
-} \
+#define FUNCTION isordered
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_ISORDERED(int, isordered, float, float)
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(int, isordered, float, float)
-
-#ifdef cl_khr_fp64
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isordered(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEFINE_ISORDERED(int, isordered, double, double)
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, isordered, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isordered(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEFINE_ISORDERED(int, isordered, half, half)
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, isordered, half, half)
-
-#endif
-
-#undef _CLC_DEFINE_ISORDERED
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/isunordered.cl b/libclc/generic/lib/relational/isunordered.cl
index 90939807ffd3bb..46db60332c422e 100644
--- a/libclc/generic/lib/relational/isunordered.cl
+++ b/libclc/generic/lib/relational/isunordered.cl
@@ -1,36 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_isunordered.h>
 
-//Note: It would be nice to use __builtin_isunordered with vector inputs, but it seems to only take scalar values as
-//      input, which will produce incorrect output for vector input types.
+#define FUNCTION isunordered
+#define __CLC_BODY "binary_def.inc"
 
-_CLC_DEFINE_RELATIONAL_BINARY(int, isunordered, __builtin_isunordered, float, float)
-
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of isunordered(double, double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int isunordered(double x, double y){
-	return __builtin_isunordered(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(long, isunordered, double, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of isunordered(half, half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int isunordered(half x, half y){
-	return __builtin_isunordered(x, y);
-}
-
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(short, isunordered, half, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/relational.h b/libclc/generic/lib/relational/relational.h
deleted file mode 100644
index e492750dacb329..00000000000000
--- a/libclc/generic/lib/relational/relational.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Contains relational macros that have to return 1 for scalar and -1 for vector
- * when the result is true.
- */
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_NAME, ARG_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x){ \
-	return BUILTIN_NAME(x); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_VEC2(RET_TYPE, FUNCTION, ARG_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) { \
-  return (RET_TYPE)( (RET_TYPE){FUNCTION(x.lo), FUNCTION(x.hi)} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_VEC3(RET_TYPE, FUNCTION, ARG_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) { \
-  return (RET_TYPE)( (RET_TYPE){FUNCTION(x.s0), FUNCTION(x.s1), FUNCTION(x.s2)} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_VEC4(RET_TYPE, FUNCTION, ARG_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) { \
-  return (RET_TYPE)( \
-	(RET_TYPE){ \
-		FUNCTION(x.s0), FUNCTION(x.s1), FUNCTION(x.s2), FUNCTION(x.s3) \
-	} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_VEC8(RET_TYPE, FUNCTION, ARG_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) { \
-  return (RET_TYPE)( \
-	(RET_TYPE){ \
-		FUNCTION(x.s0), FUNCTION(x.s1), FUNCTION(x.s2), FUNCTION(x.s3), \
-		FUNCTION(x.s4), FUNCTION(x.s5), FUNCTION(x.s6), FUNCTION(x.s7) \
-	} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_VEC16(RET_TYPE, FUNCTION, ARG_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG_TYPE x) { \
-  return (RET_TYPE)( \
-	(RET_TYPE){ \
-		FUNCTION(x.s0), FUNCTION(x.s1), FUNCTION(x.s2), FUNCTION(x.s3), \
-		FUNCTION(x.s4), FUNCTION(x.s5), FUNCTION(x.s6), FUNCTION(x.s7), \
-		FUNCTION(x.s8), FUNCTION(x.s9), FUNCTION(x.sa), FUNCTION(x.sb), \
-		FUNCTION(x.sc), FUNCTION(x.sd), FUNCTION(x.se), FUNCTION(x.sf) \
-	} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(RET_TYPE, FUNCTION, ARG_TYPE) \
-_CLC_DEFINE_RELATIONAL_UNARY_VEC2(RET_TYPE##2, FUNCTION, ARG_TYPE##2) \
-_CLC_DEFINE_RELATIONAL_UNARY_VEC3(RET_TYPE##3, FUNCTION, ARG_TYPE##3) \
-_CLC_DEFINE_RELATIONAL_UNARY_VEC4(RET_TYPE##4, FUNCTION, ARG_TYPE##4) \
-_CLC_DEFINE_RELATIONAL_UNARY_VEC8(RET_TYPE##8, FUNCTION, ARG_TYPE##8) \
-_CLC_DEFINE_RELATIONAL_UNARY_VEC16(RET_TYPE##16, FUNCTION, ARG_TYPE##16)
-
-#define _CLC_DEFINE_RELATIONAL_UNARY(RET_TYPE, FUNCTION, BUILTIN_FUNCTION, ARG_TYPE) \
-_CLC_DEFINE_RELATIONAL_UNARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_FUNCTION, ARG_TYPE) \
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(RET_TYPE, FUNCTION, ARG_TYPE) \
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_NAME, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y){ \
-	return BUILTIN_NAME(x, y); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) { \
-  return (RET_TYPE)( (RET_TYPE){FUNCTION(x.lo, y.lo), FUNCTION(x.hi, y.hi)} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC2(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) { \
-  return (RET_TYPE)( (RET_TYPE){FUNCTION(x.lo, y.lo), FUNCTION(x.hi, y.hi)} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC3(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) { \
-  return (RET_TYPE)( (RET_TYPE){FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1), FUNCTION(x.s2, y.s2)} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC4(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) { \
-  return (RET_TYPE)( \
-	(RET_TYPE){ \
-		FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1), FUNCTION(x.s2, y.s2), FUNCTION(x.s3, y.s3) \
-	} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC8(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) { \
-  return (RET_TYPE)( \
-	(RET_TYPE){ \
-		FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1), FUNCTION(x.s2, y.s2), FUNCTION(x.s3, y.s3), \
-		FUNCTION(x.s4, y.s4), FUNCTION(x.s5, y.s5), FUNCTION(x.s6, y.s6), FUNCTION(x.s7, y.s7) \
-	} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC16(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG0_TYPE x, ARG1_TYPE y) { \
-  return (RET_TYPE)( \
-	(RET_TYPE){ \
-		FUNCTION(x.s0, y.s0), FUNCTION(x.s1, y.s1), FUNCTION(x.s2, y.s2), FUNCTION(x.s3, y.s3), \
-		FUNCTION(x.s4, y.s4), FUNCTION(x.s5, y.s5), FUNCTION(x.s6, y.s6), FUNCTION(x.s7, y.s7), \
-		FUNCTION(x.s8, y.s8), FUNCTION(x.s9, y.s9), FUNCTION(x.sa, y.sa), FUNCTION(x.sb, y.sb), \
-		FUNCTION(x.sc, y.sc), FUNCTION(x.sd, y.sd), FUNCTION(x.se, y.se), FUNCTION(x.sf, y.sf) \
-	} != (RET_TYPE)0); \
-}
-
-#define _CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEFINE_RELATIONAL_BINARY_VEC2(RET_TYPE##2, FUNCTION, ARG0_TYPE##2, ARG1_TYPE##2) \
-_CLC_DEFINE_RELATIONAL_BINARY_VEC3(RET_TYPE##3, FUNCTION, ARG0_TYPE##3, ARG1_TYPE##3) \
-_CLC_DEFINE_RELATIONAL_BINARY_VEC4(RET_TYPE##4, FUNCTION, ARG0_TYPE##4, ARG1_TYPE##4) \
-_CLC_DEFINE_RELATIONAL_BINARY_VEC8(RET_TYPE##8, FUNCTION, ARG0_TYPE##8, ARG1_TYPE##8) \
-_CLC_DEFINE_RELATIONAL_BINARY_VEC16(RET_TYPE##16, FUNCTION, ARG0_TYPE##16, ARG1_TYPE##16)
-
-#define _CLC_DEFINE_RELATIONAL_BINARY(RET_TYPE, FUNCTION, BUILTIN_FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEFINE_RELATIONAL_BINARY_SCALAR(RET_TYPE, FUNCTION, BUILTIN_FUNCTION, ARG0_TYPE, ARG1_TYPE) \
-_CLC_DEFINE_RELATIONAL_BINARY_VEC_ALL(RET_TYPE, FUNCTION, ARG0_TYPE, ARG1_TYPE)
diff --git a/libclc/generic/lib/relational/signbit.cl b/libclc/generic/lib/relational/signbit.cl
index a7378d7d6053e2..1cf993e22cb599 100644
--- a/libclc/generic/lib/relational/signbit.cl
+++ b/libclc/generic/lib/relational/signbit.cl
@@ -1,33 +1,7 @@
 #include <clc/clc.h>
-#include "relational.h"
+#include <clc/relational/clc_signbit.h>
 
-_CLC_DEFINE_RELATIONAL_UNARY(int, signbit, __builtin_signbitf, float)
+#define FUNCTION signbit
+#define __CLC_BODY "unary_def.inc"
 
-#ifdef cl_khr_fp64
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-// The scalar version of signbit(double) returns an int, but the vector versions
-// return long.
-
-_CLC_DEF _CLC_OVERLOAD int signbit(double x){
-	return __builtin_signbit(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(long, signbit, double)
-
-#endif
-#ifdef cl_khr_fp16
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// The scalar version of signbit(half) returns an int, but the vector versions
-// return short.
-
-_CLC_DEF _CLC_OVERLOAD int signbit(half x){
-	return __builtin_signbit(x);
-}
-
-_CLC_DEFINE_RELATIONAL_UNARY_VEC_ALL(short, signbit, half)
-
-#endif
+#include <clc/relational/floatn.inc>
diff --git a/libclc/generic/lib/relational/unary_def.inc b/libclc/generic/lib/relational/unary_def.inc
new file mode 100644
index 00000000000000..dd9fe48731f969
--- /dev/null
+++ b/libclc/generic/lib/relational/unary_def.inc
@@ -0,0 +1,7 @@
+#include <clc/utils.h>
+
+#define __CLC_FUNCTION(x) __CLC_CONCAT(__clc_, x)
+
+_CLC_OVERLOAD _CLC_DECL __CLC_INTN FUNCTION(__CLC_FLOATN a) {
+  return __CLC_FUNCTION(FUNCTION)(a);
+}



More information about the cfe-commits mailing list