Skip to content

Commit 7d46602

Browse files
[HLSL] Implement ddx/ddy_fine intrinsics
Implements the HLSL ddx_fine and ddy_fine intrinsics together as the implementations are nearly identical.
1 parent 76f1949 commit 7d46602

File tree

25 files changed

+658
-2
lines changed

25 files changed

+658
-2
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5265,6 +5265,18 @@ def HLSLDdyCoarse : LangBuiltin<"HLSL_LANG"> {
52655265
let Prototype = "void(...)";
52665266
}
52675267

5268+
def HLSLDdxFine : LangBuiltin<"HLSL_LANG"> {
5269+
let Spellings = ["__builtin_hlsl_elementwise_ddx_fine"];
5270+
let Attributes = [NoThrow, Const, CustomTypeChecking];
5271+
let Prototype = "void(...)";
5272+
}
5273+
5274+
def HLSLDdyFine : LangBuiltin<"HLSL_LANG"> {
5275+
let Spellings = ["__builtin_hlsl_elementwise_ddy_fine"];
5276+
let Attributes = [NoThrow, Const, CustomTypeChecking];
5277+
let Prototype = "void(...)";
5278+
}
5279+
52685280
// Builtins for XRay.
52695281
def XRayCustomEvent : Builtin {
52705282
let Spellings = ["__xray_customevent"];

clang/lib/CodeGen/CGHLSLBuiltins.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,24 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
942942
ArrayRef<Value *>{Op0}, nullptr,
943943
"hlsl.ddy.coarse");
944944
}
945+
case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
946+
Value *Op0 = EmitScalarExpr(E->getArg(0));
947+
if (!E->getArg(0)->getType()->hasFloatingRepresentation())
948+
llvm_unreachable("ddx_fine operand must have a float representation");
949+
Intrinsic::ID ID = CGM.getHLSLRuntime().getDdxFineIntrinsic();
950+
return Builder.CreateIntrinsic(/*ReturnType=*/Op0->getType(), ID,
951+
ArrayRef<Value *>{Op0}, nullptr,
952+
"hlsl.ddx.fine");
953+
}
954+
case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
955+
Value *Op0 = EmitScalarExpr(E->getArg(0));
956+
if (!E->getArg(0)->getType()->hasFloatingRepresentation())
957+
llvm_unreachable("ddy_fine operand must have a float representation");
958+
Intrinsic::ID ID = CGM.getHLSLRuntime().getDdyFineIntrinsic();
959+
return Builder.CreateIntrinsic(/*ReturnType=*/Op0->getType(), ID,
960+
ArrayRef<Value *>{Op0}, nullptr,
961+
"hlsl.ddy.fine");
962+
}
945963
case Builtin::BI__builtin_get_spirv_spec_constant_bool:
946964
case Builtin::BI__builtin_get_spirv_spec_constant_short:
947965
case Builtin::BI__builtin_get_spirv_spec_constant_ushort:

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ class CGHLSLRuntime {
171171
GENERATE_HLSL_INTRINSIC_FUNCTION(GetDimensionsX, resource_getdimensions_x)
172172
GENERATE_HLSL_INTRINSIC_FUNCTION(DdxCoarse, ddx_coarse)
173173
GENERATE_HLSL_INTRINSIC_FUNCTION(DdyCoarse, ddy_coarse)
174+
GENERATE_HLSL_INTRINSIC_FUNCTION(DdxFine, ddx_fine)
175+
GENERATE_HLSL_INTRINSIC_FUNCTION(DdyFine, ddy_fine)
174176

175177
//===----------------------------------------------------------------------===//
176178
// End of reserved area for HLSL intrinsic getters.

clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,5 +3014,73 @@ float3 ddy_coarse(float3);
30143014
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_coarse)
30153015
float4 ddy_coarse(float4);
30163016

