Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/CodeGen/CGHLSLBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
68 changes: 68 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
26 changes: 26 additions & 0 deletions clang/test/CodeGenHLSL/builtins/ddx-fine-builtin.hlsl
Original file line number Diff line number Diff line change
@@ -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);
}
86 changes: 86 additions & 0 deletions clang/test/CodeGenHLSL/builtins/ddx-fine.hlsl
Original file line number Diff line number Diff line change
@@ -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);
}
26 changes: 26 additions & 0 deletions clang/test/CodeGenHLSL/builtins/ddy-fine-builtin.hlsl
Original file line number Diff line number Diff line change
@@ -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);
}
86 changes: 86 additions & 0 deletions clang/test/CodeGenHLSL/builtins/ddy-fine.hlsl
Original file line number Diff line number Diff line change
@@ -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);
}
22 changes: 22 additions & 0 deletions clang/test/SemaHLSL/BuiltIns/ddx-fine-errors.hlsl
Original file line number Diff line number Diff line change
@@ -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')}}
}
Loading