================ @@ -1306,15 +1306,68 @@ float min(float __x, float __y) { return __builtin_fminf(__x, __y); } __DEVICE__ double min(double __x, double __y) { return __builtin_fmin(__x, __y); } -#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__) -__host__ inline static int min(int __arg1, int __arg2) { - return __arg1 < __arg2 ? __arg1 : __arg2; +// Define host min/max functions. +#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__) && \ + !defined(__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__) + +#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS") +#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS") +#define DEFINE_MIN_MAX_FUNCTIONS(ret_type, type1, type2) \ + static inline ret_type min(const type1 __a, const type2 __b) { \ + return (__a < __b) ? __a : __b; \ + } \ + static inline ret_type max(const type1 __a, const type2 __b) { \ + return (__a > __b) ? __a : __b; \ + } + +// Define min and max functions for same type comparisons +DEFINE_MIN_MAX_FUNCTIONS(int, int, int) +DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, unsigned int) +DEFINE_MIN_MAX_FUNCTIONS(long, long, long) +DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, unsigned long) +DEFINE_MIN_MAX_FUNCTIONS(long long, long long, long long) +DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long, + unsigned long long) + +// Define min and max functions for all mixed type comparisons +DEFINE_MIN_MAX_FUNCTIONS(unsigned int, int, unsigned int) +DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, int) +DEFINE_MIN_MAX_FUNCTIONS(unsigned long, long, unsigned long) +DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, long) +DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, long long, unsigned long long) +DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long, long long) ---------------- yxsamliu wrote:
> I assume these are needed in order to avoid errors about ambiguous overload > resolution when we pass signed/unsigned arguments. > > Normally, if we were to use `std::min()` function, the user would have to > explicitly cast arguments or use `std::min<unsigned>()` to resolve the issue. > > Implicitly converting int->unsigned under the hood is probably not a good > idea here as we do not know what the user needs/wants and whether it's a WAI > or an error. For min/max converting a negative argument into an unsigned > would probably be an error. I think we do need to force users to use one of > the all-signed or all-unsigned variants here, too, same as with std::min/max. You are right about that std::min/max does not allow mixed signed/unsigned arguments. Unfortunately, that is how CUDA defines its host min/max functions, e.g. https://godbolt.org/z/Wxxq9dv91 Not following this could cause incompatibility and regressions. https://github.com/llvm/llvm-project/pull/82956 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits