llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Alexander Johnston (Alexander-Johnston)

<details>
<summary>Changes</summary>

Implements the HLSL ddx_fine and ddy_fine intrinsics.
For the SPIRV backend the intrinsics are ensured to be unavailable in opencl 
(as they require fragment execution stage).

Closes https://github.com/llvm/llvm-project/issues/99098
Closes https://github.com/llvm/llvm-project/issues/99101

---

Patch is 39.46 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/168874.diff


25 Files Affected:

- (modified) clang/include/clang/Basic/Builtins.td (+12) 
- (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+18) 
- (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+2) 
- (modified) clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h (+68) 
- (modified) clang/lib/Sema/SemaHLSL.cpp (+3-1) 
- (added) clang/test/CodeGenHLSL/builtins/ddx-fine-builtin.hlsl (+26) 
- (added) clang/test/CodeGenHLSL/builtins/ddx-fine.hlsl (+86) 
- (added) clang/test/CodeGenHLSL/builtins/ddy-fine-builtin.hlsl (+26) 
- (added) clang/test/CodeGenHLSL/builtins/ddy-fine.hlsl (+86) 
- (added) clang/test/SemaHLSL/BuiltIns/ddx-fine-errors.hlsl (+22) 
- (added) clang/test/SemaHLSL/BuiltIns/ddy-fine-errors.hlsl (+22) 
- (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+2) 
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+2) 
- (modified) llvm/lib/Target/DirectX/DXIL.td (+18) 
- (modified) llvm/lib/Target/DirectX/DirectXTargetTransformInfo.cpp (+2) 
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+4) 
- (modified) llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp (+3-1) 
- (added) llvm/test/CodeGen/DirectX/ddx_fine-errors.ll (+29) 
- (added) llvm/test/CodeGen/DirectX/ddx_fine.ll (+40) 
- (added) llvm/test/CodeGen/DirectX/ddy_fine-errors.ll (+29) 
- (added) llvm/test/CodeGen/DirectX/ddy_fine.ll (+40) 
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/ddx_fine.ll (+47) 
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/ddy_fine.ll (+47) 
- (added) llvm/test/CodeGen/SPIRV/opencl/ddx_fine-error.ll (+12) 
- (added) llvm/test/CodeGen/SPIRV/opencl/ddy_fine-error.ll (+12) 


``````````diff
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 502382a069856..64de76a01f335 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5265,6 +5265,18 @@ def HLSLDdyCoarse : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLDdxFine : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_ddx_fine"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def HLSLDdyFine : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_ddy_fine"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 12d9a98915ce3..bfa9a53b7804e 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -942,6 +942,24 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
                                    ArrayRef<Value *>{Op0}, nullptr,
                                    "hlsl.ddy.coarse");
   }
+  case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
+    Value *Op0 = EmitScalarExpr(E->getArg(0));
+    if (!E->getArg(0)->getType()->hasFloatingRepresentation())
+      llvm_unreachable("ddx_fine operand must have a float representation");
+    Intrinsic::ID ID = CGM.getHLSLRuntime().getDdxFineIntrinsic();
+    return Builder.CreateIntrinsic(/*ReturnType=*/Op0->getType(), ID,
+                                   ArrayRef<Value *>{Op0}, nullptr,
+                                   "hlsl.ddx.fine");
+  }
+  case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
+    Value *Op0 = EmitScalarExpr(E->getArg(0));
+    if (!E->getArg(0)->getType()->hasFloatingRepresentation())
+      llvm_unreachable("ddy_fine operand must have a float representation");
+    Intrinsic::ID ID = CGM.getHLSLRuntime().getDdyFineIntrinsic();
+    return Builder.CreateIntrinsic(/*ReturnType=*/Op0->getType(), ID,
+                                   ArrayRef<Value *>{Op0}, nullptr,
+                                   "hlsl.ddy.fine");
+  }
   case Builtin::BI__builtin_get_spirv_spec_constant_bool:
   case Builtin::BI__builtin_get_spirv_spec_constant_short:
   case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index c883282a8d9c8..2ad39c91280a0 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -171,6 +171,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(GetDimensionsX, resource_getdimensions_x)
   GENERATE_HLSL_INTRINSIC_FUNCTION(DdxCoarse, ddx_coarse)
   GENERATE_HLSL_INTRINSIC_FUNCTION(DdyCoarse, ddy_coarse)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(DdxFine, ddx_fine)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(DdyFine, ddy_fine)
 
   
