-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[HLSL] Implement the lit
intrinsic
#134171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-hlsl Author: Kaitlin Peng (kmpeng) ChangesCloses #99135. Tasks completed:
Full diff: https://github.com/llvm/llvm-project/pull/134171.diff 8 Files Affected:
diff --git a/clang/lib/Headers/hlsl.h b/clang/lib/Headers/hlsl.h
index b494b4d0f78bb..2bc1973f6eb2b 100644
--- a/clang/lib/Headers/hlsl.h
+++ b/clang/lib/Headers/hlsl.h
@@ -22,10 +22,10 @@
// HLSL standard library function declarations/definitions.
#include "hlsl/hlsl_alias_intrinsics.h"
+#include "hlsl/hlsl_intrinsics.h"
#if __HLSL_VERSION <= __HLSL_202x
#include "hlsl/hlsl_compat_overloads.h"
#endif
-#include "hlsl/hlsl_intrinsics.h"
#if defined(__clang__)
#pragma clang diagnostic pop
diff --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index 47ae34adfe541..cbf5364c0b29c 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -280,6 +280,22 @@ constexpr bool4 isinf(double4 V) { return isinf((float4)V); }
_DXC_COMPAT_TERNARY_DOUBLE_OVERLOADS(lerp)
_DXC_COMPAT_TERNARY_INTEGER_OVERLOADS(lerp)
+//===----------------------------------------------------------------------===//
+// lit builtins overloads
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+constexpr __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
+ (__detail::is_same<double, T>::value ||
+ __detail::is_same<int, T>::value ||
+ __detail::is_same<uint, T>::value ||
+ __detail::is_same<int64_t, T>::value ||
+ __detail::is_same<uint64_t, T>::value),
+ vector<T, 4>>
+lit(T NDotL, T NDotH, T M) {
+ return lit((float)NDotL, (float)NDotH, (float)M);
+}
+
//===----------------------------------------------------------------------===//
// log builtins overloads
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 8cdd63d7e07bb..3a41635a89aa4 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -101,6 +101,16 @@ constexpr vector<T, N> smoothstep_vec_impl(vector<T, N> Min, vector<T, N> Max,
#endif
}
+template <typename T> constexpr vector<T, 4> lit_impl(T NDotL, T NDotH, T M) {
+ bool DiffuseCond = NDotL < 0;
+ T Diffuse = select<T>(DiffuseCond, 0, NDotL);
+ vector<T, 4> Result = {1, Diffuse, 0, 1};
+ bool SpecularCond = or (DiffuseCond, (NDotH < 0));
+ T SpecularExp = exp(log(NDotH) * M);
+ Result[2] = select<T>(SpecularCond, 0, SpecularExp);
+ return Result;
+}
+
} // namespace __detail
} // namespace hlsl
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index fd799b8d874ae..5d23eb89b889b 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -253,6 +253,37 @@ const inline float length(__detail::HLSL_FIXED_VECTOR<float, N> X) {
return __detail::length_vec_impl(X);
}
+//===----------------------------------------------------------------------===//
+// lit builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn vector<T, 4> lit(T NDotL, T NDotH, T M)
+/// \brief Returns a lighting coefficient vector.
+/// \param NDotL The dot product of the normalized surface normal and the
+/// light vector.
+/// \param NDotH The dot product of the half-angle vector and the surface
+/// normal.
+/// \param M A specular exponent.
+///
+/// This function returns a lighting coefficient vector (ambient, diffuse,
+/// specular, 1).
+
+template <typename T>
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
+ __detail::is_same<half, T>::value,
+ vector<T, 4>> lit(T NDotL, T NDotH, T M) {
+ return __detail::lit_impl(NDotL, NDotH, M);
+}
+
+template <typename T>
+const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
+ __detail::is_same<float, T>::value,
+ vector<T, 4>>
+lit(T NDotL, T NDotH, T M) {
+ return __detail::lit_impl(NDotL, NDotH, M);
+}
+
//===----------------------------------------------------------------------===//
// D3DCOLORtoUBYTE4 builtin
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CodeGenHLSL/builtins/lit-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/lit-overloads.hlsl
new file mode 100644
index 0000000000000..676889ecf16b0
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/lit-overloads.hlsl
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
+// RUN: -emit-llvm -o - | \
+// RUN: FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: test_lit_double
+// CHECK: %conv.i = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
+// CHECK: %conv1.i = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
+// CHECK: %conv2.i = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fpext reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}} to <4 x double>
+// CHECK: ret <4 x double> %conv3.i
+double4 test_lit_double(double NDotL, double NDotH, double M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_int
+// CHECK: %conv.i = sitofp i32 %{{.*}} to float
+// CHECK: %conv1.i = sitofp i32 %{{.*}} to float
+// CHECK: %conv2.i = sitofp i32 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptosi <4 x float> %{{.*}} to <4 x i32>
+// CHECK: ret <4 x i32> %conv3.i
+int4 test_lit_int(int NDotL, int NDotH, int M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_uint
+// CHECK: %conv.i = uitofp i32 %{{.*}} to float
+// CHECK: %conv1.i = uitofp i32 %{{.*}} to float
+// CHECK: %conv2.i = uitofp i32 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptoui <4 x float> %{{.*}} to <4 x i32>
+// CHECK: ret <4 x i32> %conv3.i
+uint4 test_lit_uint(uint NDotL, uint NDotH, uint M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_int64_t
+// CHECK: %conv.i = sitofp i64 %{{.*}} to float
+// CHECK: %conv1.i = sitofp i64 %{{.*}} to float
+// CHECK: %conv2.i = sitofp i64 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptosi <4 x float> %{{.*}} to <4 x i64>
+// CHECK: ret <4 x i64> %conv3.i
+int64_t4 test_lit_int64_t(int64_t NDotL, int64_t NDotH, int64_t M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_uint64_t
+// CHECK: %conv.i = uitofp i64 %{{.*}} to float
+// CHECK: %conv1.i = uitofp i64 %{{.*}} to float
+// CHECK: %conv2.i = uitofp i64 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptoui <4 x float> %{{.*}} to <4 x i64>
+// CHECK: ret <4 x i64> %conv3.i
+uint64_t4 test_lit_uint64_t(uint64_t NDotL, uint64_t NDotH, uint64_t M) { return lit(NDotL, NDotH, M); }
diff --git a/clang/test/CodeGenHLSL/builtins/lit.hlsl b/clang/test/CodeGenHLSL/builtins/lit.hlsl
new file mode 100644
index 0000000000000..1737a460e020f
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/lit.hlsl
@@ -0,0 +1,36 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s
+
+// CHECK-LABEL: test_lit_half
+// CHECK-SAME: half noundef nofpclass(nan inf) [[NDOTL:%.*]], half noundef nofpclass(nan inf) [[NDOTH:%.*]], half noundef nofpclass(nan inf) [[M:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[NDOTL]], 0xH0000
+// CHECK-NEXT: [[HLSL_SELECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.maxnum.f16(half [[NDOTL]], half 0xH0000)
+// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x half> <half 0xH3C00, half poison, half poison, half 0xH3C00>, half [[HLSL_SELECT_I]], i64 1
+// CHECK-NEXT: [[CMP4_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[NDOTH]], 0xH0000
+// CHECK-NEXT: [[HLSL_OR_I:%.*]] = or i1 [[CMP_I]], [[CMP4_I]]
+// CHECK-NEXT: [[ELT_LOG_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half [[NDOTH]])
+// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[ELT_LOG_I]], [[M]]
+// CHECK-NEXT: [[ELT_EXP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half [[MUL_I]])
+// CHECK-NEXT: [[HLSL_SELECT7_I:%.*]] = select reassoc nnan ninf nsz arcp afn i1 [[HLSL_OR_I]], half 0xH0000, half [[ELT_EXP_I]]
+// CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x half> [[VECINIT2_I]], half [[HLSL_SELECT7_I]], i64 2
+// CHECK-NEXT: ret <4 x half> [[VECINS_I]]
+//
+half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_float
+// CHECK-SAME: float noundef nofpclass(nan inf) [[NDOTL:%.*]], float noundef nofpclass(nan inf) [[NDOTH:%.*]], float noundef nofpclass(nan inf) [[M:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[NDOTL]], 0.000000e+00
+// CHECK-NEXT: [[HLSL_SELECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.maxnum.f32(float [[NDOTL]], float 0.000000e+00)
+// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float 1.000000e+00>, float [[HLSL_SELECT_I]], i64 1
+// CHECK-NEXT: [[CMP4_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[NDOTH]], 0.000000e+00
+// CHECK-NEXT: [[HLSL_OR_I:%.*]] = or i1 [[CMP_I]], [[CMP4_I]]
+// CHECK-NEXT: [[ELT_LOG_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float [[NDOTH]])
+// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[ELT_LOG_I]], [[M]]
+// CHECK-NEXT: [[ELT_EXP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float [[MUL_I]])
+// CHECK-NEXT: [[HLSL_SELECT7_I:%.*]] = select reassoc nnan ninf nsz arcp afn i1 [[HLSL_OR_I]], float 0.000000e+00, float [[ELT_EXP_I]]
+// CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[HLSL_SELECT7_I]], i64 2
+// CHECK-NEXT: ret <4 x float> [[VECINS_I]]
+//
+float4 test_lit_float(float NDotL, float NDotH, float M) { return lit(NDotL, NDotH, M); }
diff --git a/clang/test/SemaHLSL/BuiltIns/lit-errors-16bit.hlsl b/clang/test/SemaHLSL/BuiltIns/lit-errors-16bit.hlsl
new file mode 100644
index 0000000000000..311bad9a0ef79
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/lit-errors-16bit.hlsl
@@ -0,0 +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=int16_t
+// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1 | FileCheck %s -DTEST_TYPE=uint16_t
+
+// 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'
+vector<TEST_TYPE,4> test_error(TEST_TYPE p0) {
+ return lit(p0, p0, p0);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl
new file mode 100644
index 0000000000000..799fb62a9560d
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify
+
+float4 test_no_second_arg(float p0) {
+ return lit(p0);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+}
+
+float4 test_no_third_arg(float p0) {
+ return lit(p0, p0);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+}
+
+float4 test_too_many_arg(float p0) {
+ return lit(p0, p0, p0, p0);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+}
+
+float4 test_vec_inputs(float2 p0, float2 p1, float2 p2) {
+ return lit(p0, p1, p2);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float2]: invalid vector element type 'vector<float, 2>' (vector of 2 'float' values)}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float2]: invalid vector element type 'vector<float, 2>' (vector of 2 'float' values)}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate template ignored: substitution failure [with T = float2]: invalid vector element type 'vector<float, 2>' (vector of 2 'float' values)}}
+}
+
+float4 test_vec1_inputs(float1 p0, float1 p1, float1 p2) {
+ return lit(p0, p1, p2);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: invalid vector element type 'vector<float, 1>' (vector of 1 'float' value)}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: invalid vector element type 'vector<float, 1>' (vector of 1 'float' value)}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate template ignored: substitution failure [with T = float1]: invalid vector element type 'vector<float, 1>' (vector of 1 'float' value)}}
+}
|
@llvm/pr-subscribers-backend-x86 Author: Kaitlin Peng (kmpeng) ChangesCloses #99135. Tasks completed:
Full diff: https://github.com/llvm/llvm-project/pull/134171.diff 8 Files Affected:
diff --git a/clang/lib/Headers/hlsl.h b/clang/lib/Headers/hlsl.h
index b494b4d0f78bb..2bc1973f6eb2b 100644
--- a/clang/lib/Headers/hlsl.h
+++ b/clang/lib/Headers/hlsl.h
@@ -22,10 +22,10 @@
// HLSL standard library function declarations/definitions.
#include "hlsl/hlsl_alias_intrinsics.h"
+#include "hlsl/hlsl_intrinsics.h"
#if __HLSL_VERSION <= __HLSL_202x
#include "hlsl/hlsl_compat_overloads.h"
#endif
-#include "hlsl/hlsl_intrinsics.h"
#if defined(__clang__)
#pragma clang diagnostic pop
diff --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index 47ae34adfe541..cbf5364c0b29c 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -280,6 +280,22 @@ constexpr bool4 isinf(double4 V) { return isinf((float4)V); }
_DXC_COMPAT_TERNARY_DOUBLE_OVERLOADS(lerp)
_DXC_COMPAT_TERNARY_INTEGER_OVERLOADS(lerp)
+//===----------------------------------------------------------------------===//
+// lit builtins overloads
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+constexpr __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
+ (__detail::is_same<double, T>::value ||
+ __detail::is_same<int, T>::value ||
+ __detail::is_same<uint, T>::value ||
+ __detail::is_same<int64_t, T>::value ||
+ __detail::is_same<uint64_t, T>::value),
+ vector<T, 4>>
+lit(T NDotL, T NDotH, T M) {
+ return lit((float)NDotL, (float)NDotH, (float)M);
+}
+
//===----------------------------------------------------------------------===//
// log builtins overloads
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 8cdd63d7e07bb..3a41635a89aa4 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -101,6 +101,16 @@ constexpr vector<T, N> smoothstep_vec_impl(vector<T, N> Min, vector<T, N> Max,
#endif
}
+template <typename T> constexpr vector<T, 4> lit_impl(T NDotL, T NDotH, T M) {
+ bool DiffuseCond = NDotL < 0;
+ T Diffuse = select<T>(DiffuseCond, 0, NDotL);
+ vector<T, 4> Result = {1, Diffuse, 0, 1};
+ bool SpecularCond = or (DiffuseCond, (NDotH < 0));
+ T SpecularExp = exp(log(NDotH) * M);
+ Result[2] = select<T>(SpecularCond, 0, SpecularExp);
+ return Result;
+}
+
} // namespace __detail
} // namespace hlsl
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index fd799b8d874ae..5d23eb89b889b 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -253,6 +253,37 @@ const inline float length(__detail::HLSL_FIXED_VECTOR<float, N> X) {
return __detail::length_vec_impl(X);
}
+//===----------------------------------------------------------------------===//
+// lit builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn vector<T, 4> lit(T NDotL, T NDotH, T M)
+/// \brief Returns a lighting coefficient vector.
+/// \param NDotL The dot product of the normalized surface normal and the
+/// light vector.
+/// \param NDotH The dot product of the half-angle vector and the surface
+/// normal.
+/// \param M A specular exponent.
+///
+/// This function returns a lighting coefficient vector (ambient, diffuse,
+/// specular, 1).
+
+template <typename T>
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
+ __detail::is_same<half, T>::value,
+ vector<T, 4>> lit(T NDotL, T NDotH, T M) {
+ return __detail::lit_impl(NDotL, NDotH, M);
+}
+
+template <typename T>
+const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
+ __detail::is_same<float, T>::value,
+ vector<T, 4>>
+lit(T NDotL, T NDotH, T M) {
+ return __detail::lit_impl(NDotL, NDotH, M);
+}
+
//===----------------------------------------------------------------------===//
// D3DCOLORtoUBYTE4 builtin
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CodeGenHLSL/builtins/lit-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/lit-overloads.hlsl
new file mode 100644
index 0000000000000..676889ecf16b0
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/lit-overloads.hlsl
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
+// RUN: -emit-llvm -o - | \
+// RUN: FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: test_lit_double
+// CHECK: %conv.i = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
+// CHECK: %conv1.i = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
+// CHECK: %conv2.i = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fpext reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}} to <4 x double>
+// CHECK: ret <4 x double> %conv3.i
+double4 test_lit_double(double NDotL, double NDotH, double M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_int
+// CHECK: %conv.i = sitofp i32 %{{.*}} to float
+// CHECK: %conv1.i = sitofp i32 %{{.*}} to float
+// CHECK: %conv2.i = sitofp i32 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptosi <4 x float> %{{.*}} to <4 x i32>
+// CHECK: ret <4 x i32> %conv3.i
+int4 test_lit_int(int NDotL, int NDotH, int M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_uint
+// CHECK: %conv.i = uitofp i32 %{{.*}} to float
+// CHECK: %conv1.i = uitofp i32 %{{.*}} to float
+// CHECK: %conv2.i = uitofp i32 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptoui <4 x float> %{{.*}} to <4 x i32>
+// CHECK: ret <4 x i32> %conv3.i
+uint4 test_lit_uint(uint NDotL, uint NDotH, uint M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_int64_t
+// CHECK: %conv.i = sitofp i64 %{{.*}} to float
+// CHECK: %conv1.i = sitofp i64 %{{.*}} to float
+// CHECK: %conv2.i = sitofp i64 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptosi <4 x float> %{{.*}} to <4 x i64>
+// CHECK: ret <4 x i64> %conv3.i
+int64_t4 test_lit_int64_t(int64_t NDotL, int64_t NDotH, int64_t M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_uint64_t
+// CHECK: %conv.i = uitofp i64 %{{.*}} to float
+// CHECK: %conv1.i = uitofp i64 %{{.*}} to float
+// CHECK: %conv2.i = uitofp i64 %{{.*}} to float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float poison>, float %{{.*}}, i32 1
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2
+// CHECK: %conv3.i = fptoui <4 x float> %{{.*}} to <4 x i64>
+// CHECK: ret <4 x i64> %conv3.i
+uint64_t4 test_lit_uint64_t(uint64_t NDotL, uint64_t NDotH, uint64_t M) { return lit(NDotL, NDotH, M); }
diff --git a/clang/test/CodeGenHLSL/builtins/lit.hlsl b/clang/test/CodeGenHLSL/builtins/lit.hlsl
new file mode 100644
index 0000000000000..1737a460e020f
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/lit.hlsl
@@ -0,0 +1,36 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s
+
+// CHECK-LABEL: test_lit_half
+// CHECK-SAME: half noundef nofpclass(nan inf) [[NDOTL:%.*]], half noundef nofpclass(nan inf) [[NDOTH:%.*]], half noundef nofpclass(nan inf) [[M:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[NDOTL]], 0xH0000
+// CHECK-NEXT: [[HLSL_SELECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.maxnum.f16(half [[NDOTL]], half 0xH0000)
+// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x half> <half 0xH3C00, half poison, half poison, half 0xH3C00>, half [[HLSL_SELECT_I]], i64 1
+// CHECK-NEXT: [[CMP4_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[NDOTH]], 0xH0000
+// CHECK-NEXT: [[HLSL_OR_I:%.*]] = or i1 [[CMP_I]], [[CMP4_I]]
+// CHECK-NEXT: [[ELT_LOG_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half [[NDOTH]])
+// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[ELT_LOG_I]], [[M]]
+// CHECK-NEXT: [[ELT_EXP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half [[MUL_I]])
+// CHECK-NEXT: [[HLSL_SELECT7_I:%.*]] = select reassoc nnan ninf nsz arcp afn i1 [[HLSL_OR_I]], half 0xH0000, half [[ELT_EXP_I]]
+// CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x half> [[VECINIT2_I]], half [[HLSL_SELECT7_I]], i64 2
+// CHECK-NEXT: ret <4 x half> [[VECINS_I]]
+//
+half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, M); }
+
+// CHECK-LABEL: test_lit_float
+// CHECK-SAME: float noundef nofpclass(nan inf) [[NDOTL:%.*]], float noundef nofpclass(nan inf) [[NDOTH:%.*]], float noundef nofpclass(nan inf) [[M:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[NDOTL]], 0.000000e+00
+// CHECK-NEXT: [[HLSL_SELECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.maxnum.f32(float [[NDOTL]], float 0.000000e+00)
+// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> <float 1.000000e+00, float poison, float poison, float 1.000000e+00>, float [[HLSL_SELECT_I]], i64 1
+// CHECK-NEXT: [[CMP4_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[NDOTH]], 0.000000e+00
+// CHECK-NEXT: [[HLSL_OR_I:%.*]] = or i1 [[CMP_I]], [[CMP4_I]]
+// CHECK-NEXT: [[ELT_LOG_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float [[NDOTH]])
+// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[ELT_LOG_I]], [[M]]
+// CHECK-NEXT: [[ELT_EXP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float [[MUL_I]])
+// CHECK-NEXT: [[HLSL_SELECT7_I:%.*]] = select reassoc nnan ninf nsz arcp afn i1 [[HLSL_OR_I]], float 0.000000e+00, float [[ELT_EXP_I]]
+// CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[HLSL_SELECT7_I]], i64 2
+// CHECK-NEXT: ret <4 x float> [[VECINS_I]]
+//
+float4 test_lit_float(float NDotL, float NDotH, float M) { return lit(NDotL, NDotH, M); }
diff --git a/clang/test/SemaHLSL/BuiltIns/lit-errors-16bit.hlsl b/clang/test/SemaHLSL/BuiltIns/lit-errors-16bit.hlsl
new file mode 100644
index 0000000000000..311bad9a0ef79
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/lit-errors-16bit.hlsl
@@ -0,0 +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=int16_t
+// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 202x %s 2>&1 | FileCheck %s -DTEST_TYPE=uint16_t
+
+// 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'
+vector<TEST_TYPE,4> test_error(TEST_TYPE p0) {
+ return lit(p0, p0, p0);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl
new file mode 100644
index 0000000000000..799fb62a9560d
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify
+
+float4 test_no_second_arg(float p0) {
+ return lit(p0);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+}
+
+float4 test_no_third_arg(float p0) {
+ return lit(p0, p0);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+}
+
+float4 test_too_many_arg(float p0) {
+ return lit(p0, p0, p0, p0);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+}
+
+float4 test_vec_inputs(float2 p0, float2 p1, float2 p2) {
+ return lit(p0, p1, p2);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float2]: invalid vector element type 'vector<float, 2>' (vector of 2 'float' values)}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float2]: invalid vector element type 'vector<float, 2>' (vector of 2 'float' values)}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate template ignored: substitution failure [with T = float2]: invalid vector element type 'vector<float, 2>' (vector of 2 'float' values)}}
+}
+
+float4 test_vec1_inputs(float1 p0, float1 p1, float1 p2) {
+ return lit(p0, p1, p2);
+ // expected-error@-1 {{no matching function for call to 'lit'}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: invalid vector element type 'vector<float, 1>' (vector of 1 'float' value)}}
+ // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: invalid vector element type 'vector<float, 1>' (vector of 1 'float' value)}}
+ // expected-note@hlsl/hlsl_compat_overloads.h:* {{candidate template ignored: substitution failure [with T = float1]: invalid vector element type 'vector<float, 1>' (vector of 1 'float' value)}}
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
I'm concerned that you had to remove your change in |
In my opinion, we should just define Implicit vector truncation is also an area that needs addressing as a problem with the language, rather than being a special-case behavior handled by each function's implementation. Again, a compiler warning would go a long way to addressing problems where implicit truncation may not be intended by the programmer.
Or maybe implicit truncation should be removed from the language entirely (for 202y perhaps)? If you can make the behavior consistent with DXC under all cases with some special implementation in hlsl_compat_overloads for 202x, then you can do that, but I don't think we should be writing an implementation that matches DXC now and then rewrite it entirely again when we swap to 202y that makes the language more consistent (which is one of our goals for HLSL's future, right?) |
We should have Because |
I think we are all in agreement about not resolving lit cases outside of Deric and I were of the opinion that we shouldn't do templates and instead just define a function overload for half and float. Kaitlin astutely pointed out that lit in dxc doesn't support implicit vector truncation. So we have been trying to find a way to get the same restrictions to just half and float using templates. Thats how we landed on the Given your feedback here it sounds like you want us to drop the template and allow for implicit vector truncation so that the error will be ambiguous instead of |
Yes, let's not add compatibility overloads unless we have driving reasons for them. |
@@ -0,0 +1,34 @@ | |||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 | |||
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't do -01 here. Drop the check-next and just check for the instructions you are expecting like
select, or, exp, log, and select again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for future reference, when do we want to use -O1
and/or -disable-llvm-passes
in tests? I haven't been able to figure out a consistent rule looking through the other codegen tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally you should prefer -disable-llvm-passes
since it makes the test run faster
Closes llvm#99135. Tasks completed: - Wrote implementation in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h` - Added codegen tests to `clang/test/CodeGenHLSL/builtins/lit.hlsl`
Closes llvm#99135. Tasks completed: - Wrote implementation in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h` - Added codegen tests to `clang/test/CodeGenHLSL/builtins/lit.hlsl`
Closes #99135.
Tasks completed:
hlsl_intrinsics.h
/hlsl_intrinsic_helpers.h
clang/test/CodeGenHLSL/builtins/lit.hlsl