Skip to content

Commit 719bb94

Browse files
committed
finished lit implementation, added codegen and sema tests
1 parent 990a086 commit 719bb94

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ constexpr vector<T, N> smoothstep_vec_impl(vector<T, N> Min, vector<T, N> Max,
101101
#endif
102102
}
103103

104+
template <typename T>
105+
constexpr vector<T, 4> lit_impl(T N_dot_l, T N_dot_h, T M) {
106+
bool Cond1 = N_dot_l < 0;
107+
T ClampedP1 = select<T>(Cond1, 0, N_dot_l);
108+
vector<T, 4> Result = {1, ClampedP1, 0, 1};
109+
bool CombinedCond = or (Cond1, (N_dot_h < 0));
110+
T LogP2 = log(N_dot_h);
111+
T Exp = exp(LogP2 * M);
112+
Result[2] = select<T>(CombinedCond, 0, Exp);
113+
return Result;
114+
}
115+
104116
} // namespace __detail
105117
} // namespace hlsl
106118

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,37 @@ const inline float length(__detail::HLSL_FIXED_VECTOR<float, N> X) {
253253
return __detail::length_vec_impl(X);
254254
}
255255

256+
//===----------------------------------------------------------------------===//
257+
// lit builtins
258+
//===----------------------------------------------------------------------===//
259+
260+
/// \fn vector<T, 4> lit(T x, T y)
261+
/// \brief Returns a lighting coefficient vector.
262+
/// \param N_dot_l The dot product of the normalized surface normal and the
263+
/// light vector.
264+
/// \param N_dot_h The dot product of the half-angle vector and the surface
265+
/// normal.
266+
/// \param M A specular exponent.
267+
///
268+
/// This function returns a lighting coefficient vector (ambient, diffuse,
269+
/// specular, 1).
270+
271+
template <typename T>
272+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
273+
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
274+
__detail::is_same<half, T>::value,
275+
vector<T, 4>> lit(T N_dot_l, T N_dot_h, T M) {
276+
return __detail::lit_impl(N_dot_l, N_dot_h, M);
277+
}
278+
279+
template <typename T>
280+
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
281+
__detail::is_same<float, T>::value,
282+
vector<T, 4>>
283+
lit(T N_dot_l, T N_dot_h, T M) {
284+
return __detail::lit_impl(N_dot_l, N_dot_h, M);
285+
}
286+
256287
//===----------------------------------------------------------------------===//
257288
// D3DCOLORtoUBYTE4 builtin
258289
//===----------------------------------------------------------------------===//
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s
3+
4+
// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z13test_lit_halfDhDhDh(
5+
// CHECK-SAME: half noundef nofpclass(nan inf) [[N_DOT_L:%.*]], half noundef nofpclass(nan inf) [[N_DOT_H:%.*]], half noundef nofpclass(nan inf) [[M:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
6+
// CHECK-NEXT: [[ENTRY:.*:]]
7+
// CHECK-NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[N_DOT_L]], 0xH0000
8+
// CHECK-NEXT: [[HLSL_SELECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.maxnum.f16(half [[N_DOT_L]], half 0xH0000)
9+
// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x half> <half 0xH3C00, half poison, half poison, half 0xH3C00>, half [[HLSL_SELECT_I]], i64 1
10+
// CHECK-NEXT: [[CMP4_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[N_DOT_H]], 0xH0000
11+
// CHECK-NEXT: [[HLSL_OR_I:%.*]] = or i1 [[CMP_I]], [[CMP4_I]]
12+
// CHECK-NEXT: [[ELT_LOG_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half [[N_DOT_H]])
13+
// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[ELT_LOG_I]], [[M]]
14+
// CHECK-NEXT: [[ELT_EXP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half [[MUL_I]])
15+
// CHECK-NEXT: [[HLSL_SELECT7_I:%.*]] = select reassoc nnan ninf nsz arcp afn i1 [[HLSL_OR_I]], half 0xH0000, half [[ELT_EXP_I]]
16+
// CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x half> [[VECINIT2_I]], half [[HLSL_SELECT7_I]], i64 2
17+
// CHECK-NEXT: ret <4 x half> [[VECINS_I]]
18+
//
19+
half4 test_lit_half(half N_dot_l, half N_dot_h, half M) { return lit(N_dot_l, N_dot_h, M); }
20+
21+
// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_lit_floatfff(
22+
// CHECK-SAME: float noundef nofpclass(nan inf) [[N_DOT_L:%.*]], float noundef nofpclass(nan inf) [[N_DOT_H:%.*]], float noundef nofpclass(nan inf) [[M:%.*]]) local_unnamed_addr #[[ATTR0]] {
23+
// CHECK-NEXT: [[ENTRY:.*:]]
24+
// CHECK-NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[N_DOT_L]], 0.000000e+00
25+
// CHECK-NEXT: [[HLSL_SELECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.maxnum.f32(float [[N_DOT_L]], float 0.000000e+00)
26+
// 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
27+
// CHECK-NEXT: [[CMP4_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[N_DOT_H]], 0.000000e+00
28+
// CHECK-NEXT: [[HLSL_OR_I:%.*]] = or i1 [[CMP_I]], [[CMP4_I]]
29+
// CHECK-NEXT: [[ELT_LOG_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float [[N_DOT_H]])
30+
// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[ELT_LOG_I]], [[M]]
31+
// CHECK-NEXT: [[ELT_EXP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float [[MUL_I]])
32+
// CHECK-NEXT: [[HLSL_SELECT7_I:%.*]] = select reassoc nnan ninf nsz arcp afn i1 [[HLSL_OR_I]], float 0.000000e+00, float [[ELT_EXP_I]]
33+
// CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[HLSL_SELECT7_I]], i64 2
34+
// CHECK-NEXT: ret <4 x float> [[VECINS_I]]
35+
//
36+
float4 test_lit_float(float N_dot_l, float N_dot_h, float M) { return lit(N_dot_l, N_dot_h, M); }
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// 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
2+
3+
float4 test_no_second_arg(float p0) {
4+
return lit(p0);
5+
// expected-error@-1 {{no matching function for call to 'lit'}}
6+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
7+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
8+
}
9+
10+
float4 test_no_third_arg(float p0) {
11+
return lit(p0, p0);
12+
// expected-error@-1 {{no matching function for call to 'lit'}}
13+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
14+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
15+
}
16+
17+
float4 test_too_many_arg(float p0) {
18+
return lit(p0, p0, p0, p0);
19+
// expected-error@-1 {{no matching function for call to 'lit'}}
20+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
21+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
22+
}
23+
24+
float4 test_double_inputs(double p0, double p1, double p2) {
25+
return lit(p0, p1, p2);
26+
// expected-error@-1 {{no matching function for call to 'lit'}}
27+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = double]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<double, 4>>'}}
28+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = double]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<double, 4>>'}}
29+
}
30+
31+
float4 test_int_inputs(int p0, int p1, int p2) {
32+
return lit(p0, p1, p2);
33+
// expected-error@-1 {{no matching function for call to 'lit'}}
34+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = int]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<int, 4>>'}}
35+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = int]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<int, 4>>'}}
36+
}
37+
38+
float4 test_vec_inputs(float2 p0, float2 p1, float2 p2) {
39+
return lit(p0, p1, p2);
40+
// expected-error@-1 {{no matching function for call to 'lit'}}
41+
// 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)}}
42+
// 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)}}
43+
}
44+
45+
float4 test_vec1_inputs(float1 p0, float1 p1, float1 p2) {
46+
return lit(p0, p1, p2);
47+
// expected-error@-1 {{no matching function for call to 'lit'}}
48+
// 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)}}
49+
// 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)}}
50+
}

0 commit comments

Comments
 (0)