[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)
https://github.com/Icohedron edited https://github.com/llvm/llvm-project/pull/122992 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)
llvmbot wrote:
@llvm/pr-subscribers-hlsl
Author: Deric Cheung (Icohedron)
Changes
Fixes #99152
Tasks completed:
- Implement `reflect` in `clang/lib/Headers/hlsl/hlsl_intrinsics.h`
- Implement the `reflect` SPIR-V target built-in in
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `clang/lib/Headers/hlsl/hlsl_detail.h` in the form
```c++
#if (__has_builtin(__builtin_spirv_reflect))
return __builtin_spirv_reflect(...);
#else
return ...; // regular behavior
#endif
```
- Add codegen for the SPIR-V `reflect` built-in to `EmitSPIRVBuiltinExpr` in
`clang/lib/CodeGen/CGBuiltin.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/reflect.hlsl`
- Add SPIR-V built-in codegen tests to
`clang/test/CodeGenSPIRV/Builtins/reflect.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl`
- Add SPIR-V sema tests to `clang/test/CodeGenSPIRV/Builtins/reflect-errors.c`
- Create the `int_spv_reflect` intrinsic in
`llvm/include/llvm/IR/IntrinsicsSPIRV.td`
- In `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` create the `reflect`
lowering and map it to `int_spv_reflect` in
`SPIRVInstructionSelector::selectIntrinsic`
- Create a SPIR-V backend test case in
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll`
Additional tasks completed:
- Implement sema check for the `reflect` SPIR-V built-in in
`clang/lib/Sema/SemaSPIRV.cpp`
- Required for HLSL codegen to work via the SPIR-V fast path, otherwise the
test `clang/test/CodeGenHLSL/builtins/reflect.hlsl` outright fails to compile
Incomplete tasks:
- Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/opencl/reflect.ll
- I do not think an OpenCL test is applicable in this case because the
[OpenCL SPIR-V extended instruction
set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html)
does not include a `reflect` function
---
Patch is 29.45 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/122992.diff
12 Files Affected:
- (modified) clang/include/clang/Basic/BuiltinsSPIRV.td (+6)
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+13)
- (modified) clang/lib/Headers/hlsl/hlsl_detail.h (+17)
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+43)
- (modified) clang/lib/Sema/SemaSPIRV.cpp (+32)
- (added) clang/test/CodeGenHLSL/builtins/reflect.hlsl (+195)
- (added) clang/test/CodeGenSPIRV/Builtins/reflect.c (+32)
- (added) clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl (+33)
- (added) clang/test/SemaSPIRV/BuiltIns/reflect-errors.c (+23)
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll (+33)
``diff
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}
+
+def SPIRVReflect : Builtin {
+ let Spellings = ["__builtin_spirv_reflect"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned
BuiltinID,
/*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
ArrayRef{X, Y}, nullptr, "spv.distance");
}
+ case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+ E->getArg(1)->getType()->hasFloatingRepresentation() &&
+ "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+ E->getArg(1)->getType()->isVectorType() &&
+ "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+ }
}
return nullptr;
}
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -68,6 +68,23 @@ distance_vec_impl(vector X, vector Y) {
return length_vec_impl(X - Y);
#endif
}
+
+template
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+ return I - 2 * N * I * N;
+}
+
+template
+constexpr enable_if_t::value || is_same::value, T>
+reflect_vec_impl(vector I, vector N) {
+#if
[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Deric Cheung (Icohedron)
Changes
Fixes #99152
Tasks completed:
- Implement `reflect` in `clang/lib/Headers/hlsl/hlsl_intrinsics.h`
- Implement the `reflect` SPIR-V target built-in in
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `clang/lib/Headers/hlsl/hlsl_detail.h` in the form
```c++
#if (__has_builtin(__builtin_spirv_reflect))
return __builtin_spirv_reflect(...);
#else
return ...; // regular behavior
#endif
```
- Add codegen for the SPIR-V `reflect` built-in to `EmitSPIRVBuiltinExpr` in
`clang/lib/CodeGen/CGBuiltin.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/reflect.hlsl`
- Add SPIR-V built-in codegen tests to
`clang/test/CodeGenSPIRV/Builtins/reflect.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl`
- Add SPIR-V sema tests to `clang/test/CodeGenSPIRV/Builtins/reflect-errors.c`
- Create the `int_spv_reflect` intrinsic in
`llvm/include/llvm/IR/IntrinsicsSPIRV.td`
- In `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` create the `reflect`
lowering and map it to `int_spv_reflect` in
`SPIRVInstructionSelector::selectIntrinsic`
- Create a SPIR-V backend test case in
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll`
Additional tasks completed:
- Implement sema check for the `reflect` SPIR-V built-in in
`clang/lib/Sema/SemaSPIRV.cpp`
- Required for HLSL codegen to work via the SPIR-V fast path, otherwise the
test `clang/test/CodeGenHLSL/builtins/reflect.hlsl` outright fails to compile
Incomplete tasks:
- Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/opencl/reflect.ll
- I do not think an OpenCL test is applicable in this case because the
[OpenCL SPIR-V extended instruction
set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html)
does not include a `reflect` function
---
Patch is 29.45 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/122992.diff
12 Files Affected:
- (modified) clang/include/clang/Basic/BuiltinsSPIRV.td (+6)
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+13)
- (modified) clang/lib/Headers/hlsl/hlsl_detail.h (+17)
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+43)
- (modified) clang/lib/Sema/SemaSPIRV.cpp (+32)
- (added) clang/test/CodeGenHLSL/builtins/reflect.hlsl (+195)
- (added) clang/test/CodeGenSPIRV/Builtins/reflect.c (+32)
- (added) clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl (+33)
- (added) clang/test/SemaSPIRV/BuiltIns/reflect-errors.c (+23)
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll (+33)
``diff
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}
+
+def SPIRVReflect : Builtin {
+ let Spellings = ["__builtin_spirv_reflect"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned
BuiltinID,
/*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
ArrayRef{X, Y}, nullptr, "spv.distance");
}
+ case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+ E->getArg(1)->getType()->hasFloatingRepresentation() &&
+ "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+ E->getArg(1)->getType()->isVectorType() &&
+ "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+ }
}
return nullptr;
}
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -68,6 +68,23 @@ distance_vec_impl(vector X, vector Y) {
return length_vec_impl(X - Y);
#endif
}
+
+template
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+ return I - 2 * N * I * N;
+}
+
+template
+constexpr enable_if_t::value || is_same::value, T>
+reflect_vec_impl(vector I, vector N) {
+#if
[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)
llvmbot wrote:
@llvm/pr-subscribers-clang-codegen
Author: Deric Cheung (Icohedron)
Changes
Fixes #99152
Tasks completed:
- Implement `reflect` in `clang/lib/Headers/hlsl/hlsl_intrinsics.h`
- Implement the `reflect` SPIR-V target built-in in
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `clang/lib/Headers/hlsl/hlsl_detail.h` in the form
```c++
#if (__has_builtin(__builtin_spirv_reflect))
return __builtin_spirv_reflect(...);
#else
return ...; // regular behavior
#endif
```
- Add codegen for the SPIR-V `reflect` built-in to `EmitSPIRVBuiltinExpr` in
`clang/lib/CodeGen/CGBuiltin.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/reflect.hlsl`
- Add SPIR-V built-in codegen tests to
`clang/test/CodeGenSPIRV/Builtins/reflect.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl`
- Add SPIR-V sema tests to `clang/test/CodeGenSPIRV/Builtins/reflect-errors.c`
- Create the `int_spv_reflect` intrinsic in
`llvm/include/llvm/IR/IntrinsicsSPIRV.td`
- In `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` create the `reflect`
lowering and map it to `int_spv_reflect` in
`SPIRVInstructionSelector::selectIntrinsic`
- Create a SPIR-V backend test case in
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll`
Additional tasks completed:
- Implement sema check for the `reflect` SPIR-V built-in in
`clang/lib/Sema/SemaSPIRV.cpp`
- Required for HLSL codegen to work via the SPIR-V fast path, otherwise the
test `clang/test/CodeGenHLSL/builtins/reflect.hlsl` outright fails to compile
Incomplete tasks:
- Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/opencl/reflect.ll
- I do not think an OpenCL test is applicable in this case because the
[OpenCL SPIR-V extended instruction
set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html)
does not include a `reflect` function
---
Patch is 29.45 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/122992.diff
12 Files Affected:
- (modified) clang/include/clang/Basic/BuiltinsSPIRV.td (+6)
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+13)
- (modified) clang/lib/Headers/hlsl/hlsl_detail.h (+17)
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+43)
- (modified) clang/lib/Sema/SemaSPIRV.cpp (+32)
- (added) clang/test/CodeGenHLSL/builtins/reflect.hlsl (+195)
- (added) clang/test/CodeGenSPIRV/Builtins/reflect.c (+32)
- (added) clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl (+33)
- (added) clang/test/SemaSPIRV/BuiltIns/reflect-errors.c (+23)
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll (+33)
``diff
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}
+
+def SPIRVReflect : Builtin {
+ let Spellings = ["__builtin_spirv_reflect"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned
BuiltinID,
/*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
ArrayRef{X, Y}, nullptr, "spv.distance");
}
+ case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+ E->getArg(1)->getType()->hasFloatingRepresentation() &&
+ "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+ E->getArg(1)->getType()->isVectorType() &&
+ "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+ }
}
return nullptr;
}
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -68,6 +68,23 @@ distance_vec_impl(vector X, vector Y) {
return length_vec_impl(X - Y);
#endif
}
+
+template
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+ return I - 2 * N * I * N;
+}
+
+template
+constexpr enable_if_t::value || is_same::value, T>
+reflect_vec_impl(vector I, vector N) {
+#if
[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)
https://github.com/Icohedron created
https://github.com/llvm/llvm-project/pull/122992
Fixes #99152
Tasks completed:
- Implement `reflect` in `clang/lib/Headers/hlsl/hlsl_intrinsics.h`
- Implement the `reflect` SPIR-V target built-in in
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `clang/lib/Headers/hlsl/hlsl_detail.h` in the form
```c++
#if (__has_builtin(__builtin_spirv_reflect))
return __builtin_spirv_reflect(...);
#else
return ...; // regular behavior
#endif
```
- Add codegen for the SPIR-V `reflect` built-in to `EmitSPIRVBuiltinExpr` in
`clang/lib/CodeGen/CGBuiltin.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/reflect.hlsl`
- Add SPIR-V built-in codegen tests to
`clang/test/CodeGenSPIRV/Builtins/reflect.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl`
- Add SPIR-V sema tests to `clang/test/CodeGenSPIRV/Builtins/reflect-errors.c`
- Create the `int_spv_reflect` intrinsic in
`llvm/include/llvm/IR/IntrinsicsSPIRV.td`
- In `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` create the `reflect`
lowering and map it to `int_spv_reflect` in
`SPIRVInstructionSelector::selectIntrinsic`
- Create a SPIR-V backend test case in
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll`
Additional tasks completed:
- Implement sema check for the `reflect` SPIR-V built-in in
`clang/lib/Sema/SemaSPIRV.cpp`
- Required for HLSL codegen to work via the SPIR-V fast path, otherwise the
test `clang/test/CodeGenHLSL/builtins/reflect.hlsl` outright fails to compile
Incomplete tasks:
- Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/opencl/reflect.ll
- I do not think an OpenCL test is applicable in this case because the
[OpenCL SPIR-V extended instruction
set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html)
does not include a `reflect` function
>From 3f3b8c75c14bb9b3ed611c9cddec49d0e9339705 Mon Sep 17 00:00:00 2001
From: Icohedron
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH] Implement `reflect` HLSL function
---
clang/include/clang/Basic/BuiltinsSPIRV.td| 6 +
clang/lib/CodeGen/CGBuiltin.cpp | 13 ++
clang/lib/Headers/hlsl/hlsl_detail.h | 17 ++
clang/lib/Headers/hlsl/hlsl_intrinsics.h | 43
clang/lib/Sema/SemaSPIRV.cpp | 32 +++
clang/test/CodeGenHLSL/builtins/reflect.hlsl | 195 ++
clang/test/CodeGenSPIRV/Builtins/reflect.c| 32 +++
.../SemaHLSL/BuiltIns/reflect-errors.hlsl | 33 +++
.../test/SemaSPIRV/BuiltIns/reflect-errors.c | 23 +++
llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 +
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 2 +
.../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll | 33 +++
12 files changed, 430 insertions(+)
create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}
+
+def SPIRVReflect : Builtin {
+ let Spellings = ["__builtin_spirv_reflect"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned
BuiltinID,
/*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
ArrayRef{X, Y}, nullptr, "spv.distance");
}
+ case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+ E->getArg(1)->getType()->hasFloatingRepresentation() &&
+ "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+ E->getArg(1)->getType()->isVectorType() &&
+ "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+ }
}
return nullptr;
}
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++
