[clang] [HLSL] Add matrix support to atan2 (PR #194984)

via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 29 17:05:02 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: joaosaffran

<details>
<summary>Changes</summary>

This patch updates atan2 hlsl intrinsic overloads to support matrix types.
Fix: https://github.com/llvm/llvm-project/issues/184476

---
Full diff: https://github.com/llvm/llvm-project/pull/194984.diff


4 Files Affected:

- (modified) clang/lib/Headers/hlsl/hlsl_compat_overloads.h (+36) 
- (modified) clang/lib/Sema/SemaHLSL.cpp (+8-6) 
- (modified) clang/test/CodeGenHLSL/builtins/atan2-overloads.hlsl (+45) 
- (modified) clang/test/CodeGenHLSL/builtins/atan2.hlsl (+27) 


``````````diff
diff --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index ee243abef6a41..0c4963b495b51 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -230,6 +230,40 @@ namespace hlsl {
     return fn((float4)V1, (float4)V2, (float4)V3);                             \
   }
 
+#define _DXC_COMPAT_BINARY_DOUBLE_MATRIX_OVERLOADS(fn)                         \
+  template <uint R, uint C>                                                    \
+  constexpr matrix<float, R, C> fn(matrix<double, R, C> y,                     \
+                                   matrix<double, R, C> x) {                   \
+    return fn((matrix<float, R, C>)y, (matrix<float, R, C>)x);                 \
+  }
+
+#define _DXC_COMPAT_BINARY_INTEGER_MATRIX_OVERLOADS(fn)                        \
+  template <uint R, uint C>                                                    \
+  _DXC_DEPRECATED_INT_FN(fn)                                                   \
+  constexpr matrix<float, R, C> fn(matrix<int, R, C> y, matrix<int, R, C> x) { \
+    return fn((matrix<float, R, C>)y, (matrix<float, R, C>)x);                 \
+  }                                                                            \
+                                                                               \
+  template <uint R, uint C>                                                    \
+  _DXC_DEPRECATED_INT_FN(fn)                                                   \
+  constexpr matrix<float, R, C> fn(matrix<uint, R, C> y,                       \
+                                   matrix<uint, R, C> x) {                     \
+    return fn((matrix<float, R, C>)y, (matrix<float, R, C>)x);                 \
+  }                                                                            \
+                                                                               \
+  template <uint R, uint C>                                                    \
+  _DXC_DEPRECATED_INT_FN(fn)                                                   \
+  constexpr matrix<float, R, C> fn(matrix<int64_t, R, C> y,                    \
+                                   matrix<int64_t, R, C> x) {                  \
+    return fn((matrix<float, R, C>)y, (matrix<float, R, C>)x);                 \
+  }                                                                            \
+                                                                               \
+  template <uint R, uint C>                                                    \
+  _DXC_DEPRECATED_INT_FN(fn)                                                   \
+  constexpr matrix<float, R, C> fn(matrix<uint64_t, R, C> y,                   \
+                                   matrix<uint64_t, R, C> x) {                 \
+    return fn((matrix<float, R, C>)y, (matrix<float, R, C>)x);                 \
+  }
 //===----------------------------------------------------------------------===//
 // acos builtins overloads
 //===----------------------------------------------------------------------===//
@@ -257,6 +291,8 @@ _DXC_COMPAT_UNARY_INTEGER_OVERLOADS(atan)
 
 _DXC_COMPAT_BINARY_DOUBLE_OVERLOADS(atan2)
 _DXC_COMPAT_BINARY_INTEGER_OVERLOADS(atan2)
+_DXC_COMPAT_BINARY_DOUBLE_MATRIX_OVERLOADS(atan2)
+_DXC_COMPAT_BINARY_INTEGER_MATRIX_OVERLOADS(atan2)
 
 //===----------------------------------------------------------------------===//
 // ceil builtins overloads
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index aba1c5072a5fc..368a54b44c2d5 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3232,14 +3232,16 @@ static bool CheckFloatRepresentation(Sema *S, SourceLocation Loc,
 static bool CheckFloatOrHalfRepresentation(Sema *S, SourceLocation Loc,
                                            int ArgOrdinal,
                                            clang::QualType PassedType) {
-  clang::QualType BaseType =
-      PassedType->isVectorType()
-          ? PassedType->castAs<clang::VectorType>()->getElementType()
-          : PassedType;
+  clang::QualType BaseType = PassedType;
+  if (PassedType->isVectorType())
+    BaseType = PassedType->castAs<clang::VectorType>()->getElementType();
+  else if (PassedType->isMatrixType())
+    BaseType = PassedType->castAs<clang::MatrixType>()->getElementType();
+
   if (!BaseType->isHalfType() && !BaseType->isFloat32Type())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
-           << ArgOrdinal << /* scalar or vector of */ 5 << /* no int */ 0
-           << /* half or float */ 2 << PassedType;
+           << ArgOrdinal << /* scalar, vector or matrix of */ 5
+           << /* no int */ 0 << /* half or float */ 2 << PassedType;
   return false;
 }
 
diff --git a/clang/test/CodeGenHLSL/builtins/atan2-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/atan2-overloads.hlsl
index 85ff75110a78e..6ecad28850b00 100644
--- a/clang/test/CodeGenHLSL/builtins/atan2-overloads.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/atan2-overloads.hlsl
@@ -38,6 +38,15 @@ float4 test_atan2_double4 (double4 p0, double4 p1) {
   return atan2(p0, p1);
 }
 
+// CHECK: define [[FNATTRS]] <16 x float> @_Z20test_atan2_double4x4u11matrix_typeILj4ELj4EdES_(
+// CHECK:    [[CONVI:%.*]] = fptrunc {{.*}} <16 x double> %{{.*}} to <16 x float>
+// CHECK:    [[CONV1I:%.*]] = fptrunc {{.*}} <16 x double> %{{.*}} to <16 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <16 x float> @llvm.atan2.v16f32(<16 x float> [[CONVI]], <16 x float> [[CONV1I]])
+// CHECK:    ret <16 x float> [[V5]]
+float4x4 test_atan2_double4x4 (double4x4 p0, double4x4 p1) {
+  return atan2(p0, p1);
+}
+
 // CHECK: define [[FNATTRS]] float @_Z14test_atan2_intii(
 // CHECK:    [[CONVI:%.*]] = sitofp i32 %{{.*}} to float
 // CHECK:    [[CONV1I:%.*]] = sitofp i32 %{{.*}} to float
@@ -181,3 +190,39 @@ float3 test_atan2_uint64_t3 (uint64_t3 p0, uint64_t3 p1) {
 float4 test_atan2_uint64_t4 (uint64_t4 p0, uint64_t4 p1) {
   return atan2(p0, p1);
 }
+
+// CHECK: define [[FNATTRS]] <16 x float> @_Z19test_atan2_int_t4x4u11matrix_typeILj4ELj4EiES_(
+// CHECK:    [[CONVI:%.*]] = sitofp <16 x i32> %{{.*}} to <16 x float>
+// CHECK:    [[CONV1I:%.*]] = sitofp <16 x i32> %{{.*}} to <16 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <16 x float> @llvm.atan2.v16f32(<16 x float> [[CONVI]], <16 x float> [[CONV1I]])
+// CHECK:    ret <16 x float> [[V5]]
+float4x4 test_atan2_int_t4x4 (int4x4 p0, int4x4 p1) {
+  return atan2(p0, p1);
+}
+
+// CHECK: define [[FNATTRS]] <16 x float> @_Z20test_atan2_uint_t4x4u11matrix_typeILj4ELj4EjES_(
+// CHECK:    [[CONVI:%.*]] = uitofp <16 x i32> %{{.*}} to <16 x float>
+// CHECK:    [[CONV1I:%.*]] = uitofp <16 x i32> %{{.*}} to <16 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <16 x float> @llvm.atan2.v16f32(<16 x float> [[CONVI]], <16 x float> [[CONV1I]])
+// CHECK:    ret <16 x float> [[V5]]
+float4x4 test_atan2_uint_t4x4 (uint4x4 p0, uint4x4 p1) {
+  return atan2(p0, p1);
+}
+
+// CHECK: define [[FNATTRS]] <16 x float> @_Z21test_atan2_int64_t4x4u11matrix_typeILj4ELj4ElES_(
+// CHECK:    [[CONVI:%.*]] = sitofp <16 x i64> %{{.*}} to <16 x float>
+// CHECK:    [[CONV1I:%.*]] = sitofp <16 x i64> %{{.*}} to <16 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <16 x float> @llvm.atan2.v16f32(<16 x float> [[CONVI]], <16 x float> [[CONV1I]])
+// CHECK:    ret <16 x float> [[V5]]
+float4x4 test_atan2_int64_t4x4 (int64_t4x4 p0, int64_t4x4 p1) {
+  return atan2(p0, p1);
+}
+
+// CHECK: define [[FNATTRS]] <16 x float> @_Z22test_atan2_uint64_t4x4u11matrix_typeILj4ELj4EmES_(
+// CHECK:    [[CONVI:%.*]] = uitofp <16 x i64> %{{.*}} to <16 x float>
+// CHECK:    [[CONV1I:%.*]] = uitofp <16 x i64> %{{.*}} to <16 x float>
+// CHECK:    [[V5:%.*]] = call {{.*}} <16 x float> @llvm.atan2.v16f32(<16 x float> [[CONVI]], <16 x float> [[CONV1I]])
+// CHECK:    ret <16 x float> [[V5]]
+float4x4 test_atan2_uint64_t4x4 (uint64_t4x4 p0, uint64_t4x4 p1) {
+  return atan2(p0, p1);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/atan2.hlsl b/clang/test/CodeGenHLSL/builtins/atan2.hlsl
index 512b44a5780db..986ddc75b4f8e 100644
--- a/clang/test/CodeGenHLSL/builtins/atan2.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/atan2.hlsl
@@ -34,6 +34,20 @@ half4 test_atan2_half4 (half4 p0, half4 p1) {
   return atan2(p0, p1);
 }
 
+// CHECK-LABEL: test_atan2_half4x4
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <16 x half> @llvm.atan2.v16f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <16 x float> @llvm.atan2.v16f32
+half4x4 test_atan2_half4x4 (half4x4 p0, half4x4 p1) {
+  return atan2(p0, p1);
+}
+
+// CHECK-LABEL: test_atan2_half2x3
+// NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <6 x half> @llvm.atan2.v6f16
+// NO_HALF: call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.atan2.v6f32
+half2x3 test_atan2_half2x3 (half2x3 p0, half2x3 p1) {
+  return atan2(p0, p1);
+}
+
 // CHECK-LABEL: test_atan2_float
 // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.atan2.f32
 float test_atan2_float (float p0, float p1) {
@@ -57,3 +71,16 @@ float3 test_atan2_float3 (float3 p0, float3 p1) {
 float4 test_atan2_float4 (float4 p0, float4 p1) {
   return atan2(p0, p1);
 }
+
+// CHECK-LABEL: test_atan2_float4x4
+// CHECK:  call reassoc nnan ninf nsz arcp afn <16 x float> @llvm.atan2.v16f32
+float4x4 test_atan2_float4x4 (float4x4 p0, float4x4 p1) {
+  return atan2(p0, p1);
+}
+
+
+// CHECK-LABEL: test_atan2_float2x3
+// CHECK:  call reassoc nnan ninf nsz arcp afn <6 x float> @llvm.atan2.v6f32
+float2x3 test_atan2_float2x3 (float2x3 p0, float2x3 p1) {
+  return atan2(p0, p1);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/194984


More information about the cfe-commits mailing list