3017+
//===----------------------------------------------------------------------===//
3018+
// ddx_fine builtin
3019+
//===----------------------------------------------------------------------===//
3020+
3021+
/// \fn T ddx_fine(T value)
3022+
/// \brief Computes a high precision partial derivative with respect to the
3023+
/// screen-space x-coordinate.
3024+
/// \param value The input value.
3025+
///
3026+
/// The return value is a floating point scalar or vector containing the high
3027+
/// prevision partial derivative of the input value.
3028+
3029+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3030+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3031+
half ddx_fine(half);
3032+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3033+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3034+
half2 ddx_fine(half2);
3035+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3036+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3037+
half3 ddx_fine(half3);
3038+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3039+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3040+
half4 ddx_fine(half4);
3041+
3042+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3043+
float ddx_fine(float);
3044+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3045+
float2 ddx_fine(float2);
3046+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3047+
float3 ddx_fine(float3);
3048+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddx_fine)
3049+
float4 ddx_fine(float4);
3050+
3051+
//===----------------------------------------------------------------------===//
3052+
// ddy_fine builtin
3053+
//===----------------------------------------------------------------------===//
3054+
3055+
/// \fn T ddy_fine(T value)
3056+
/// \brief Computes a high precision partial derivative with respect to the
3057+
/// screen-space y-coordinate.
3058+
/// \param value The input value.
3059+
///
3060+
/// The return value is a floating point scalar or vector containing the high
3061+
/// prevision partial derivative of the input value.
3062+
3063+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3064+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3065+
half ddy_fine(half);
3066+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3067+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3068+
half2 ddy_fine(half2);
3069+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3070+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3071+
half3 ddy_fine(half3);
3072+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
3073+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3074+
half4 ddy_fine(half4);
3075+
3076+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3077+
float ddy_fine(float);
3078+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3079+
float2 ddy_fine(float2);
3080+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3081+
float3 ddy_fine(float3);
3082+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_ddy_fine)
3083+
float4 ddy_fine(float4);
3084+
30173085
} // namespace hlsl
30183086
#endif //_HLSL_HLSL_ALIAS_INTRINSICS_H_

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3211,7 +3211,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
32113211
case Builtin::BI__builtin_hlsl_elementwise_rsqrt:
32123212
case Builtin::BI__builtin_hlsl_elementwise_frac:
32133213
case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse:
3214-
case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
3214+
case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse:
3215+
case Builtin::BI__builtin_hlsl_elementwise_ddx_fine:
3216+
case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
32153217
if (SemaRef.checkArgCount(TheCall, 1))
32163218
return true;
32173219
if (CheckAllArgTypesAreCorrect(&SemaRef, TheCall,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
2+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
3+
// RUN: FileCheck %s --check-prefixes=CHECK
4+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \
5+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
6+
// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV
7+
8+
// CHECK-LABEL: half @_Z17test_f16_ddx_fineDh
9+
// CHECK: %hlsl.ddx.fine = call {{.*}} half @llvm.dx.ddx.fine.f16(half %{{.*}})
10+
// CHECK: ret half %hlsl.ddx.fine
11+
// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddx_fineDh
12+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} half @llvm.spv.ddx.fine.f16(half %{{.*}})
13+
// CHECK-SPIRV: ret half %hlsl.ddx.fine
14+
half test_f16_ddx_fine(half val) {
15+
return __builtin_hlsl_elementwise_ddx_fine(val);
16+
}
17+
18+
// CHECK-LABEL: float @_Z17test_f32_ddx_finef
19+
// CHECK: %hlsl.ddx.fine = call {{.*}} float @llvm.dx.ddx.fine.f32(float %{{.*}})
20+
// CHECK: ret float %hlsl.ddx.fine
21+
// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddx_finef
22+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} float @llvm.spv.ddx.fine.f32(float %{{.*}})
23+
// CHECK-SPIRV: ret float %hlsl.ddx.fine
24+
float test_f32_ddx_fine(float val) {
25+
return __builtin_hlsl_elementwise_ddx_fine(val);
26+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
2+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
3+
// RUN: FileCheck %s --check-prefixes=CHECK
4+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \
5+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
6+
// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV
7+
8+
// CHECK-LABEL: half @_Z17test_f16_ddx_fineDh
9+
// CHECK: %hlsl.ddx.fine = call {{.*}} half @llvm.dx.ddx.fine.f16(half %{{.*}})
10+
// CHECK: ret half %hlsl.ddx.fine
11+
// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddx_fineDh
12+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} half @llvm.spv.ddx.fine.f16(half %{{.*}})
13+
// CHECK-SPIRV: ret half %hlsl.ddx.fine
14+
half test_f16_ddx_fine(half val) {
15+
return ddx_fine(val);
16+
}
17+
18+
// CHECK-LABEL: <2 x half> @_Z18test_f16_ddx_fine2Dv2_Dh
19+
// CHECK: %hlsl.ddx.fine = call {{.*}} <2 x half> @llvm.dx.ddx.fine.v2f16(<2 x half> %{{.*}})
20+
// CHECK: ret <2 x half> %hlsl.ddx.fine
21+
// CHECK-LABEL-SPIRV: <2 x half> @_Z18test_f16_ddx_fine2Dv2_Dh
22+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <2 x half> @llvm.spv.ddx.fine.v2f16(<2 x half> %{{.*}})
23+
// CHECK-SPIRV: ret <2 x half> %hlsl.ddx.fine
24+
half2 test_f16_ddx_fine2(half2 val) {
25+
return ddx_fine(val);
26+
}
27+
28+
// CHECK-LABEL: <3 x half> @_Z18test_f16_ddx_fine3Dv3_Dh
29+
// CHECK: %hlsl.ddx.fine = call {{.*}} <3 x half> @llvm.dx.ddx.fine.v3f16(<3 x half> %{{.*}})
30+
// CHECK: ret <3 x half> %hlsl.ddx.fine
31+
// CHECK-LABEL-SPIRV: <3 x half> @_Z18test_f16_ddx_fine3Dv3_Dh
32+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <3 x half> @llvm.spv.ddx.fine.v3f16(<3 x half> %{{.*}})
33+
// CHECK-SPIRV: ret <3 x half> %hlsl.ddx.fine
34+
half3 test_f16_ddx_fine3(half3 val) {
35+
return ddx_fine(val);
36+
}
37+
38+
// CHECK-LABEL: <4 x half> @_Z18test_f16_ddx_fine4Dv4_Dh
39+
// CHECK: %hlsl.ddx.fine = call {{.*}} <4 x half> @llvm.dx.ddx.fine.v4f16(<4 x half> %{{.*}})
40+
// CHECK: ret <4 x half> %hlsl.ddx.fine
41+
// CHECK-LABEL-SPIRV: <4 x half> @_Z18test_f16_ddx_fine4Dv4_Dh
42+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <4 x half> @llvm.spv.ddx.fine.v4f16(<4 x half> %{{.*}})
43+
// CHECK-SPIRV: ret <4 x half> %hlsl.ddx.fine
44+
half4 test_f16_ddx_fine4(half4 val) {
45+
return ddx_fine(val);
46+
}
47+
48+
// CHECK-LABEL: float @_Z17test_f32_ddx_finef
49+
// CHECK: %hlsl.ddx.fine = call {{.*}} float @llvm.dx.ddx.fine.f32(float %{{.*}})
50+
// CHECK: ret float %hlsl.ddx.fine
51+
// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddx_finef
52+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} float @llvm.spv.ddx.fine.f32(float %{{.*}})
53+
// CHECK-SPIRV: ret float %hlsl.ddx.fine
54+
float test_f32_ddx_fine(float val) {
55+
return ddx_fine(val);
56+
}
57+
58+
// CHECK-LABEL: <2 x float> @_Z18test_f32_ddx_fine2Dv2_f
59+
// CHECK: %hlsl.ddx.fine = call {{.*}} <2 x float> @llvm.dx.ddx.fine.v2f32(<2 x float> %{{.*}})
60+
// CHECK: ret <2 x float> %hlsl.ddx.fine
61+
// CHECK-LABEL-SPIRV: <2 x float> @_Z18test_f32_ddx_fine2Dv2_f
62+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <2 x float> @llvm.spv.ddx.fine.v2f32(<2 x float> %{{.*}})
63+
// CHECK-SPIRV: ret <2 x float> %hlsl.ddx.fine
64+
float2 test_f32_ddx_fine2(float2 val) {
65+
return ddx_fine(val);
66+
}
67+
68+
// CHECK-LABEL: <3 x float> @_Z18test_f32_ddx_fine3Dv3_f
69+
// CHECK: %hlsl.ddx.fine = call {{.*}} <3 x float> @llvm.dx.ddx.fine.v3f32(<3 x float> %{{.*}})
70+
// CHECK: ret <3 x float> %hlsl.ddx.fine
71+
// CHECK-LABEL-SPIRV: <3 x float> @_Z18test_f32_ddx_fine3Dv3_f
72+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <3 x float> @llvm.spv.ddx.fine.v3f32(<3 x float> %{{.*}})
73+
// CHECK-SPIRV: ret <3 x float> %hlsl.ddx.fine
74+
float3 test_f32_ddx_fine3(float3 val) {
75+
return ddx_fine(val);
76+
}
77+
78+
// CHECK-LABEL: <4 x float> @_Z18test_f32_ddx_fine4Dv4_f
79+
// CHECK: %hlsl.ddx.fine = call {{.*}} <4 x float> @llvm.dx.ddx.fine.v4f32(<4 x float> %{{.*}})
80+
// CHECK: ret <4 x float> %hlsl.ddx.fine
81+
// CHECK-LABEL-SPIRV: <4 x float> @_Z18test_f32_ddx_fine4Dv4_f
82+
// CHECK-SPIRV: %hlsl.ddx.fine = call {{.*}} <4 x float> @llvm.spv.ddx.fine.v4f32(<4 x float> %{{.*}})
83+
// CHECK-SPIRV: ret <4 x float> %hlsl.ddx.fine
84+
float4 test_f32_ddx_fine4(float4 val) {
85+
return ddx_fine(val);
86+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
2+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
3+
// RUN: FileCheck %s --check-prefixes=CHECK
4+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \
5+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
6+
// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV
7+
8+
// CHECK-LABEL: half @_Z17test_f16_ddy_fineDh
9+
// CHECK: %hlsl.ddy.fine = call {{.*}} half @llvm.dx.ddy.fine.f16(half %{{.*}})
10+
// CHECK: ret half %hlsl.ddy.fine
11+
// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddy_fineDh
12+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} half @llvm.spv.ddy.fine.f16(half %{{.*}})
13+
// CHECK-SPIRV: ret half %hlsl.ddy.fine
14+
half test_f16_ddy_fine(half val) {
15+
return __builtin_hlsl_elementwise_ddy_fine(val);
16+
}
17+
18+
// CHECK-LABEL: float @_Z17test_f32_ddy_finef
19+
// CHECK: %hlsl.ddy.fine = call {{.*}} float @llvm.dx.ddy.fine.f32(float %{{.*}})
20+
// CHECK: ret float %hlsl.ddy.fine
21+
// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddy_finef
22+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} float @llvm.spv.ddy.fine.f32(float %{{.*}})
23+
// CHECK-SPIRV: ret float %hlsl.ddy.fine
24+
float test_f32_ddy_fine(float val) {
25+
return __builtin_hlsl_elementwise_ddy_fine(val);
26+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
2+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
3+
// RUN: FileCheck %s --check-prefixes=CHECK
4+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \
5+
// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \
6+
// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV
7+
8+
// CHECK-LABEL: half @_Z17test_f16_ddy_fineDh
9+
// CHECK: %hlsl.ddy.fine = call {{.*}} half @llvm.dx.ddy.fine.f16(half %{{.*}})
10+
// CHECK: ret half %hlsl.ddy.fine
11+
// CHECK-LABEL-SPIRV: half @_Z17test_f16_ddy_fineDh
12+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} half @llvm.spv.ddy.fine.f16(half %{{.*}})
13+
// CHECK-SPIRV: ret half %hlsl.ddy.fine
14+
half test_f16_ddy_fine(half val) {
15+
return ddy_fine(val);
16+
}
17+
18+
// CHECK-LABEL: <2 x half> @_Z18test_f16_ddy_fine2Dv2_Dh
19+
// CHECK: %hlsl.ddy.fine = call {{.*}} <2 x half> @llvm.dx.ddy.fine.v2f16(<2 x half> %{{.*}})
20+
// CHECK: ret <2 x half> %hlsl.ddy.fine
21+
// CHECK-LABEL-SPIRV: <2 x half> @_Z18test_f16_ddy_fine2Dv2_Dh
22+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <2 x half> @llvm.spv.ddy.fine.v2f16(<2 x half> %{{.*}})
23+
// CHECK-SPIRV: ret <2 x half> %hlsl.ddy.fine
24+
half2 test_f16_ddy_fine2(half2 val) {
25+
return ddy_fine(val);
26+
}
27+
28+
// CHECK-LABEL: <3 x half> @_Z18test_f16_ddy_fine3Dv3_Dh
29+
// CHECK: %hlsl.ddy.fine = call {{.*}} <3 x half> @llvm.dx.ddy.fine.v3f16(<3 x half> %{{.*}})
30+
// CHECK: ret <3 x half> %hlsl.ddy.fine
31+
// CHECK-LABEL-SPIRV: <3 x half> @_Z18test_f16_ddy_fine3Dv3_Dh
32+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <3 x half> @llvm.spv.ddy.fine.v3f16(<3 x half> %{{.*}})
33+
// CHECK-SPIRV: ret <3 x half> %hlsl.ddy.fine
34+
half3 test_f16_ddy_fine3(half3 val) {
35+
return ddy_fine(val);
36+
}
37+
38+
// CHECK-LABEL: <4 x half> @_Z18test_f16_ddy_fine4Dv4_Dh
39+
// CHECK: %hlsl.ddy.fine = call {{.*}} <4 x half> @llvm.dx.ddy.fine.v4f16(<4 x half> %{{.*}})
40+
// CHECK: ret <4 x half> %hlsl.ddy.fine
41+
// CHECK-LABEL-SPIRV: <4 x half> @_Z18test_f16_ddy_fine4Dv4_Dh
42+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <4 x half> @llvm.spv.ddy.fine.v4f16(<4 x half> %{{.*}})
43+
// CHECK-SPIRV: ret <4 x half> %hlsl.ddy.fine
44+
half4 test_f16_ddy_fine4(half4 val) {
45+
return ddy_fine(val);
46+
}
47+
48+
// CHECK-LABEL: float @_Z17test_f32_ddy_finef
49+
// CHECK: %hlsl.ddy.fine = call {{.*}} float @llvm.dx.ddy.fine.f32(float %{{.*}})
50+
// CHECK: ret float %hlsl.ddy.fine
51+
// CHECK-LABEL-SPIRV: float @_Z17test_f32_ddy_finef
52+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} float @llvm.spv.ddy.fine.f32(float %{{.*}})
53+
// CHECK-SPIRV: ret float %hlsl.ddy.fine
54+
float test_f32_ddy_fine(float val) {
55+
return ddy_fine(val);
56+
}
57+
58+
// CHECK-LABEL: <2 x float> @_Z18test_f32_ddy_fine2Dv2_f
59+
// CHECK: %hlsl.ddy.fine = call {{.*}} <2 x float> @llvm.dx.ddy.fine.v2f32(<2 x float> %{{.*}})
60+
// CHECK: ret <2 x float> %hlsl.ddy.fine
61+
// CHECK-LABEL-SPIRV: <2 x float> @_Z18test_f32_ddy_fine2Dv2_f
62+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <2 x float> @llvm.spv.ddy.fine.v2f32(<2 x float> %{{.*}})
63+
// CHECK-SPIRV: ret <2 x float> %hlsl.ddy.fine
64+
float2 test_f32_ddy_fine2(float2 val) {
65+
return ddy_fine(val);
66+
}
67+
68+
// CHECK-LABEL: <3 x float> @_Z18test_f32_ddy_fine3Dv3_f
69+
// CHECK: %hlsl.ddy.fine = call {{.*}} <3 x float> @llvm.dx.ddy.fine.v3f32(<3 x float> %{{.*}})
70+
// CHECK: ret <3 x float> %hlsl.ddy.fine
71+
// CHECK-LABEL-SPIRV: <3 x float> @_Z18test_f32_ddy_fine3Dv3_f
72+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <3 x float> @llvm.spv.ddy.fine.v3f32(<3 x float> %{{.*}})
73+
// CHECK-SPIRV: ret <3 x float> %hlsl.ddy.fine
74+
float3 test_f32_ddy_fine3(float3 val) {
75+
return ddy_fine(val);
76+
}
77+
78+
// CHECK-LABEL: <4 x float> @_Z18test_f32_ddy_fine4Dv4_f
79+
// CHECK: %hlsl.ddy.fine = call {{.*}} <4 x float> @llvm.dx.ddy.fine.v4f32(<4 x float> %{{.*}})
80+
// CHECK: ret <4 x float> %hlsl.ddy.fine
81+
// CHECK-LABEL-SPIRV: <4 x float> @_Z18test_f32_ddy_fine4Dv4_f
82+
// CHECK-SPIRV: %hlsl.ddy.fine = call {{.*}} <4 x float> @llvm.spv.ddy.fine.v4f32(<4 x float> %{{.*}})
83+
// CHECK-SPIRV: ret <4 x float> %hlsl.ddy.fine
84+
float4 test_f32_ddy_fine4(float4 val) {
85+
return ddy_fine(val);
86+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify
2+
// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-library %s -fnative-half-type -verify
3+
4+
float no_arg() {
5+
return __builtin_hlsl_elementwise_ddx_fine();
6+
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
7+
}
8+
9+
float too_many_args(float val) {
10+
return __builtin_hlsl_elementwise_ddx_fine(val, val);
11+
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
12+
}
13+
14+
float test_integer_scalar_input(int val) {
15+
return __builtin_hlsl_elementwise_ddx_fine(val);
16+
// expected-error@-1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'int')}}
17+
}
18+
19+
double test_double_scalar_input(double val) {
20+
return __builtin_hlsl_elementwise_ddx_fine(val);
21+
// expected-error@-1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double')}}
22+
}

0 commit comments

Comments
 (0)