Author: Sarah Spall
Date: 2025-03-19T08:47:56-07:00
New Revision: 2c41a8e6d39800383edfd863d6d96f0cfc4a2283

URL: 
https://github.com/llvm/llvm-project/commit/2c41a8e6d39800383edfd863d6d96f0cfc4a2283
DIFF: 
https://github.com/llvm/llvm-project/commit/2c41a8e6d39800383edfd863d6d96f0cfc4a2283.diff

LOG: [HLSL] Fix bug in new clamp overloads (#131928)

In some cases using the newly introduced clamp overloads, when floats
were involved, clang would behave differently than DXC.
To ensure the same behavior as DXC, require that for mix scalar/vector
overloads the type of the scalar matches the type of the vector.

Added: 
    

Modified: 
    clang/lib/Headers/hlsl/hlsl_compat_overloads.h
    clang/test/CodeGenHLSL/builtins/clamp.hlsl
    clang/test/SemaHLSL/BuiltIns/clamp-errors-16bit.hlsl
    clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h 
b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index 97f3cade32676..1553d6e2a34ed 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -20,39 +20,23 @@ namespace hlsl {
 // clamp builtins overloads
 
//===----------------------------------------------------------------------===//
 
-template <typename T, typename R, typename U, uint N>
-constexpr __detail::enable_if_t<
-    __detail::is_arithmetic<U>::Value && (N > 1 && N <= 4), vector<T, N>>
-clamp(vector<T, N> p0, vector<R, N> p1, U p2) {
-  return clamp(p0, (vector<T, N>)p1, (vector<T, N>)p2);
-}
-template <typename T, typename R, typename U, uint N>
-constexpr __detail::enable_if_t<
-    __detail::is_arithmetic<U>::Value && (N > 1 && N <= 4), vector<T, N>>
-clamp(vector<T, N> p0, U p1, vector<R, N> p2) {
-  return clamp(p0, (vector<T, N>)p1, (vector<T, N>)p2);
+template <typename T, uint N>
+constexpr __detail::enable_if_t<(N > 1 && N <= 4), vector<T, N>>
+clamp(vector<T, N> p0, vector<T, N> p1, T p2) {
+  return clamp(p0, p1, (vector<T, N>)p2);
 }
-template <typename T, typename U, typename V, uint N>
-constexpr __detail::enable_if_t<__detail::is_arithmetic<U>::Value &&
-                                    __detail::is_arithmetic<V>::Value &&
-                                    (N > 1 && N <= 4),
-                                vector<T, N>>
-clamp(vector<T, N> p0, U p1, V p2) {
-  return clamp(p0, (vector<T, N>)p1, (vector<T, N>)p2);
+
+template <typename T, uint N>
+constexpr __detail::enable_if_t<(N > 1 && N <= 4), vector<T, N>>
+clamp(vector<T, N> p0, T p1, vector<T, N> p2) {
+  return clamp(p0, (vector<T, N>)p1, p2);
 }
-template <typename T, typename R, typename S, uint N>
+
+template <typename T, uint N>
 constexpr __detail::enable_if_t<(N > 1 && N <= 4), vector<T, N>>
-clamp(vector<T, N> p0, vector<R, N> p1, vector<S, N> p2) {
+clamp(vector<T, N> p0, T p1, T p2) {
   return clamp(p0, (vector<T, N>)p1, (vector<T, N>)p2);
 }
-template <typename U, typename V, typename W>
-constexpr __detail::enable_if_t<__detail::is_arithmetic<U>::Value &&
-                                    __detail::is_arithmetic<V>::Value &&
-                                    __detail::is_arithmetic<W>::Value,
-                                U>
-clamp(U p0, V p1, W p2) {
-  return clamp(p0, (U)p1, (U)p2);
-}
 
 } // namespace hlsl
 #endif // _HLSL_COMPAT_OVERLOADS_H_

diff  --git a/clang/test/CodeGenHLSL/builtins/clamp.hlsl 
b/clang/test/CodeGenHLSL/builtins/clamp.hlsl
index f04b6096fa220..7647aa165141d 100644
--- a/clang/test/CodeGenHLSL/builtins/clamp.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/clamp.hlsl
@@ -174,22 +174,6 @@ double4 test_clamp_double4_mismatch(double4 p0, double p1) 
{ return clamp(p0, p0
 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> 
@llvm.[[TARGET]].nclamp.v4f64
 double4 test_clamp_double4_mismatch2(double4 p0, double p1) { return clamp(p0, 
p1,p0); }
 
-// CHECK: define [[FNATTRS]] <2 x i32> {{.*}}_overloads1
-// CHECK: call <2 x i32> @llvm.[[TARGET]].sclamp.v2i32
-int2 test_overloads1(int2 p0, float2 p1, uint p2) { return clamp(p0, p1, p2); }
-
-// CHECK: define [[FNATTRS]] [[FFNATTRS]] <2 x float> {{.*}}test_overloads2
-// CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> 
@llvm.[[TARGET]].nclamp.v2f32
-float2 test_overloads2(float2 p0, uint p1, int2 p2) { return clamp(p0, p1, 
p2); }
-
 // CHECK: define [[FNATTRS]] <3 x i32> {{.*}}test_overloads3
 // CHECK: call <3 x i32> @llvm.[[TARGET]].uclamp.v3i32
-uint3 test_overloads3(uint3 p0, int p1, float p2) { return clamp(p0, p1, p2); }
-
-// CHECK: define [[FNATTRS]] [[FFNATTRS]] <4 x double> {{.*}}test_overloads4
-// CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> 
@llvm.[[TARGET]].nclamp.v4f64
-double4 test_overloads4(double4 p0, float4 p1, int4 p2) { return clamp(p0, p1, 
p2); }
-
-// CHECK: define [[FNATTRS]] i32 {{.*}}test_overloads5
-// CHECK: call i32 @llvm.[[TARGET]].sclamp.i32(
-int test_overloads5(int p0, uint p1, double p2) { return clamp(p0, p1, p2); }
+uint3 test_overloads3(uint3 p0, uint p1, uint p2) { return clamp(p0, p1, p2); }

diff  --git a/clang/test/SemaHLSL/BuiltIns/clamp-errors-16bit.hlsl 
b/clang/test/SemaHLSL/BuiltIns/clamp-errors-16bit.hlsl
index 8846f78833e87..41c66a8631fad 100644
--- a/clang/test/SemaHLSL/BuiltIns/clamp-errors-16bit.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/clamp-errors-16bit.hlsl
@@ -1,12 +1,9 @@
 // RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1  | 
FileCheck %s -DTEST_TYPE=half
-// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1  | 
FileCheck %s -DTEST_TYPE=half3
 // RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1  | 
FileCheck %s -DTEST_TYPE=int16_t
-// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1  | 
FileCheck %s -DTEST_TYPE=int16_t3
 // RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1  | 
FileCheck %s -DTEST_TYPE=uint16_t
-// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1  | 
FileCheck %s -DTEST_TYPE=uint16_t3
 
 // check we error on 16 bit type if shader model is too old
 // CHECK: '-enable-16bit-types' option requires target HLSL Version >= 2018 
and shader model >= 6.2, but HLSL Version is 'hlsl202x' and shader model is 
'6.0'
-TEST_TYPE test_half_error(TEST_TYPE p0, int p1) {
+vector<TEST_TYPE,3> test_half_error(vector<TEST_TYPE,3> p0, TEST_TYPE p1) {
   return clamp(p0, p1, p1);
 }

diff  --git a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl
index c689c4cdadfce..71c16e9cf9ff2 100644
--- a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl
@@ -59,16 +59,14 @@ float2 test_clamp_builtin_vector_size_mismatch(float3 p0, 
float2 p1) {
   // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' 
must have the same type}}
 }
 
-// allowed by the overloads in hlsl_compat_overloads.h
-// support for this overload might be removed in a future version of hlsl
 float test_clamp_scalar_mismatch(float p0, half p1) {
   return clamp(p1, p0, p1);
+  // expected-error@-1 {{call to 'clamp' is ambiguous}}
 }
 
-// allowed by the overloads in hlsl_compat_overloads.h
-// support for this overload might be removed in a future version of hlsl
 float2 test_clamp_element_type_mismatch(half2 p0, float2 p1) {
   return clamp(p1, p0, p1);
+  // expected-error@-1 {{call to 'clamp' is ambiguous}}
 }
 
 float2 test_builtin_clamp_float2_splat(float p0, float2 p1) {


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to