Skip to content

Commit 8d2b49e

Browse files
committed
libclc: clspv: update gen_convert.cl for clspv
Add a clspv switch in gen_convert.cl This is needed as Vulkan SPIR-V does not respect the assumptions needed to have the generic convert.cl compliant on many platforms. It is needed because of the conversion of TYPE_MAX and TYPE_MIN. Depending on the platform the behaviour can vary, but most of them just do not convert correctly those 2 values. Because of that, we also need to avoid having explicit function for simple conversions because it allows llvm to optimise the code, thus removing some of the added checks that are in fact needed. I did not use python argparse to avoid adding the dependency on it.
1 parent b19cfb9 commit 8d2b49e

File tree

2 files changed

+83
-16
lines changed

2 files changed

+83
-16
lines changed

libclc/CMakeLists.txt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ add_custom_command(
174174
DEPENDS ${script_loc} )
175175
add_custom_target( "generate_convert.cl" DEPENDS convert.cl )
176176

177+
add_custom_command(
178+
OUTPUT clspv-convert.cl
179+
COMMAND ${Python3_EXECUTABLE} ${script_loc} --clspv > clspv-convert.cl
180+
DEPENDS ${script_loc} )
181+
add_custom_target( "clspv-generate_convert.cl" DEPENDS clspv-convert.cl )
182+
177183
enable_testing()
178184

179185
foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
@@ -218,11 +224,14 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
218224
# Add the generated convert.cl here to prevent adding
219225
# the one listed in SOURCES
220226
if( NOT ${ARCH} STREQUAL "spirv" AND NOT ${ARCH} STREQUAL "spirv64" )
221-
set( rel_files convert.cl )
222-
set( objects convert.cl )
223227
if( NOT ENABLE_RUNTIME_SUBNORMAL AND NOT ${ARCH} STREQUAL "clspv" AND
224228
NOT ${ARCH} STREQUAL "clspv64" )
229+
set( rel_files convert.cl )
230+
set( objects convert.cl )
225231
list( APPEND rel_files generic/lib/subnormal_use_default.ll )
232+
elseif(${ARCH} STREQUAL "clspv" OR ${ARCH} STREQUAL "clspv64")
233+
set( rel_files clspv-convert.cl )
234+
set( objects clspv-convert.cl )
226235
endif()
227236
else()
228237
set( rel_files )
@@ -286,6 +295,8 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
286295
# multiple invocations
287296
add_dependencies( builtins.link.${arch_suffix}
288297
generate_convert.cl )
298+
add_dependencies( builtins.link.${arch_suffix}
299+
clspv-generate_convert.cl )
289300
# CMake will turn this include into absolute path
290301
target_include_directories( builtins.link.${arch_suffix} PRIVATE
291302
"generic/include" )

libclc/generic/lib/gen_convert.py

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#
33
# Copyright (c) 2013 Victor Oliveira <[email protected]>
44
# Copyright (c) 2013 Jesse Towner <[email protected]>
5+
# Copyright (c) 2024 Romaric Jodin <[email protected]>
56
#
67
# Permission is hereby granted, free of charge, to any person obtaining a copy
78
# of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +27,12 @@
2627
#
2728
# convert_<destTypen><_sat><_roundingMode>(<sourceTypen>)
2829

