Skip to content

Commit 12f3610

Browse files
committed
[HIP] fix host min/max in header (llvm#82956)
CUDA defines min/max functions for host in global namespace. HIP header needs to define them too to be compatible. Currently only min/max(int, int) is defined. This causes wrong result for arguments that are out of range for int. This patch defines host min/max functions to be compatible with CUDA. Also allows users to define `__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__` to disable host max/min in global namespace. min/max functions with mixed signed/unsigned integer parameters are not defined unless `__HIP_DEFINE_MIXED_HOST_MIN_MAX__` is defined. Fixes: SWDEV-446564
1 parent 411ee79 commit 12f3610

File tree

1 file changed

+66
-6
lines changed

1 file changed

+66
-6
lines changed

clang/lib/Headers/__clang_hip_math.h

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,15 +1349,75 @@ float min(float __x, float __y) { return __builtin_fminf(__x, __y); }
13491349
__DEVICE__
13501350
double min(double __x, double __y) { return __builtin_fmin(__x, __y); }
13511351

1352-
#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
1353-
__host__ inline static int min(int __arg1, int __arg2) {
1354-
return __arg1 < __arg2 ? __arg1 : __arg2;
1352+
// Define host min/max functions.
1353+
#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__) && \
1354+
!defined(__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__)
1355+
1356+
#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
1357+
#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
1358+
#define DEFINE_MIN_MAX_FUNCTIONS(ret_type, type1, type2) \
1359+
inline ret_type min(const type1 __a, const type2 __b) { \
1360+
return (__a < __b) ? __a : __b; \
1361+
} \
1362+
inline ret_type max(const type1 __a, const type2 __b) { \
1363+
return (__a > __b) ? __a : __b; \
1364+
}
1365+
1366+
// Define min and max functions for same type comparisons
1367+
DEFINE_MIN_MAX_FUNCTIONS(int, int, int)
1368+
DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, unsigned int)
1369+
DEFINE_MIN_MAX_FUNCTIONS(long, long, long)
1370+
DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, unsigned long)
1371+
DEFINE_MIN_MAX_FUNCTIONS(long long, long long, long long)
1372+
DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long,
1373+
unsigned long long)
1374+
1375+
// The host min/max functions below accept mixed signed/unsigned integer
1376+
// parameters and perform unsigned comparisons, which may produce unexpected
1377+
// results if a signed integer was passed unintentionally. To avoid this
1378+
// happening silently, these overloaded functions are not defined by default.
1379+
// However, for compatibility with CUDA, they will be defined if users define
1380+
// __HIP_DEFINE_MIXED_HOST_MIN_MAX__.
1381+
#ifdef __HIP_DEFINE_MIXED_HOST_MIN_MAX__
1382+
DEFINE_MIN_MAX_FUNCTIONS(unsigned int, int, unsigned int)
1383+
DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, int)
1384+
DEFINE_MIN_MAX_FUNCTIONS(unsigned long, long, unsigned long)
1385+
DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, long)
1386+
DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, long long, unsigned long long)
1387+
DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long, long long)
1388+
#endif // ifdef __HIP_DEFINE_MIXED_HOST_MIN_MAX__
1389+
1390+
// Floating-point comparisons using built-in functions
1391+
inline float min(float const __a, float const __b) {
1392+
return __builtin_fminf(__a, __b);
1393+
}
1394+
inline double min(double const __a, double const __b) {
1395+
return __builtin_fmin(__a, __b);
1396+
}
1397+
inline double min(float const __a, double const __b) {
1398+
return __builtin_fmin(__a, __b);
1399+
}
1400+
inline double min(double const __a, float const __b) {
1401+
return __builtin_fmin(__a, __b);
13551402
}
13561403

1357-
__host__ inline static int max(int __arg1, int __arg2) {
1358-
return __arg1 > __arg2 ? __arg1 : __arg2;
1404+
inline float max(float const __a, float const __b) {
1405+
return __builtin_fmaxf(__a, __b);
1406+
}
1407+
inline double max(double const __a, double const __b) {
1408+
return __builtin_fmax(__a, __b);
1409+
}
1410+
inline double max(float const __a, double const __b) {
1411+
return __builtin_fmax(__a, __b);
13591412
}
1360-
#endif // !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
1413+
inline double max(double const __a, float const __b) {
1414+
return __builtin_fmax(__a, __b);
1415+
}
1416+
1417+
#pragma pop_macro("DEFINE_MIN_MAX_FUNCTIONS")
1418+
1419+
#endif // !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__) &&
1420+
// !defined(__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__)
13611421
#endif
13621422

13631423
#pragma pop_macro("__DEVICE_NOCE__")

0 commit comments

Comments
 (0)