//===----------------------------------------------------------------------===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 38b95ee90736a..f58150ed61106 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -3014,5 +3014,73 @@ float3 ddy_coarse(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_coarse)
 float4 ddy_coarse(float4);
 
+//===----------------------------------------------------------------------===//
+// ddx_fine builtin
+//===----------------------------------------------------------------------===//
+
+/// \fn T ddx_fine(T value)
+/// \brief Computes a high precision partial derivative with respect to the
+/// screen-space x-coordinate.
+/// \param value The input value.
+///
+/// The return value is a floating point scalar or vector containing the high
+/// prevision partial derivative of the input value.
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+half ddx_fine(half);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+half2 ddx_fine(half2);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+half3 ddx_fine(half3);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+half4 ddx_fine(half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+float ddx_fine(float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+float2 ddx_fine(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+float3 ddx_fine(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
+float4 ddx_fine(float4);
+
+//===----------------------------------------------------------------------===//
+// ddy_fine builtin
+//===----------------------------------------------------------------------===//
+
+/// \fn T ddy_fine(T value)
+/// \brief Computes a high precision partial derivative with respect to the
+/// screen-space y-coordinate.
+/// \param value The input value.
+///
+/// The return value is a floating point scalar or vector containing the high
+/// prevision partial derivative of the input value.
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+half ddy_fine(half);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+half2 ddy_fine(half2);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+half3 ddy_fine(half3);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+half4 ddy_fine(half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+float ddy_fine(float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+float2 ddy_fine(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+float3 ddy_fine(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
+float4 ddy_fine(float4);
+
 } // namespace hlsl
 #endif //_HLSL_HLSL_ALIAS_INTRINSICS_H_
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index c5666941fd36a..cc2939314b0eb 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3211,7 +3211,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   case Builtin::BI__builtin_hlsl_elementwise_rsqrt:
   case Builtin::BI__builtin_hlsl_elementwise_frac:
   case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse:
-  case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
+  case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse:
+  case Builtin::BI__builtin_hlsl_elementwise_ddx_fine:
+  case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
     if (SemaRef.checkArgCount(TheCall, 1))
       return true;
     if (CheckAllArgTypesAreCorrect(&SemaRef, TheCall,
diff --git a/clang/test/CodeGenHLSL/builtins/ddx-fine-builtin.hlsl 
b/clang/test/CodeGenHLSL/builtins/ddx-fine-builtin.hlsl
new file mode 100644
index 0000000000000..69f7ab3c6ce62
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/ddx-fine-builtin.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
dxil-pc-shadermodel6.3-library %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
spirv-pc-vulkan-compute  %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK-SPIRV
+
+// CHECK-LABEL: half @_Z17test_f16_ddx_fineDh
+// CHECK: %hlsl.ddx.fine = call {{.*}} half @llvm.dx.ddx.fine.f16(half %{{.*}})
+// CHECK: ret half %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddx_fineDh
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} half @llvm.spv.ddx.fine.f16(half 
%{{.*}})
+// CHECK-SPIRV: ret half %hlsl.ddx.fine
+half test_f16_ddx_fine(half val) {
+    return __builtin_hlsl_elementwise_ddx_fine(val);
+}
+
+// CHECK-LABEL: float @_Z17test_f32_ddx_finef
+// CHECK: %hlsl.ddx.fine = call {{.*}} float @llvm.dx.ddx.fine.f32(float 
%{{.*}})
+// CHECK: ret float %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddx_finef
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} float 
@llvm.spv.ddx.fine.f32(float %{{.*}})
+// CHECK-SPIRV: ret float %hlsl.ddx.fine
+float test_f32_ddx_fine(float val) {
+    return __builtin_hlsl_elementwise_ddx_fine(val);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/ddx-fine.hlsl 
b/clang/test/CodeGenHLSL/builtins/ddx-fine.hlsl
new file mode 100644
index 0000000000000..2630260abcb43
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/ddx-fine.hlsl
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
dxil-pc-shadermodel6.3-library %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
spirv-pc-vulkan-compute  %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK-SPIRV
+
+// CHECK-LABEL: half @_Z17test_f16_ddx_fineDh
+// CHECK: %hlsl.ddx.fine = call {{.*}} half @llvm.dx.ddx.fine.f16(half %{{.*}})
+// CHECK: ret half %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddx_fineDh
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} half @llvm.spv.ddx.fine.f16(half 
%{{.*}})
+// CHECK-SPIRV: ret half %hlsl.ddx.fine
+half test_f16_ddx_fine(half val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: <2 x half> @_Z18test_f16_ddx_fine2Dv2_Dh
+// CHECK: %hlsl.ddx.fine = call {{.*}} <2 x half> @llvm.dx.ddx.fine.v2f16(<2 x 
half> %{{.*}})
+// CHECK: ret <2 x half> %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: <2 x half> @_Z18test_f16_ddx_fine2Dv2_Dh
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <2 x half> 
@llvm.spv.ddx.fine.v2f16(<2 x half> %{{.*}})
+// CHECK-SPIRV: ret <2 x half> %hlsl.ddx.fine
+half2 test_f16_ddx_fine2(half2 val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: <3 x half> @_Z18test_f16_ddx_fine3Dv3_Dh
+// CHECK: %hlsl.ddx.fine = call {{.*}} <3 x half> @llvm.dx.ddx.fine.v3f16(<3 x 
half> %{{.*}})
+// CHECK: ret <3 x half> %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: <3 x half> @_Z18test_f16_ddx_fine3Dv3_Dh
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <3 x half> 
@llvm.spv.ddx.fine.v3f16(<3 x half> %{{.*}})
+// CHECK-SPIRV: ret <3 x half> %hlsl.ddx.fine
+half3 test_f16_ddx_fine3(half3 val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: <4 x half> @_Z18test_f16_ddx_fine4Dv4_Dh
+// CHECK: %hlsl.ddx.fine = call {{.*}} <4 x half> @llvm.dx.ddx.fine.v4f16(<4 x 
half> %{{.*}})
+// CHECK: ret <4 x half> %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: <4 x half> @_Z18test_f16_ddx_fine4Dv4_Dh
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <4 x half> 
@llvm.spv.ddx.fine.v4f16(<4 x half> %{{.*}})
+// CHECK-SPIRV: ret <4 x half> %hlsl.ddx.fine
+half4 test_f16_ddx_fine4(half4 val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: float @_Z17test_f32_ddx_finef
+// CHECK: %hlsl.ddx.fine = call {{.*}} float @llvm.dx.ddx.fine.f32(float 
%{{.*}})
+// CHECK: ret float %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddx_finef
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} float 
@llvm.spv.ddx.fine.f32(float %{{.*}})
+// CHECK-SPIRV: ret float %hlsl.ddx.fine
+float test_f32_ddx_fine(float val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: <2 x float> @_Z18test_f32_ddx_fine2Dv2_f
+// CHECK: %hlsl.ddx.fine = call {{.*}} <2 x float> @llvm.dx.ddx.fine.v2f32(<2 
x float> %{{.*}})
+// CHECK: ret <2 x float> %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: <2 x float> @_Z18test_f32_ddx_fine2Dv2_f
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <2 x float> 
@llvm.spv.ddx.fine.v2f32(<2 x float> %{{.*}})
+// CHECK-SPIRV: ret <2 x float> %hlsl.ddx.fine
+float2 test_f32_ddx_fine2(float2 val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: <3 x float> @_Z18test_f32_ddx_fine3Dv3_f
+// CHECK: %hlsl.ddx.fine = call {{.*}} <3 x float> @llvm.dx.ddx.fine.v3f32(<3 
x float> %{{.*}})
+// CHECK: ret <3 x float> %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: <3 x float> @_Z18test_f32_ddx_fine3Dv3_f
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <3 x float> 
@llvm.spv.ddx.fine.v3f32(<3 x float> %{{.*}})
+// CHECK-SPIRV: ret <3 x float> %hlsl.ddx.fine
+float3 test_f32_ddx_fine3(float3 val) {
+    return ddx_fine(val);
+}
+
+// CHECK-LABEL: <4 x float> @_Z18test_f32_ddx_fine4Dv4_f
+// CHECK: %hlsl.ddx.fine = call {{.*}} <4 x float> @llvm.dx.ddx.fine.v4f32(<4 
x float> %{{.*}})
+// CHECK: ret <4 x float> %hlsl.ddx.fine
+// CHECK-LABEL-SPIRV: <4 x float> @_Z18test_f32_ddx_fine4Dv4_f
+// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <4 x float> 
@llvm.spv.ddx.fine.v4f32(<4 x float> %{{.*}})
+// CHECK-SPIRV: ret <4 x float> %hlsl.ddx.fine
+float4 test_f32_ddx_fine4(float4 val) {
+    return ddx_fine(val);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/ddy-fine-builtin.hlsl 
b/clang/test/CodeGenHLSL/builtins/ddy-fine-builtin.hlsl
new file mode 100644
index 0000000000000..00630721ceb66
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/ddy-fine-builtin.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
dxil-pc-shadermodel6.3-library %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
spirv-pc-vulkan-compute  %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK-SPIRV
+
+// CHECK-LABEL: half @_Z17test_f16_ddy_fineDh
+// CHECK: %hlsl.ddy.fine = call {{.*}} half @llvm.dx.ddy.fine.f16(half %{{.*}})
+// CHECK: ret half %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddy_fineDh
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} half @llvm.spv.ddy.fine.f16(half 
%{{.*}})
+// CHECK-SPIRV: ret half %hlsl.ddy.fine
+half test_f16_ddy_fine(half val) {
+    return __builtin_hlsl_elementwise_ddy_fine(val);
+}
+
+// CHECK-LABEL: float @_Z17test_f32_ddy_finef
+// CHECK: %hlsl.ddy.fine = call {{.*}} float @llvm.dx.ddy.fine.f32(float 
%{{.*}})
+// CHECK: ret float %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddy_finef
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} float 
@llvm.spv.ddy.fine.f32(float %{{.*}})
+// CHECK-SPIRV: ret float %hlsl.ddy.fine
+float test_f32_ddy_fine(float val) {
+    return __builtin_hlsl_elementwise_ddy_fine(val);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/ddy-fine.hlsl 
b/clang/test/CodeGenHLSL/builtins/ddy-fine.hlsl
new file mode 100644
index 0000000000000..7e32ee29e767d
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/ddy-fine.hlsl
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
dxil-pc-shadermodel6.3-library %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -finclude-default-header  -x hlsl  -triple 
spirv-pc-vulkan-compute  %s \
+// RUN:  -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK-SPIRV
+
+// CHECK-LABEL: half @_Z17test_f16_ddy_fineDh
+// CHECK: %hlsl.ddy.fine = call {{.*}} half @llvm.dx.ddy.fine.f16(half %{{.*}})
+// CHECK: ret half %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddy_fineDh
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} half @llvm.spv.ddy.fine.f16(half 
%{{.*}})
+// CHECK-SPIRV: ret half %hlsl.ddy.fine
+half test_f16_ddy_fine(half val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: <2 x half> @_Z18test_f16_ddy_fine2Dv2_Dh
+// CHECK: %hlsl.ddy.fine = call {{.*}} <2 x half> @llvm.dx.ddy.fine.v2f16(<2 x 
half> %{{.*}})
+// CHECK: ret <2 x half> %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: <2 x half> @_Z18test_f16_ddy_fine2Dv2_Dh
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <2 x half> 
@llvm.spv.ddy.fine.v2f16(<2 x half> %{{.*}})
+// CHECK-SPIRV: ret <2 x half> %hlsl.ddy.fine
+half2 test_f16_ddy_fine2(half2 val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: <3 x half> @_Z18test_f16_ddy_fine3Dv3_Dh
+// CHECK: %hlsl.ddy.fine = call {{.*}} <3 x half> @llvm.dx.ddy.fine.v3f16(<3 x 
half> %{{.*}})
+// CHECK: ret <3 x half> %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: <3 x half> @_Z18test_f16_ddy_fine3Dv3_Dh
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <3 x half> 
@llvm.spv.ddy.fine.v3f16(<3 x half> %{{.*}})
+// CHECK-SPIRV: ret <3 x half> %hlsl.ddy.fine
+half3 test_f16_ddy_fine3(half3 val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: <4 x half> @_Z18test_f16_ddy_fine4Dv4_Dh
+// CHECK: %hlsl.ddy.fine = call {{.*}} <4 x half> @llvm.dx.ddy.fine.v4f16(<4 x 
half> %{{.*}})
+// CHECK: ret <4 x half> %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: <4 x half> @_Z18test_f16_ddy_fine4Dv4_Dh
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <4 x half> 
@llvm.spv.ddy.fine.v4f16(<4 x half> %{{.*}})
+// CHECK-SPIRV: ret <4 x half> %hlsl.ddy.fine
+half4 test_f16_ddy_fine4(half4 val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: float @_Z17test_f32_ddy_finef
+// CHECK: %hlsl.ddy.fine = call {{.*}} float @llvm.dx.ddy.fine.f32(float 
%{{.*}})
+// CHECK: ret float %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddy_finef
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} float 
@llvm.spv.ddy.fine.f32(float %{{.*}})
+// CHECK-SPIRV: ret float %hlsl.ddy.fine
+float test_f32_ddy_fine(float val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: <2 x float> @_Z18test_f32_ddy_fine2Dv2_f
+// CHECK: %hlsl.ddy.fine = call {{.*}} <2 x float> @llvm.dx.ddy.fine.v2f32(<2 
x float> %{{.*}})
+// CHECK: ret <2 x float> %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: <2 x float> @_Z18test_f32_ddy_fine2Dv2_f
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <2 x float> 
@llvm.spv.ddy.fine.v2f32(<2 x float> %{{.*}})
+// CHECK-SPIRV: ret <2 x float> %hlsl.ddy.fine
+float2 test_f32_ddy_fine2(float2 val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: <3 x float> @_Z18test_f32_ddy_fine3Dv3_f
+// CHECK: %hlsl.ddy.fine = call {{.*}} <3 x float> @llvm.dx.ddy.fine.v3f32(<3 
x float> %{{.*}})
+// CHECK: ret <3 x float> %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: <3 x float> @_Z18test_f32_ddy_fine3Dv3_f
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <3 x float> 
@llvm.spv.ddy.fine.v3f32(<3 x float> %{{.*}})
+// CHECK-SPIRV: ret <3 x float> %hlsl.ddy.fine
+float3 test_f32_ddy_fine3(float3 val) {
+    return ddy_fine(val);
+}
+
+// CHECK-LABEL: <4 x float> @_Z18test_f32_ddy_fine4Dv4_f
+// CHECK: %hlsl.ddy.fine = call {{.*}} <4 x float> @llvm.dx.ddy.fine.v4f32(<4 
x float> %{{.*}})
+// CHECK: ret <4 x float> %hlsl.ddy.fine
+// CHECK-LABEL-SPIRV: <4 x float> @_Z18test_f32_ddy_fine4Dv4_f
+// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <4 x float> 
@llvm.spv.ddy.fine.v4f32(<4 x float> %{{.*}})
+// CHECK-SPIRV: ret <4 x float> %hlsl.ddy.fine
+float4 test_f32_ddy_fine4(float4 val) {
+    return ddy_fine(val);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/ddx-fine-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/ddx-fine-errors.hlsl
new file mode 100644
index 0000000000000..71196943c322a
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/ddx-fine-errors.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library %s 
-fnative-half-type -verify
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-library %s 
-fnative-half-type -verify
+
+float no_arg() {
+  return __builtin_hlsl_elementwise_ddx_fine();
+  // expected-error@-1 {{too few arguments to function call, expected 1, have 
0}}
+}
+
+float too_many_args(float val) {
+  return __builtin_hlsl_elementwise_ddx_fine(val, val);
+  // expected-error@-1 {{too many arguments to function call, expected 1, have 
2}}
+}
+
+float test_integer_scalar_input(int val) {
+  return __builtin_hlsl_elementwise_ddx_fine(val);
+  // expected-error@-1 {{1st argument must be a scalar or vector of 16 or 32 
bit floating-point types (was 'int')}}
+}
+
+double test_double_scalar_input(double val) {
+  return __builtin_hlsl_elementwise_ddx_fine(val);
+  // expected-error@-1 {{1st argument must be a scalar or vector of 16 or 32 
bit floating-point types (was 'double')}}
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/ddy-fine-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/ddy-fine-errors.hlsl
new file mode 100644
index 0000000000000..e17d5f36832b2
--- /dev/null...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/168874
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to