30+
import sys
31+
32+
clspv = False
33+
if len(sys.argv) == 2 and sys.argv[1] == "--clspv":
34+
clspv = True
35+
2936
types = [
3037
"char",
3138
"uchar",
@@ -251,13 +258,19 @@ def generate_default_conversion(src, dst, mode):
251258
print("#endif")
252259

253260

254-
for src in types:
255-
for dst in types:
256-
generate_default_conversion(src, dst, "")
261+
# Do not generate default conversion for clspv as they are handle natively
262+
if not clspv:
263+
for src in types:
264+
for dst in types:
265+
generate_default_conversion(src, dst, "")
257266

258267
for src in int_types:
259268
for dst in int_types:
260269
for mode in rounding_modes:
270+
# Do not generate "_rte" conversion for clspv as they are handle
271+
# natively
272+
if clspv and mode == "_rte":
273+
continue
261274
generate_default_conversion(src, dst, mode)
262275

263276
#
@@ -307,8 +320,8 @@ def generate_saturated_conversion(src, dst, size):
307320
# Conversion from float to int
308321
print(
309322
""" {DST}{N} y = convert_{DST}{N}(x);
310-
y = select(y, ({DST}{N}){DST_MIN}, {BP}(x < ({SRC}{N}){DST_MIN}){BS});
311-
y = select(y, ({DST}{N}){DST_MAX}, {BP}(x > ({SRC}{N}){DST_MAX}){BS});
323+
y = select(y, ({DST}{N}){DST_MIN}, {BP}(x <= ({SRC}{N}){DST_MIN}){BS});
324+
y = select(y, ({DST}{N}){DST_MAX}, {BP}(x >= ({SRC}{N}){DST_MAX}){BS});
312325
return y;""".format(
313326
SRC=src,
314327
DST=dst,
@@ -432,7 +445,10 @@ def generate_float_conversion(src, dst, size, mode, sat):
432445
print(" return convert_{DST}{N}(x);".format(DST=dst, N=size))
433446
else:
434447
print(" {DST}{N} r = convert_{DST}{N}(x);".format(DST=dst, N=size))
435-
print(" {SRC}{N} y = convert_{SRC}{N}(r);".format(SRC=src, N=size))
448+
if clspv:
449+
print(" {SRC}{N} y = convert_{SRC}{N}_sat(r);".format(SRC=src, N=size))
450+
else:
451+
print(" {SRC}{N} y = convert_{SRC}{N}(r);".format(SRC=src, N=size))
436452
if mode == "_rtz":
437453
if src in int_types:
438454
print(
@@ -448,23 +464,59 @@ def generate_float_conversion(src, dst, size, mode, sat):
448464
else:
449465
print(" {SRC}{N} abs_x = fabs(x);".format(SRC=src, N=size))
450466
print(" {SRC}{N} abs_y = fabs(y);".format(SRC=src, N=size))
451-
print(
452-
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x));".format(
453-
DST=dst, N=size, BOOL=bool_type[dst]
467+
if clspv:
468+
print(
469+
" {BOOL}{N} c = convert_{BOOL}{N}(abs_y > abs_x);".format(
470+
BOOL=bool_type[dst], N=size
471+
)
472+
)
473+
if sizeof_type[src] >= 4 and src in int_types:
474+
print(
475+
" c = c || convert_{BOOL}{N}(({SRC}{N}){SRC_MAX} == x);".format(
476+
BOOL=bool_type[dst], N=size, SRC=src, SRC_MAX=limit_max[src]
477+
)
478+
)
479+
print(
480+
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), c);".format(
481+
DST=dst, N=size, BOOL=bool_type[dst], SRC=src
482+
)
483+
)
484+
else:
485+
print(
486+
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x));".format(
487+
DST=dst, N=size, BOOL=bool_type[dst]
488+
)
454489
)
455-
)
456490
if mode == "_rtp":
457491
print(
458492
" return select(r, nextafter(r, ({DST}{N})INFINITY), convert_{BOOL}{N}(y < x));".format(
459493
DST=dst, N=size, BOOL=bool_type[dst]
460494
)
461495
)
462496
if mode == "_rtn":
463-
print(
464-
" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));".format(
465-
DST=dst, N=size, BOOL=bool_type[dst]
497+
if clspv:
498+
print(
499+
" {BOOL}{N} c = convert_{BOOL}{N}(y > x);".format(
500+
BOOL=bool_type[dst], N=size
501+
)
502+
)
503+
if sizeof_type[src] >= 4 and src in int_types:
504+
print(
505+
" c = c || convert_{BOOL}{N}(({SRC}{N}){SRC_MAX} == x);".format(
506+
BOOL=bool_type[dst], N=size, SRC=src, SRC_MAX=limit_max[src]
507+
)
508+
)
509+
print(
510+
" return select(r, nextafter(r, ({DST}{N})-INFINITY), c);".format(
511+
DST=dst, N=size, BOOL=bool_type[dst], SRC=src
512+
)
513+
)
514+
else:
515+
print(
516+
" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));".format(
517+
DST=dst, N=size, BOOL=bool_type[dst]
518+
)
466519
)
467-
)
468520

469521
# Footer
470522
print("}")
@@ -484,4 +536,8 @@ def generate_float_conversion(src, dst, size, mode, sat):
484536
for dst in float_types:
485537
for size in vector_sizes:
486538
for mode in rounding_modes:
539+
# Do not generate "_rte" conversion for clspv as they are
540+
# handle natively
541+
if clspv and mode == "_rte":
542+
continue
487543
generate_float_conversion(src, dst, size, mode, "")

0 commit comments

Comments
 (0)