[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng closed 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl approved this pull request.


https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng updated 
https://github.com/llvm/llvm-project/pull/135878

>From 115b4f8e6276c4dd19e66136a5ad01b6b22f7586 Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Mon, 7 Apr 2025 14:46:07 -0700
Subject: [PATCH 1/5] create int_spv_faceforward intrinsic, create faceforward
 lowering & map to int_spv_faceforward, create SPIR-V backend test case

---
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |  1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  2 ++
 .../SPIRV/hlsl-intrinsics/faceforward.ll  | 35 +++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..77cca0a58424f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -67,6 +67,7 @@ let TargetPrefix = "spv" in {
   def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_faceforward : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
 [IntrNoMem] >;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..8304077f049a3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3083,6 +3083,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
   case Intrinsic::spv_degrees:
 return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
+  case Intrinsic::spv_faceforward:
+return selectExtInst(ResVReg, ResType, I, GL::FaceForward);
   case Intrinsic::spv_frac:
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
new file mode 100644
index 0..4b34adc88c0f2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; Make sure SPIRV operation function calls for faceforward are lowered 
correctly.
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+
+define noundef <4 x half> @faceforward_half4(<4 x half> noundef %a, <4 x half> 
noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_16]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x half> @llvm.spv.faceforward.f16(<4 x half> %a, 
<4 x half> %b, <4 x half> %c)
+  ret <4 x half> %spv.faceforward
+}
+
+define noundef <4 x float> @faceforward_float4(<4 x float> noundef %a, <4 x 
float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_32]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x float> @llvm.spv.faceforward.f32(<4 x float> 
%a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %spv.faceforward
+}
+
+declare <4 x half> @llvm.spv.faceforward.f16(<4 x half>, <4 x half>, <4 x 
half>)
+declare <4 x float> @llvm.spv.faceforward.f32(<4 x float>, <4 x float>, <4 x 
float>)

>From ae11724e49658d9b6c51556746618e7817835d27 Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Thu, 10 Apr 2025 14:55:17 -0700
Subject: [PATCH 2/5] implemented `faceforward` in `hlsl.Intrinsics.h` an

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-24 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-21 Thread Farzon Lotfi via cfe-commits


@@ -0,0 +1,63 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; TODO(#136344): This test currently fails when --target-env vulkan1.3 is 
specified.
+; XFAIL: spirv-tools

farzonl wrote:

we can't xfail a new test

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-18 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-18 Thread Kaitlin Peng via cfe-commits


@@ -105,35 +136,27 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 if (SemaRef.checkArgCount(TheCall, 3))
   return true;
 
-// check if the all arguments have floating representation
-for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
-  ExprResult Arg = TheCall->getArg(i);
-  QualType ArgTy = Arg.get()->getType();
-  if (!ArgTy->hasFloatingRepresentation()) {
-SemaRef.Diag(Arg.get()->getBeginLoc(),
- diag::err_builtin_invalid_arg_type)
-<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1
-<< ArgTy;
-return true;
-  }
-}
+if (CheckAllArgsHaveFloatRepresentation(&SemaRef, TheCall))
+  return true;
 
-// check if all arguments are of the same type
-ExprResult A = TheCall->getArg(0);
-ExprResult B = TheCall->getArg(1);
-ExprResult C = TheCall->getArg(2);
-if (!(SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),
- B.get()->getType()) &&
-  SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),
- C.get()->getType( 
{
-  SemaRef.Diag(TheCall->getBeginLoc(),
-   diag::err_vec_builtin_incompatible_vector)
-  << TheCall->getDirectCallee() << /*useAllTerminology*/ true
-  << SourceRange(A.get()->getBeginLoc(), C.get()->getEndLoc());
+if (CheckAllArgsHaveSameType(&SemaRef, TheCall))

kmpeng wrote:

Code updated to only check the first value for float representation

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-18 Thread Kaitlin Peng via cfe-commits


@@ -126,6 +126,24 @@ template  constexpr vector lit_impl(T 
NDotL, T NDotH, T M) {
   return Result;
 }
 
+template  constexpr T faceforward_impl(T N, T I, T Ng) {

kmpeng wrote:

You're right. Removed vector implementation

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-18 Thread Kaitlin Peng via cfe-commits


@@ -0,0 +1,35 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+
+// RUN: %clang_cc1 -O1 -triple spirv-pc-vulkan-compute %s -emit-llvm -o - | 
FileCheck %s
+
+typedef float float2 __attribute__((ext_vector_type(2)));
+typedef float float3 __attribute__((ext_vector_type(3)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+

kmpeng wrote:

Added half tests

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-18 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng updated 
https://github.com/llvm/llvm-project/pull/135878

>From d953d95867574dd575cf098668554dfa8e7ffad5 Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Mon, 7 Apr 2025 14:46:07 -0700
Subject: [PATCH 1/4] create int_spv_faceforward intrinsic, create faceforward
 lowering & map to int_spv_faceforward, create SPIR-V backend test case

---
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |  1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  2 ++
 .../SPIRV/hlsl-intrinsics/faceforward.ll  | 35 +++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..77cca0a58424f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -67,6 +67,7 @@ let TargetPrefix = "spv" in {
   def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_faceforward : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
 [IntrNoMem] >;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..8304077f049a3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3083,6 +3083,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
   case Intrinsic::spv_degrees:
 return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
+  case Intrinsic::spv_faceforward:
+return selectExtInst(ResVReg, ResType, I, GL::FaceForward);
   case Intrinsic::spv_frac:
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
new file mode 100644
index 0..4b34adc88c0f2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; Make sure SPIRV operation function calls for faceforward are lowered 
correctly.
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+
+define noundef <4 x half> @faceforward_half4(<4 x half> noundef %a, <4 x half> 
noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_16]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x half> @llvm.spv.faceforward.f16(<4 x half> %a, 
<4 x half> %b, <4 x half> %c)
+  ret <4 x half> %spv.faceforward
+}
+
+define noundef <4 x float> @faceforward_float4(<4 x float> noundef %a, <4 x 
float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_32]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x float> @llvm.spv.faceforward.f32(<4 x float> 
%a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %spv.faceforward
+}
+
+declare <4 x half> @llvm.spv.faceforward.f16(<4 x half>, <4 x half>, <4 x 
half>)
+declare <4 x float> @llvm.spv.faceforward.f32(<4 x float>, <4 x float>, <4 x 
float>)

>From 9966b0cf1d12dd5db1907d7d99c8d812a75349c0 Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Thu, 10 Apr 2025 14:55:17 -0700
Subject: [PATCH 2/4] implemented `faceforward` in `hlsl.Intrinsics.h` an

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-18 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng updated 
https://github.com/llvm/llvm-project/pull/135878

>From 69aee464d31dcf585c355808053b0c4d1c7d7f3c Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Mon, 7 Apr 2025 14:46:07 -0700
Subject: [PATCH 1/4] create int_spv_faceforward intrinsic, create faceforward
 lowering & map to int_spv_faceforward, create SPIR-V backend test case

---
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |  1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  2 ++
 .../SPIRV/hlsl-intrinsics/faceforward.ll  | 35 +++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..77cca0a58424f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -67,6 +67,7 @@ let TargetPrefix = "spv" in {
   def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_faceforward : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
 [IntrNoMem] >;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..8304077f049a3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3083,6 +3083,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
   case Intrinsic::spv_degrees:
 return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
+  case Intrinsic::spv_faceforward:
+return selectExtInst(ResVReg, ResType, I, GL::FaceForward);
   case Intrinsic::spv_frac:
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
new file mode 100644
index 0..4b34adc88c0f2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; Make sure SPIRV operation function calls for faceforward are lowered 
correctly.
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+
+define noundef <4 x half> @faceforward_half4(<4 x half> noundef %a, <4 x half> 
noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_16]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x half> @llvm.spv.faceforward.f16(<4 x half> %a, 
<4 x half> %b, <4 x half> %c)
+  ret <4 x half> %spv.faceforward
+}
+
+define noundef <4 x float> @faceforward_float4(<4 x float> noundef %a, <4 x 
float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_32]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x float> @llvm.spv.faceforward.f32(<4 x float> 
%a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %spv.faceforward
+}
+
+declare <4 x half> @llvm.spv.faceforward.f16(<4 x half>, <4 x half>, <4 x 
half>)
+declare <4 x float> @llvm.spv.faceforward.f32(<4 x float>, <4 x float>, <4 x 
float>)

>From 06324ca82d3c593c801bf602b8f58683d13e738f Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Thu, 10 Apr 2025 14:55:17 -0700
Subject: [PATCH 2/4] implemented `faceforward` in `hlsl.Intrinsics.h` an

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Kaitlin Peng via cfe-commits


@@ -105,35 +136,27 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 if (SemaRef.checkArgCount(TheCall, 3))
   return true;
 
-// check if the all arguments have floating representation
-for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
-  ExprResult Arg = TheCall->getArg(i);
-  QualType ArgTy = Arg.get()->getType();
-  if (!ArgTy->hasFloatingRepresentation()) {
-SemaRef.Diag(Arg.get()->getBeginLoc(),
- diag::err_builtin_invalid_arg_type)
-<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1
-<< ArgTy;
-return true;
-  }
-}
+if (CheckAllArgsHaveFloatRepresentation(&SemaRef, TheCall))
+  return true;
 
-// check if all arguments are of the same type
-ExprResult A = TheCall->getArg(0);
-ExprResult B = TheCall->getArg(1);
-ExprResult C = TheCall->getArg(2);
-if (!(SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),
- B.get()->getType()) &&
-  SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),
- C.get()->getType( 
{
-  SemaRef.Diag(TheCall->getBeginLoc(),
-   diag::err_vec_builtin_incompatible_vector)
-  << TheCall->getDirectCallee() << /*useAllTerminology*/ true
-  << SourceRange(A.get()->getBeginLoc(), C.get()->getEndLoc());
+if (CheckAllArgsHaveSameType(&SemaRef, TheCall))

kmpeng wrote:

You're right, it would be better to just check the first value then do 
`CheckAllArgsHaveSameType`.

The only caveat I can think of would be that it would change the error messages 
for tests, e.g. the error message for
```
float test_int_scalar_inputs2(float p0, int p1, int p2)
```
would change from `2nd argument must be a scalar or vector of floating-point 
types (was 'int')` to `all arguments to '__builtin_spirv_faceforward' must have 
the same type`, which I think is fine. 

If we want to make this change for `smoothstep` though, we would probably want 
to do it in a separate PR right?

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits


@@ -105,35 +136,27 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 if (SemaRef.checkArgCount(TheCall, 3))
   return true;
 
-// check if the all arguments have floating representation
-for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
-  ExprResult Arg = TheCall->getArg(i);
-  QualType ArgTy = Arg.get()->getType();
-  if (!ArgTy->hasFloatingRepresentation()) {
-SemaRef.Diag(Arg.get()->getBeginLoc(),
- diag::err_builtin_invalid_arg_type)
-<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1
-<< ArgTy;
-return true;
-  }
-}
+if (CheckAllArgsHaveFloatRepresentation(&SemaRef, TheCall))
+  return true;
 
-// check if all arguments are of the same type
-ExprResult A = TheCall->getArg(0);
-ExprResult B = TheCall->getArg(1);
-ExprResult C = TheCall->getArg(2);
-if (!(SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),
- B.get()->getType()) &&
-  SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),
- C.get()->getType( 
{
-  SemaRef.Diag(TheCall->getBeginLoc(),
-   diag::err_vec_builtin_incompatible_vector)
-  << TheCall->getDirectCallee() << /*useAllTerminology*/ true
-  << SourceRange(A.get()->getBeginLoc(), C.get()->getEndLoc());
+if (CheckAllArgsHaveSameType(&SemaRef, TheCall))

farzonl wrote:

do we need to do CheckAllArgsHaveSameType and 
CheckAllArgsHaveFloatRepresentation.  Two loops over arguments seems 
unnecesary. Seems like we can just check if the first value has a float 
representation then do CheckAllArgsHaveSameType

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits


@@ -0,0 +1,35 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+
+// RUN: %clang_cc1 -O1 -triple spirv-pc-vulkan-compute %s -emit-llvm -o - | 
FileCheck %s
+
+typedef float float2 __attribute__((ext_vector_type(2)));
+typedef float float3 __attribute__((ext_vector_type(3)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+

farzonl wrote:

if you want to do half testing you should be able to do this 
```cpp
typedef _Float16 half;
typedef half half2 __attribute__((ext_vector_type(2)));
```

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits


@@ -126,6 +126,24 @@ template  constexpr vector lit_impl(T 
NDotL, T NDotH, T M) {
   return Result;
 }
 
+template  constexpr T faceforward_impl(T N, T I, T Ng) {

farzonl wrote:

So in cases like length and distance I know why we had a scalar and vector 
version of the implementation function. 
In those two cases the return type was different than the argument types. In 
other cases like reflect it also made sense to do two seperate functions 
because the scalar case did not call the spirv builtin. In this case the return 
and argument types are the same and both the vector ans scalar cases call the 
spirv builtin so why do we need two seperate templatized functions?

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-17 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng updated 
https://github.com/llvm/llvm-project/pull/135878

>From 69aee464d31dcf585c355808053b0c4d1c7d7f3c Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Mon, 7 Apr 2025 14:46:07 -0700
Subject: [PATCH 1/3] create int_spv_faceforward intrinsic, create faceforward
 lowering & map to int_spv_faceforward, create SPIR-V backend test case

---
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |  1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  2 ++
 .../SPIRV/hlsl-intrinsics/faceforward.ll  | 35 +++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..77cca0a58424f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -67,6 +67,7 @@ let TargetPrefix = "spv" in {
   def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_faceforward : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
 [IntrNoMem] >;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..8304077f049a3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3083,6 +3083,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
   case Intrinsic::spv_degrees:
 return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
+  case Intrinsic::spv_faceforward:
+return selectExtInst(ResVReg, ResType, I, GL::FaceForward);
   case Intrinsic::spv_frac:
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
new file mode 100644
index 0..4b34adc88c0f2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; Make sure SPIRV operation function calls for faceforward are lowered 
correctly.
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+
+define noundef <4 x half> @faceforward_half4(<4 x half> noundef %a, <4 x half> 
noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_16]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x half> @llvm.spv.faceforward.f16(<4 x half> %a, 
<4 x half> %b, <4 x half> %c)
+  ret <4 x half> %spv.faceforward
+}
+
+define noundef <4 x float> @faceforward_float4(<4 x float> noundef %a, <4 x 
float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_32]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x float> @llvm.spv.faceforward.f32(<4 x float> 
%a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %spv.faceforward
+}
+
+declare <4 x half> @llvm.spv.faceforward.f16(<4 x half>, <4 x half>, <4 x 
half>)
+declare <4 x float> @llvm.spv.faceforward.f32(<4 x float>, <4 x float>, <4 x 
float>)

>From 06324ca82d3c593c801bf602b8f58683d13e738f Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Thu, 10 Apr 2025 14:55:17 -0700
Subject: [PATCH 2/3] implemented `faceforward` in `hlsl.Intrinsics.h` an

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits


@@ -214,6 +214,53 @@ const inline double4 dst(double4 Src0, double4 Src1) {
   return __detail::dst_impl(Src0, Src1);
 }
 
+//===--===//
+// faceforward builtin
+//===--===//
+
+/// \fn T faceforward(T N, T I, T Ng)
+/// \brief Flips the surface-normal (if needed) to face in a direction opposite
+/// to \a I. Returns the result in \a N.

kmpeng wrote:

Ah yeah, that's makes it much more clear. Code updated, thanks!

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits


@@ -137,6 +137,42 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 TheCall->setType(RetTy);
 break;
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+if (SemaRef.checkArgCount(TheCall, 3))
+  return true;
+
+// check if all arguments have floating representation
+for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
+  ExprResult Arg = TheCall->getArg(i);
+  QualType ArgTy = Arg.get()->getType();
+  if (!ArgTy->hasFloatingRepresentation()) {
+SemaRef.Diag(Arg.get()->getBeginLoc(),
+ diag::err_builtin_invalid_arg_type)
+<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1

kmpeng wrote:

Code updated

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits


@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \

kmpeng wrote:

Code updated

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits


@@ -137,6 +137,42 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 TheCall->setType(RetTy);
 break;
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+if (SemaRef.checkArgCount(TheCall, 3))
+  return true;
+
+// check if all arguments have floating representation
+for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
+  ExprResult Arg = TheCall->getArg(i);
+  QualType ArgTy = Arg.get()->getType();
+  if (!ArgTy->hasFloatingRepresentation()) {
+SemaRef.Diag(Arg.get()->getBeginLoc(),
+ diag::err_builtin_invalid_arg_type)
+<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1
+<< ArgTy;
+return true;
+  }
+}
+
+// check if all arguments are of the same type
+ExprResult A = TheCall->getArg(0);
+ExprResult B = TheCall->getArg(1);
+ExprResult C = TheCall->getArg(2);
+if (!(SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),

kmpeng wrote:

Code updated

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Finn Plummer via cfe-commits


@@ -214,6 +214,53 @@ const inline double4 dst(double4 Src0, double4 Src1) {
   return __detail::dst_impl(Src0, Src1);
 }
 
+//===--===//
+// faceforward builtin
+//===--===//
+
+/// \fn T faceforward(T N, T I, T Ng)
+/// \brief Flips the surface-normal (if needed) to face in a direction opposite
+/// to \a I. Returns the result in \a N.

inbelic wrote:

I assume this is copied from the docs, but "returns the result in N" is quite 
confusing to me. Maybe it was meant to be "Returns the result in terms of N" or 
the like?

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Finn Plummer via cfe-commits


@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \

inbelic wrote:

```suggestion
// RUN: %clang_cc1 -finclude-default-header -triple \
```
`-x` just specifies the file extension, since the file is `.hlsl` it should 
naturally detect and use it as expected.

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Finn Plummer via cfe-commits


@@ -137,6 +137,42 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 TheCall->setType(RetTy);
 break;
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+if (SemaRef.checkArgCount(TheCall, 3))
+  return true;
+
+// check if all arguments have floating representation
+for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
+  ExprResult Arg = TheCall->getArg(i);
+  QualType ArgTy = Arg.get()->getType();
+  if (!ArgTy->hasFloatingRepresentation()) {
+SemaRef.Diag(Arg.get()->getBeginLoc(),
+ diag::err_builtin_invalid_arg_type)
+<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1

inbelic wrote:

```suggestion
<< /* ordinal */ i + 1 << /* scalar or vector */ 5 << /* no int */ 
0 << /* fp */ 1
```

I think this for loop is the exact same as the smoothstep function? We could 
probably move it to a common function then. 

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Finn Plummer via cfe-commits


@@ -137,6 +137,42 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned 
BuiltinID,
 TheCall->setType(RetTy);
 break;
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+if (SemaRef.checkArgCount(TheCall, 3))
+  return true;
+
+// check if all arguments have floating representation
+for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
+  ExprResult Arg = TheCall->getArg(i);
+  QualType ArgTy = Arg.get()->getType();
+  if (!ArgTy->hasFloatingRepresentation()) {
+SemaRef.Diag(Arg.get()->getBeginLoc(),
+ diag::err_builtin_invalid_arg_type)
+<< i + 1 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 
1
+<< ArgTy;
+return true;
+  }
+}
+
+// check if all arguments are of the same type
+ExprResult A = TheCall->getArg(0);
+ExprResult B = TheCall->getArg(1);
+ExprResult C = TheCall->getArg(2);
+if (!(SemaRef.getASTContext().hasSameUnqualifiedType(A.get()->getType(),

inbelic wrote:

Same here, could be common function. See the `CheckAllArgsHaveTheSameType` in 
`SemaHLSL`. You could probably just copy paste that into this file. I think we 
previously decided to NOT move them to a common place so I wouldn't worry about 
doing that.

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Finn Plummer via cfe-commits

https://github.com/inbelic commented:

Just a collection of nits. LGTM

https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Finn Plummer via cfe-commits

https://github.com/inbelic edited 
https://github.com/llvm/llvm-project/pull/135878
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-16 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng updated 
https://github.com/llvm/llvm-project/pull/135878

>From 69aee464d31dcf585c355808053b0c4d1c7d7f3c Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Mon, 7 Apr 2025 14:46:07 -0700
Subject: [PATCH 1/2] create int_spv_faceforward intrinsic, create faceforward
 lowering & map to int_spv_faceforward, create SPIR-V backend test case

---
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |  1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  2 ++
 .../SPIRV/hlsl-intrinsics/faceforward.ll  | 35 +++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..77cca0a58424f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -67,6 +67,7 @@ let TargetPrefix = "spv" in {
   def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_faceforward : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
 [IntrNoMem] >;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..8304077f049a3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3083,6 +3083,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
   case Intrinsic::spv_degrees:
 return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
+  case Intrinsic::spv_faceforward:
+return selectExtInst(ResVReg, ResType, I, GL::FaceForward);
   case Intrinsic::spv_frac:
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
new file mode 100644
index 0..4b34adc88c0f2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; Make sure SPIRV operation function calls for faceforward are lowered 
correctly.
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+
+define noundef <4 x half> @faceforward_half4(<4 x half> noundef %a, <4 x half> 
noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_16]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x half> @llvm.spv.faceforward.f16(<4 x half> %a, 
<4 x half> %b, <4 x half> %c)
+  ret <4 x half> %spv.faceforward
+}
+
+define noundef <4 x float> @faceforward_float4(<4 x float> noundef %a, <4 x 
float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_32]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] 
FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  %spv.faceforward = call <4 x float> @llvm.spv.faceforward.f32(<4 x float> 
%a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %spv.faceforward
+}
+
+declare <4 x half> @llvm.spv.faceforward.f16(<4 x half>, <4 x half>, <4 x 
half>)
+declare <4 x float> @llvm.spv.faceforward.f32(<4 x float>, <4 x float>, <4 x 
float>)

>From 06324ca82d3c593c801bf602b8f58683d13e738f Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Thu, 10 Apr 2025 14:55:17 -0700
Subject: [PATCH 2/2] implemented `faceforward` in `hlsl.Intrinsics.h` an

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-15 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Kaitlin Peng (kmpeng)


Changes

Resolves #99114. There will be a follow-up PR on pattern matching later.

Tasks completed:
- Implement `faceforward` in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h`
- Implement `faceforward` SPIR-V target builtin in 
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `hlsl_intrinsic_helpers.h`
- Add sema checks for `faceforward` to `CheckSPIRVBuiltinFunctionCall` in 
`clang/lib/Sema/SemaSPIRV.cpp`
- Add codegen for SPIR-V `faceforward` builtin to `EmitSPIRVBuiltinExpr` in 
`SPIR.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/faceforward.hlsl`
- Add SPIRV builtin codegen tests to 
`clang/test/CodeGenSPIRV/Builtins/faceforward.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl`
- Add spirv sema tests to `clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c`
- Create the `int_spv_faceforward` intrinsic in `IntrinsicsSPIRV.td`
- In `SPIRVInstructionSelector.cpp` create the `faceforward` lowering and map 
it to `int_spv_faceforward` in `SPIRVInstructionSelector::selectIntrinsic`
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll`

Incomplete tasks:
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/opencl/faceforward.ll`
  - Not applicable because the OpenCL SPIR-V extended instruction set does not 
include a `faceforward` function

---

Patch is 27.53 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/135878.diff


12 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsSPIRV.td (+6) 
- (modified) clang/lib/CodeGen/TargetBuiltins/SPIR.cpp (+12) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h (+18) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+47) 
- (modified) clang/lib/Sema/SemaSPIRV.cpp (+36) 
- (added) clang/test/CodeGenHLSL/builtins/faceforward.hlsl (+94) 
- (added) clang/test/CodeGenSPIRV/Builtins/faceforward.c (+35) 
- (added) clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl (+39) 
- (added) clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c (+54) 
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1) 
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2) 
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll (+60) 


``diff
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 9f76d672cc7ce..cc0c2f960f8d2 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -31,3 +31,9 @@ def SPIRVSmoothStep : Builtin {
   let Attributes = [NoThrow, Const, CustomTypeChecking];
   let Prototype = "void(...)";
 }
+
+def SPIRVFaceForward : Builtin {
+  let Spellings = ["__builtin_spirv_faceforward"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp 
b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
index 92e2c1c6da68f..c1bcc9ae084d0 100644
--- a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
@@ -71,6 +71,18 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 ArrayRef{Min, Max, X}, /*FMFSource=*/nullptr,
 "spv.smoothstep");
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+Value *N = EmitScalarExpr(E->getArg(0));
+Value *I = EmitScalarExpr(E->getArg(1));
+Value *Ng = EmitScalarExpr(E->getArg(2));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   E->getArg(2)->getType()->hasFloatingRepresentation() &&
+   "FaceForward operands must have a float representation");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/N->getType(), Intrinsic::spv_smoothstep,
+ArrayRef{N, I, Ng}, /*FMFSource=*/nullptr, "spv.faceforward");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 3a8a9b6fa2a45..b2332419dc034 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -126,6 +126,24 @@ template  constexpr vector lit_impl(T 
NDotL, T NDotH, T M) {
   return Result;
 }
 
+template  constexpr T faceforward_impl(T N, T I, T Ng) {
+#if (__has_builtin(__builtin_spirv_faceforward))
+  return __builtin_spirv_faceforward(N, I, Ng);
+#else
+  return select(I * Ng < 0, N, -N);
+#endif
+}
+
+template 
+constexpr vector faceforward_vec_impl(vector N, vector I,
+vector Ng) {
+#if (__has_builtin(__builtin_spirv_faceforward))
+  return __builtin_spirv_faceforward(N, I, Ng);
+#else
+  return select(dot(I, Ng) < 0, N, -N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 
diff --git a/clang/lib/Headers/hlsl/

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-15 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-spir-v

Author: Kaitlin Peng (kmpeng)


Changes

Resolves #99114. There will be a follow-up PR on pattern matching later.

Tasks completed:
- Implement `faceforward` in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h`
- Implement `faceforward` SPIR-V target builtin in 
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `hlsl_intrinsic_helpers.h`
- Add sema checks for `faceforward` to `CheckSPIRVBuiltinFunctionCall` in 
`clang/lib/Sema/SemaSPIRV.cpp`
- Add codegen for SPIR-V `faceforward` builtin to `EmitSPIRVBuiltinExpr` in 
`SPIR.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/faceforward.hlsl`
- Add SPIRV builtin codegen tests to 
`clang/test/CodeGenSPIRV/Builtins/faceforward.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl`
- Add spirv sema tests to `clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c`
- Create the `int_spv_faceforward` intrinsic in `IntrinsicsSPIRV.td`
- In `SPIRVInstructionSelector.cpp` create the `faceforward` lowering and map 
it to `int_spv_faceforward` in `SPIRVInstructionSelector::selectIntrinsic`
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll`

Incomplete tasks:
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/opencl/faceforward.ll`
  - Not applicable because the OpenCL SPIR-V extended instruction set does not 
include a `faceforward` function

---

Patch is 27.53 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/135878.diff


12 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsSPIRV.td (+6) 
- (modified) clang/lib/CodeGen/TargetBuiltins/SPIR.cpp (+12) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h (+18) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+47) 
- (modified) clang/lib/Sema/SemaSPIRV.cpp (+36) 
- (added) clang/test/CodeGenHLSL/builtins/faceforward.hlsl (+94) 
- (added) clang/test/CodeGenSPIRV/Builtins/faceforward.c (+35) 
- (added) clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl (+39) 
- (added) clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c (+54) 
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1) 
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2) 
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll (+60) 


``diff
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 9f76d672cc7ce..cc0c2f960f8d2 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -31,3 +31,9 @@ def SPIRVSmoothStep : Builtin {
   let Attributes = [NoThrow, Const, CustomTypeChecking];
   let Prototype = "void(...)";
 }
+
+def SPIRVFaceForward : Builtin {
+  let Spellings = ["__builtin_spirv_faceforward"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp 
b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
index 92e2c1c6da68f..c1bcc9ae084d0 100644
--- a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
@@ -71,6 +71,18 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 ArrayRef{Min, Max, X}, /*FMFSource=*/nullptr,
 "spv.smoothstep");
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+Value *N = EmitScalarExpr(E->getArg(0));
+Value *I = EmitScalarExpr(E->getArg(1));
+Value *Ng = EmitScalarExpr(E->getArg(2));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   E->getArg(2)->getType()->hasFloatingRepresentation() &&
+   "FaceForward operands must have a float representation");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/N->getType(), Intrinsic::spv_smoothstep,
+ArrayRef{N, I, Ng}, /*FMFSource=*/nullptr, "spv.faceforward");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 3a8a9b6fa2a45..b2332419dc034 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -126,6 +126,24 @@ template  constexpr vector lit_impl(T 
NDotL, T NDotH, T M) {
   return Result;
 }
 
+template  constexpr T faceforward_impl(T N, T I, T Ng) {
+#if (__has_builtin(__builtin_spirv_faceforward))
+  return __builtin_spirv_faceforward(N, I, Ng);
+#else
+  return select(I * Ng < 0, N, -N);
+#endif
+}
+
+template 
+constexpr vector faceforward_vec_impl(vector N, vector I,
+vector Ng) {
+#if (__has_builtin(__builtin_spirv_faceforward))
+  return __builtin_spirv_faceforward(N, I, Ng);
+#else
+  return select(dot(I, Ng) < 0, N, -N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 
diff --git a/clang/lib/Headers/hlsl

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-15 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-hlsl

Author: Kaitlin Peng (kmpeng)


Changes

Resolves #99114. There will be a follow-up PR on pattern matching later.

Tasks completed:
- Implement `faceforward` in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h`
- Implement `faceforward` SPIR-V target builtin in 
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `hlsl_intrinsic_helpers.h`
- Add sema checks for `faceforward` to `CheckSPIRVBuiltinFunctionCall` in 
`clang/lib/Sema/SemaSPIRV.cpp`
- Add codegen for SPIR-V `faceforward` builtin to `EmitSPIRVBuiltinExpr` in 
`SPIR.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/faceforward.hlsl`
- Add SPIRV builtin codegen tests to 
`clang/test/CodeGenSPIRV/Builtins/faceforward.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl`
- Add spirv sema tests to `clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c`
- Create the `int_spv_faceforward` intrinsic in `IntrinsicsSPIRV.td`
- In `SPIRVInstructionSelector.cpp` create the `faceforward` lowering and map 
it to `int_spv_faceforward` in `SPIRVInstructionSelector::selectIntrinsic`
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll`

Incomplete tasks:
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/opencl/faceforward.ll`
  - Not applicable because the OpenCL SPIR-V extended instruction set does not 
include a `faceforward` function

---

Patch is 27.53 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/135878.diff


12 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsSPIRV.td (+6) 
- (modified) clang/lib/CodeGen/TargetBuiltins/SPIR.cpp (+12) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h (+18) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+47) 
- (modified) clang/lib/Sema/SemaSPIRV.cpp (+36) 
- (added) clang/test/CodeGenHLSL/builtins/faceforward.hlsl (+94) 
- (added) clang/test/CodeGenSPIRV/Builtins/faceforward.c (+35) 
- (added) clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl (+39) 
- (added) clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c (+54) 
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1) 
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2) 
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll (+60) 


``diff
diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 9f76d672cc7ce..cc0c2f960f8d2 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -31,3 +31,9 @@ def SPIRVSmoothStep : Builtin {
   let Attributes = [NoThrow, Const, CustomTypeChecking];
   let Prototype = "void(...)";
 }
+
+def SPIRVFaceForward : Builtin {
+  let Spellings = ["__builtin_spirv_faceforward"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp 
b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
index 92e2c1c6da68f..c1bcc9ae084d0 100644
--- a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
@@ -71,6 +71,18 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 ArrayRef{Min, Max, X}, /*FMFSource=*/nullptr,
 "spv.smoothstep");
   }
+  case SPIRV::BI__builtin_spirv_faceforward: {
+Value *N = EmitScalarExpr(E->getArg(0));
+Value *I = EmitScalarExpr(E->getArg(1));
+Value *Ng = EmitScalarExpr(E->getArg(2));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   E->getArg(2)->getType()->hasFloatingRepresentation() &&
+   "FaceForward operands must have a float representation");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/N->getType(), Intrinsic::spv_smoothstep,
+ArrayRef{N, I, Ng}, /*FMFSource=*/nullptr, "spv.faceforward");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 3a8a9b6fa2a45..b2332419dc034 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -126,6 +126,24 @@ template  constexpr vector lit_impl(T 
NDotL, T NDotH, T M) {
   return Result;
 }
 
+template  constexpr T faceforward_impl(T N, T I, T Ng) {
+#if (__has_builtin(__builtin_spirv_faceforward))
+  return __builtin_spirv_faceforward(N, I, Ng);
+#else
+  return select(I * Ng < 0, N, -N);
+#endif
+}
+
+template 
+constexpr vector faceforward_vec_impl(vector N, vector I,
+vector Ng) {
+#if (__has_builtin(__builtin_spirv_faceforward))
+  return __builtin_spirv_faceforward(N, I, Ng);
+#else
+  return select(dot(I, Ng) < 0, N, -N);
+#endif
+}
+
 } // namespace __detail
 } // 

[clang] [llvm] [HLSL] Implement the `faceforward` intrinsic (PR #135878)

2025-04-15 Thread Kaitlin Peng via cfe-commits

https://github.com/kmpeng created 
https://github.com/llvm/llvm-project/pull/135878

Resolves #99114. There will be a follow-up PR on pattern matching later.

Tasks completed:
- Implement `faceforward` in `hlsl_intrinsics.h`/`hlsl_intrinsic_helpers.h`
- Implement `faceforward` SPIR-V target builtin in 
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `hlsl_intrinsic_helpers.h`
- Add sema checks for `faceforward` to `CheckSPIRVBuiltinFunctionCall` in 
`clang/lib/Sema/SemaSPIRV.cpp`
- Add codegen for SPIR-V `faceforward` builtin to `EmitSPIRVBuiltinExpr` in 
`SPIR.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/faceforward.hlsl`
- Add SPIRV builtin codegen tests to 
`clang/test/CodeGenSPIRV/Builtins/faceforward.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/faceforward-errors.hlsl`
- Add spirv sema tests to `clang/test/SemaSPIRV/BuiltIns/faceforward-errors.c`
- Create the `int_spv_faceforward` intrinsic in `IntrinsicsSPIRV.td`
- In `SPIRVInstructionSelector.cpp` create the `faceforward` lowering and map 
it to `int_spv_faceforward` in `SPIRVInstructionSelector::selectIntrinsic`
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll`

Incomplete tasks:
- Create SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/opencl/faceforward.ll`
  - Not applicable because the OpenCL SPIR-V extended instruction set does not 
include a `faceforward` function

>From fc4bb1c5747cb26fafab8bffa53c7b21e377d09e Mon Sep 17 00:00:00 2001
From: kmpeng 
Date: Mon, 7 Apr 2025 14:46:07 -0700
Subject: [PATCH 1/2] create int_spv_faceforward intrinsic, create faceforward
 lowering & map to int_spv_faceforward, create SPIR-V backend test case

---
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |  1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  2 ++
 .../SPIRV/hlsl-intrinsics/faceforward.ll  | 35 +++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td 
b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..77cca0a58424f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -67,6 +67,7 @@ let TargetPrefix = "spv" in {
   def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_distance : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_faceforward : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
 [IntrNoMem] >;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp 
b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..8304077f049a3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3083,6 +3083,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
   case Intrinsic::spv_degrees:
 return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
+  case Intrinsic::spv_faceforward:
+return selectExtInst(ResVReg, ResType, I, GL::FaceForward);
   case Intrinsic::spv_frac:
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll 
b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
new file mode 100644
index 0..4b34adc88c0f2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val --target-env vulkan1.3 %}
+
+; Make sure SPIRV operation function calls for faceforward are lowered 
correctly.
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+
+define noundef <4 x half> @faceforward_half4(<4 x half> noundef %a, <4 x half> 
noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#vec4_float_16]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_fl