Author: Kaitlin Peng
Date: 2025-04-09T12:12:26-07:00
New Revision: 2ab2276ee079478b7ba9dd42c62b796d3dab1759

URL: 
https://github.com/llvm/llvm-project/commit/2ab2276ee079478b7ba9dd42c62b796d3dab1759
DIFF: 
https://github.com/llvm/llvm-project/commit/2ab2276ee079478b7ba9dd42c62b796d3dab1759.diff

LOG: [HLSL] Implement the `lit` intrinsic (#134171)

Closes #99135.

Tasks completed:
- Wrote implementation in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h`
- Added codegen tests to `clang/test/CodeGenHLSL/builtins/lit.hlsl`

Added: 
    clang/test/CodeGenHLSL/builtins/lit.hlsl

Modified: 
    clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
    clang/lib/Headers/hlsl/hlsl_intrinsics.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index b5d88ee1f65cb..3a8a9b6fa2a45 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -114,6 +114,18 @@ 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};
+  // clang-format off
+  bool SpecularCond = or(DiffuseCond, (NDotH < 0));
+  // clang-format on
+  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 8197b5ddf078d..35ff80052cf43 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -292,6 +292,30 @@ 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, 
diff use,
+/// specular, 1).
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+const inline half4 lit(half NDotL, half NDotH, half M) {
+  return __detail::lit_impl(NDotL, NDotH, M);
+}
+
+const inline float4 lit(float NDotL, float NDotH, float M) {
+  return __detail::lit_impl(NDotL, NDotH, M);
+}
+
 
//===----------------------------------------------------------------------===//
 // D3DCOLORtoUBYTE4 builtin
 
//===----------------------------------------------------------------------===//

diff  --git a/clang/test/CodeGenHLSL/builtins/lit.hlsl 
b/clang/test/CodeGenHLSL/builtins/lit.hlsl
new file mode 100644
index 0000000000000..44b3e96ef88bf
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/lit.hlsl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple 
dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -o - | 
FileCheck %s
+
+// CHECK-LABEL: test_lit_half
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 
0xH0000
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, 
half 0xH0000, half %{{.*}}
+// CHECK: %vecinit.i = insertelement <4 x half> <half 0xH3C00, half poison, 
half poison, half poison>, half %{{.*}}, i32 1
+// CHECK: %vecinit2.i = insertelement <4 x half> %{{.*}}, half 0xH3C00, i32 3
+// CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 
0xH0000
+// CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i
+// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn half 
@llvm.log.f16(half %{{.*}})
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn half %elt.log.i, %{{.*}}
+// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn half 
@llvm.exp.f16(half %mul.i)
+// CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, 
half 0xH0000, half %{{.*}}
+// CHECK: %vecins.i = insertelement <4 x half> %{{.*}}, half %hlsl.select7.i, 
i32 2
+// CHECK: ret <4 x half> %{{.*}}
+half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, 
M); }
+
+// CHECK-LABEL: test_lit_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: %vecinit2.i = insertelement <4 x float> %{{.*}}, float 1.000000e+00, 
i32 3
+// 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: ret <4 x float> %{{.*}}
+float4 test_lit_float(float NDotL, float NDotH, float M) { return lit(NDotL, 
NDotH, M); }


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to