https://github.com/frasercrmck updated https://github.com/llvm/llvm-project/pull/115699
>From 9c5f79e720d0701d17f9d128b358320401baf666 Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fra...@codeplay.com> Date: Thu, 7 Nov 2024 12:40:56 +0000 Subject: [PATCH 1/2] [libclc] Move sign to the CLC builtins library This patch necessitates some changes to how CLSPV and SPIR-V targets are built. This is the first patch in this series in which an OpenCL function declaration has been called from the CLC library for these targets. Since libclc's OpenCL headers aren't being included at this stage, the OpenCL sign function isn't available. To fix this, these two libclc targets now have clang declare OpenCL builtins when building the internal CLC library. The __CLC_INTERNAL preprocessor definition has been repurposed (without the leading underscores) to be passed when building the internal CLC library. It was only used in one other place to guard an extra maths preprocessor definition, which we can do unconditionally. There are no changes (with llvm-diff) to any libclc target other than SPIR-V, which now has OpenCL sign call __clc_sign. --- libclc/CMakeLists.txt | 11 ++- libclc/clc/include/clc/common/clc_sign.h | 17 ++++ libclc/clc/include/clc/common/floatn.inc | 85 +++++++++++++++++++ libclc/clc/include/clc/common/unary_def.inc | 7 ++ libclc/clc/lib/generic/SOURCES | 1 + libclc/clc/lib/generic/common/clc_sign.cl | 38 +++++++++ libclc/clc/lib/spirv/SOURCES | 1 + libclc/clc/lib/spirv64/SOURCES | 1 + .../generic/include/clc/float/definitions.h | 4 +- libclc/generic/lib/common/sign.cl | 37 +------- 10 files changed, 164 insertions(+), 38 deletions(-) create mode 100644 libclc/clc/include/clc/common/clc_sign.h create mode 100644 libclc/clc/include/clc/common/floatn.inc create mode 100644 libclc/clc/include/clc/common/unary_def.inc create mode 100644 libclc/clc/lib/generic/common/clc_sign.cl diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 2c2c7f16e29442..68ce43605b8dd6 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -347,7 +347,6 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) string( TOUPPER "CLC_${MACRO_ARCH}" CLC_TARGET_DEFINE ) list( APPEND build_flags - -D__CLC_INTERNAL -D${CLC_TARGET_DEFINE} # All libclc builtin libraries see CLC headers -I${CMAKE_CURRENT_SOURCE_DIR}/clc/include @@ -359,12 +358,20 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) list( APPEND build_flags -mcpu=${cpu} ) endif() + set( clc_build_flags ${build_flags} -DCLC_INTERNAL ) + + # clspv and spir-v targets remap some CLC functions to OpenCL builtins. + # Automatically provide those declarations to the compiler for CLC builtins. + if ( ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 OR ARCH STREQUAL clspv OR ARCH STREQUAL clspv64 ) + list( APPEND clc_build_flags -Xclang -fdeclare-opencl-builtins ) + endif() + add_libclc_builtin_set( CLC_INTERNAL ARCH ${ARCH} ARCH_SUFFIX clc-${arch_suffix} TRIPLE ${clang_triple} - COMPILE_FLAGS ${build_flags} + COMPILE_FLAGS ${clc_build_flags} OPT_FLAGS ${opt_flags} LIB_FILES ${clc_lib_files} ) diff --git a/libclc/clc/include/clc/common/clc_sign.h b/libclc/clc/include/clc/common/clc_sign.h new file mode 100644 index 00000000000000..bda4fa65dfa890 --- /dev/null +++ b/libclc/clc/include/clc/common/clc_sign.h @@ -0,0 +1,17 @@ +#ifndef __CLC_COMMON_CLC_SIGN_H__ +#define __CLC_COMMON_CLC_SIGN_H__ + +#if defined(CLC_CLSPV) +// clspv targets provide their own OpenCL-compatible sign +#define __clc_sign sign +#else + +#define __CLC_FUNCTION __clc_sign +#define __CLC_BODY <clc/math/unary_decl.inc> +#include <clc/math/gentype.inc> +#undef __CLC_FUNCTION +#undef __CLC_BODY + +#endif + +#endif // __CLC_COMMON_CLC_SIGN_H__ diff --git a/libclc/clc/include/clc/common/floatn.inc b/libclc/clc/include/clc/common/floatn.inc new file mode 100644 index 00000000000000..2c4285d5bcbc58 --- /dev/null +++ b/libclc/clc/include/clc/common/floatn.inc @@ -0,0 +1,85 @@ +#define __CLC_FLOATN float +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN float2 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN float3 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN float4 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN float8 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN float16 +#include __CLC_BODY +#undef __CLC_FLOATN + +#undef __CLC_FLOAT +#undef __CLC_INT + +#ifdef cl_khr_fp64 +#pragma OPENCL EXTENSION cl_khr_fp64 : enable + +#define __CLC_FLOATN double +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN double2 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN double3 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN double4 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN double8 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN double16 +#include __CLC_BODY +#undef __CLC_FLOATN + +#endif +#ifdef cl_khr_fp16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#define __CLC_FLOATN half +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN half2 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN half3 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN half4 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN half8 +#include __CLC_BODY +#undef __CLC_FLOATN + +#define __CLC_FLOATN half16 +#include __CLC_BODY +#undef __CLC_FLOATN + +#endif + +#undef __CLC_BODY diff --git a/libclc/clc/include/clc/common/unary_def.inc b/libclc/clc/include/clc/common/unary_def.inc new file mode 100644 index 00000000000000..d4a3bf80775f0e --- /dev/null +++ b/libclc/clc/include/clc/common/unary_def.inc @@ -0,0 +1,7 @@ +#include <clc/utils.h> + +#define __CLC_FUNCTION(x) __CLC_CONCAT(__clc_, x) + +_CLC_OVERLOAD _CLC_DEF __CLC_FLOATN FUNCTION(__CLC_FLOATN a) { + return __CLC_FUNCTION(FUNCTION)(a); +} diff --git a/libclc/clc/lib/generic/SOURCES b/libclc/clc/lib/generic/SOURCES index 877a0a390a7452..67fb4fe05b5388 100644 --- a/libclc/clc/lib/generic/SOURCES +++ b/libclc/clc/lib/generic/SOURCES @@ -1,5 +1,6 @@ common/clc_degrees.cl common/clc_radians.cl +common/clc_sign.cl common/clc_smoothstep.cl geometric/clc_dot.cl integer/clc_abs.cl diff --git a/libclc/clc/lib/generic/common/clc_sign.cl b/libclc/clc/lib/generic/common/clc_sign.cl new file mode 100644 index 00000000000000..6c4db4af3f4c57 --- /dev/null +++ b/libclc/clc/lib/generic/common/clc_sign.cl @@ -0,0 +1,38 @@ +#include <clc/clcmacro.h> +#include <clc/internal/clc.h> +#include <clc/relational/clc_isnan.h> + +#define CLC_SIGN(TYPE, F) \ + _CLC_DEF _CLC_OVERLOAD TYPE __clc_sign(TYPE x) { \ + if (__clc_isnan(x)) { \ + return 0.0F; \ + } \ + if (x > 0.0F) { \ + return 1.0F; \ + } \ + if (x < 0.0F) { \ + return -1.0F; \ + } \ + return x; /* -0.0 or +0.0 */ \ + } + +CLC_SIGN(float, f) +_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_sign, float) + +#ifdef cl_khr_fp64 + +#pragma OPENCL EXTENSION cl_khr_fp64 : enable + +CLC_SIGN(double, ) +_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_sign, double) + +#endif + +#ifdef cl_khr_fp16 + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +CLC_SIGN(half, ) +_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, __clc_sign, half) + +#endif diff --git a/libclc/clc/lib/spirv/SOURCES b/libclc/clc/lib/spirv/SOURCES index 905afa03d8a56c..cd8480564f8c16 100644 --- a/libclc/clc/lib/spirv/SOURCES +++ b/libclc/clc/lib/spirv/SOURCES @@ -1,5 +1,6 @@ ../generic/common/clc_degrees.cl ../generic/common/clc_radians.cl +../generic/common/clc_sign.cl ../generic/common/clc_smoothstep.cl ../generic/geometric/clc_dot.cl ../generic/math/clc_ceil.cl diff --git a/libclc/clc/lib/spirv64/SOURCES b/libclc/clc/lib/spirv64/SOURCES index 905afa03d8a56c..cd8480564f8c16 100644 --- a/libclc/clc/lib/spirv64/SOURCES +++ b/libclc/clc/lib/spirv64/SOURCES @@ -1,5 +1,6 @@ ../generic/common/clc_degrees.cl ../generic/common/clc_radians.cl +../generic/common/clc_sign.cl ../generic/common/clc_smoothstep.cl ../generic/geometric/clc_dot.cl ../generic/math/clc_ceil.cl diff --git a/libclc/generic/include/clc/float/definitions.h b/libclc/generic/include/clc/float/definitions.h index 62501230c92de2..be3d0130f3e614 100644 --- a/libclc/generic/include/clc/float/definitions.h +++ b/libclc/generic/include/clc/float/definitions.h @@ -31,9 +31,7 @@ #define M_SQRT2_F 0x1.6a09e6p+0f #define M_SQRT1_2_F 0x1.6a09e6p-1f -#ifdef __CLC_INTERNAL -#define M_LOG210_F 0x1.a934f0p+1f -#endif +#define M_LOG210_F 0x1.a934f0p+1f #ifdef cl_khr_fp64 diff --git a/libclc/generic/lib/common/sign.cl b/libclc/generic/lib/common/sign.cl index ad8f7405e0cb30..5e70ef73f3f45c 100644 --- a/libclc/generic/lib/common/sign.cl +++ b/libclc/generic/lib/common/sign.cl @@ -1,37 +1,8 @@ #include <clc/clc.h> #include <clc/clcmacro.h> +#include <clc/common/clc_sign.h> -#define SIGN(TYPE, F) \ -_CLC_DEF _CLC_OVERLOAD TYPE sign(TYPE x) { \ - if (isnan(x)) { \ - return 0.0F; \ - } \ - if (x > 0.0F) { \ - return 1.0F; \ - } \ - if (x < 0.0F) { \ - return -1.0F; \ - } \ - return x; /* -0.0 or +0.0 */ \ -} +#define FUNCTION sign +#define __CLC_BODY <clc/common/unary_def.inc> -SIGN(float, f) -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, sign, float) - -#ifdef cl_khr_fp64 - -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -SIGN(double, ) -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, sign, double) - -#endif - -#ifdef cl_khr_fp16 - -#pragma OPENCL EXTENSION cl_khr_fp16 : enable - -SIGN(half,) -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, sign, half) - -#endif +#include <clc/common/floatn.inc> >From d01bbfd7202350478ba429465d5d984ebaa52ae8 Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fra...@codeplay.com> Date: Mon, 20 Jan 2025 18:42:37 +0000 Subject: [PATCH 2/2] optimize via vectors --- libclc/clc/include/clc/math/gentype.inc | 42 ++++++++++++++++++++++ libclc/clc/lib/generic/common/clc_sign.cl | 39 ++------------------ libclc/clc/lib/generic/common/clc_sign.inc | 21 +++++++++++ libclc/generic/lib/common/sign.cl | 17 +++++++-- 4 files changed, 80 insertions(+), 39 deletions(-) create mode 100644 libclc/clc/lib/generic/common/clc_sign.inc diff --git a/libclc/clc/include/clc/math/gentype.inc b/libclc/clc/include/clc/math/gentype.inc index 87719f2d9bc0e7..3c80f1c6172ad0 100644 --- a/libclc/clc/include/clc/math/gentype.inc +++ b/libclc/clc/include/clc/math/gentype.inc @@ -3,55 +3,69 @@ #define __CLC_SCALAR_GENTYPE float #define __CLC_FPSIZE 32 +#define __CLC_FP_LIT(x) x##F #define __CLC_GENTYPE float #define __CLC_INTN int +#define __CLC_BIT_INTN int #define __CLC_SCALAR #include __CLC_BODY #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #undef __CLC_SCALAR #define __CLC_GENTYPE float2 #define __CLC_INTN int2 +#define __CLC_BIT_INTN int2 #define __CLC_VECSIZE 2 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE float3 #define __CLC_INTN int3 +#define __CLC_BIT_INTN int3 #define __CLC_VECSIZE 3 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE float4 #define __CLC_INTN int4 +#define __CLC_BIT_INTN int4 #define __CLC_VECSIZE 4 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE float8 #define __CLC_INTN int8 +#define __CLC_BIT_INTN int8 #define __CLC_VECSIZE 8 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE float16 #define __CLC_INTN int16 +#define __CLC_BIT_INTN int16 #define __CLC_VECSIZE 16 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN +#undef __CLC_FP_LIT #undef __CLC_FPSIZE #undef __CLC_SCALAR_GENTYPE @@ -61,55 +75,69 @@ #define __CLC_SCALAR_GENTYPE double #define __CLC_FPSIZE 64 +#define __CLC_FP_LIT(x) (x) #define __CLC_SCALAR #define __CLC_GENTYPE double #define __CLC_INTN int +#define __CLC_BIT_INTN long #include __CLC_BODY #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #undef __CLC_SCALAR #define __CLC_GENTYPE double2 #define __CLC_INTN int2 +#define __CLC_BIT_INTN long2 #define __CLC_VECSIZE 2 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE double3 #define __CLC_INTN int3 +#define __CLC_BIT_INTN long3 #define __CLC_VECSIZE 3 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE double4 #define __CLC_INTN int4 +#define __CLC_BIT_INTN long4 #define __CLC_VECSIZE 4 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE double8 #define __CLC_INTN int8 +#define __CLC_BIT_INTN long8 #define __CLC_VECSIZE 8 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE double16 #define __CLC_INTN int16 +#define __CLC_BIT_INTN long16 #define __CLC_VECSIZE 16 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN +#undef __CLC_FP_LIT #undef __CLC_FPSIZE #undef __CLC_SCALAR_GENTYPE #endif @@ -121,55 +149,69 @@ #define __CLC_SCALAR_GENTYPE half #define __CLC_FPSIZE 16 +#define __CLC_FP_LIT(x) x##H #define __CLC_SCALAR #define __CLC_GENTYPE half #define __CLC_INTN int +#define __CLC_BIT_INTN short #include __CLC_BODY #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #undef __CLC_SCALAR #define __CLC_GENTYPE half2 #define __CLC_INTN int2 +#define __CLC_BIT_INTN short2 #define __CLC_VECSIZE 2 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE half3 #define __CLC_INTN int3 +#define __CLC_BIT_INTN short3 #define __CLC_VECSIZE 3 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE half4 #define __CLC_INTN int4 +#define __CLC_BIT_INTN short4 #define __CLC_VECSIZE 4 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE half8 #define __CLC_INTN int8 +#define __CLC_BIT_INTN short8 #define __CLC_VECSIZE 8 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN #define __CLC_GENTYPE half16 #define __CLC_INTN int16 +#define __CLC_BIT_INTN short16 #define __CLC_VECSIZE 16 #include __CLC_BODY #undef __CLC_VECSIZE #undef __CLC_GENTYPE +#undef __CLC_BIT_INTN #undef __CLC_INTN +#undef __CLC_FP_LIT #undef __CLC_FPSIZE #undef __CLC_SCALAR_GENTYPE #endif diff --git a/libclc/clc/lib/generic/common/clc_sign.cl b/libclc/clc/lib/generic/common/clc_sign.cl index 6c4db4af3f4c57..752808b0d84d63 100644 --- a/libclc/clc/lib/generic/common/clc_sign.cl +++ b/libclc/clc/lib/generic/common/clc_sign.cl @@ -1,38 +1,5 @@ -#include <clc/clcmacro.h> -#include <clc/internal/clc.h> #include <clc/relational/clc_isnan.h> +#include <clc/relational/clc_select.h> -#define CLC_SIGN(TYPE, F) \ - _CLC_DEF _CLC_OVERLOAD TYPE __clc_sign(TYPE x) { \ - if (__clc_isnan(x)) { \ - return 0.0F; \ - } \ - if (x > 0.0F) { \ - return 1.0F; \ - } \ - if (x < 0.0F) { \ - return -1.0F; \ - } \ - return x; /* -0.0 or +0.0 */ \ - } - -CLC_SIGN(float, f) -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, __clc_sign, float) - -#ifdef cl_khr_fp64 - -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -CLC_SIGN(double, ) -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, __clc_sign, double) - -#endif - -#ifdef cl_khr_fp16 - -#pragma OPENCL EXTENSION cl_khr_fp16 : enable - -CLC_SIGN(half, ) -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, half, __clc_sign, half) - -#endif +#define __CLC_BODY <clc_sign.inc> +#include <clc/math/gentype.inc> diff --git a/libclc/clc/lib/generic/common/clc_sign.inc b/libclc/clc/lib/generic/common/clc_sign.inc new file mode 100644 index 00000000000000..b28b371bb44a98 --- /dev/null +++ b/libclc/clc/lib/generic/common/clc_sign.inc @@ -0,0 +1,21 @@ +// TYPE sign(TYPE x) { +// if (isnan(x)) { +// return 0.0F; +// } +// if (x > 0.0F) { +// return 1.0F; +// } +// if (x < 0.0F) { +// return -1.0F; +// } +// return x; /* -0.0 or +0.0 */ +// } +_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_sign(__CLC_GENTYPE x) { + __CLC_BIT_INTN x_isnan = __clc_isnan(x); + __CLC_BIT_INTN x_isgreater_zero = x > __CLC_FP_LIT(0.0); + __CLC_BIT_INTN x_isless_zero = x < __CLC_FP_LIT(0.0); + __CLC_GENTYPE sel0 = __clc_select(x, __CLC_FP_LIT(1.0), x_isgreater_zero); + __CLC_GENTYPE sel1 = __clc_select(sel0, __CLC_FP_LIT(-1.0), x_isless_zero); + __CLC_GENTYPE sel2 = __clc_select(sel1, __CLC_FP_LIT(0.0), x_isnan); + return sel2; +} diff --git a/libclc/generic/lib/common/sign.cl b/libclc/generic/lib/common/sign.cl index 5e70ef73f3f45c..91b21ae437632f 100644 --- a/libclc/generic/lib/common/sign.cl +++ b/libclc/generic/lib/common/sign.cl @@ -2,7 +2,18 @@ #include <clc/clcmacro.h> #include <clc/common/clc_sign.h> -#define FUNCTION sign -#define __CLC_BODY <clc/common/unary_def.inc> +_CLC_DEFINE_UNARY_BUILTIN(float, sign, __clc_sign, float) -#include <clc/common/floatn.inc> +#ifdef cl_khr_fp64 +#pragma OPENCL EXTENSION cl_khr_fp64 : enable + +_CLC_DEFINE_UNARY_BUILTIN(double, sign, __clc_sign, double) + +#endif + +#ifdef cl_khr_fp16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +_CLC_DEFINE_UNARY_BUILTIN(half, sign, __clc_sign, half) + +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits