[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-26 Thread Chris B via cfe-commits

https://github.com/llvm-beanz closed 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From f6188a3308188aa3037b05f685a6065bfc2d69fa Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/6] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..9cce89b92be309 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e457694e4625db..2c06c8edca329a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From f6188a3308188aa3037b05f685a6065bfc2d69fa Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/6] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..9cce89b92be309 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e457694e4625db..2c06c8edca329a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -17959,6 +17964,54 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  if (!getLangOpts().HLSL)
+return nullptr;
+
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }

llvm-beanz wrote:

nit:

```suggestion
  if (T0->isFloatingPointTy())
return Builder.CreateFMul(Op0, Op1, "dx.dot");
```

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -17959,6 +17964,54 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  if (!getLangOpts().HLSL)
+return nullptr;
+
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }
+
+  if (T0->isIntegerTy()) {
+return Builder.CreateMul(Op0, Op1, "dx.dot");
+  }

llvm-beanz wrote:

nit:
```suggestion
  if (T0->isIntegerTy())
return Builder.CreateMul(Op0, Op1, "dx.dot");
```

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm 
-disable-llvm-passes -verify -verify-ignore-unexpected
+
+float test_no_second_arg ( float2 p0) {
+  return __builtin_hlsl_dot ( p0 );
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
1}}
+}
+
+float test_too_many_arg ( float2 p0) {
+  return __builtin_hlsl_dot ( p0, p0, p0 );
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+//NOTE: eventually behavior should match builtin

llvm-beanz wrote:

I’m not sure this comment is accurate.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -17959,6 +17964,54 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  if (!getLangOpts().HLSL)
+return nullptr;
+
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }
+
+  if (T0->isIntegerTy()) {
+return Builder.CreateMul(Op0, Op1, "dx.dot");
+  }
+  // Bools should have been promoted
+  assert(
+  false &&
+  "Dot product on a scalar is only supported on integers and floats.");

llvm-beanz wrote:

Generally `assert(false)` should be unreachable.
```suggestion
  llvm_unreachable("Scalar dot product is only supported on ints and 
floats.");
```

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits

https://github.com/llvm-beanz approved this pull request.

A few small notes, but otherwise looks good.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm 
-disable-llvm-passes -verify -verify-ignore-unexpected
+
+float test_no_second_arg ( float2 p0) {
+  return __builtin_hlsl_dot ( p0 );
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
1}}
+}
+
+float test_too_many_arg ( float2 p0) {
+  return __builtin_hlsl_dot ( p0, p0, p0 );
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+//NOTE: eventually behavior should match builtin
+float test_dot_no_second_arg ( float2 p0) {
+  return dot ( p0 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-warning@-1 {{implicit conversion truncates vector: 'float3' (aka 
'vector') to 'float __attribute__((ext_vector_type(2)))' (vector of 2 
'float' values)}}
+}
+
+float test_dot_builtin_vector_size_mismatch ( float3 p0, float2 p1 ) {
+  return __builtin_hlsl_dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have 
the same type}}
+}
+
+float test_dot_scalar_mismatch ( float p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{call to 'dot' is ambiguous}}
+}
+
+float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{call to 'dot' is ambiguous}}

llvm-beanz wrote:

Can you add the cases like this that should work but fail to the XFAIL’d test 
case that has the other overload resolution bugs?

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits

https://github.com/llvm-beanz edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From f6188a3308188aa3037b05f685a6065bfc2d69fa Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/5] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..9cce89b92be309 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e457694e4625db..2c06c8edca329a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -5161,6 +5166,157 @@ bool Sema::CheckPPCMMAType(QualType Type, 
SourceLocation TypeLoc) {
   return false;
 }
 
+// Helper function for CheckHLSLBuiltinFunctionCall
+// Note: UsualArithmeticConversions handles the case where at least
+// one arg isn't a bool
+bool PromoteBoolsToInt(Sema *S, CallExpr *TheCall) {
+  unsigned NumArgs = TheCall->getNumArgs();
+
+  for (unsigned i = 0; i < NumArgs; ++i) {
+ExprResult A = TheCall->getArg(i);
+if (!A.get()->getType()->isBooleanType())
+  return false;
+  }
+  // if we got here all args are bool
+  for (unsigned i = 0; i < NumArgs; ++i) {
+ExprResult A = TheCall->getArg(i);
+ExprResult ResA = S->PerformImplicitConversion(A.get(), S->Context.IntTy,
+   Sema::AA_Converting);
+if (ResA.isInvalid())
+  return true;
+TheCall->setArg(i, ResA.get());
+  }
+  return false;
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+// Handles the CK_HLSLVectorTruncation case for builtins
+void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() > 1);
+  ExprResult A = TheCall->getArg(0);
+  ExprResult B = TheCall->getArg(1);
+  QualType ArgTyA = A.get()->getType();
+  QualType ArgTyB = B.get()->getType();
+
+  auto *VecTyA = ArgTyA->getAs();
+  auto *VecTyB = ArgTyB->getAs();
+  if (VecTyA == nullptr && VecTyB == nullptr)
+return;
+  if (VecTyA == nullptr || VecTyB == nullptr)
+return;
+  if (VecTyA->getNumElements() == VecTyB->getNumElements())
+return;
+
+  Expr *LargerArg = B.get();
+  Expr *SmallerArg = A.get();
+  int largerIndex = 1;
+  if (VecTyA->getNumElements() > VecTyB->getNumElements()) {
+LargerArg = A.get();
+SmallerArg = B.get();
+largerIndex = 0;
+  }
+
+  S->Diag(TheCall->getExprLoc(), diag::warn_hlsl_impcast_vector_truncation)
+  << LargerArg->getType() << SmallerArg->getType()
+  << LargerArg->getSourceRange() << SmallerArg->getSourceRange();
+  ExprResult ResLargerArg = S->ImpCastExprToType(
+  LargerArg, SmallerArg->getType(), CK_HLSLVectorTruncation);
+  TheCall->setArg(largerIndex, ResLargerArg.get());
+  return;
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+void CheckVectorFloatPromotion(Sema *S, ExprResult , QualType targetTy,
+   SourceRange targetSrcRange,
+   SourceLocation BuiltinLoc) {
+  auto *vecTyTarget = source.get()->getType()->getAs();
+  assert(vecTyTarget);
+  QualType vecElemT = vecTyTarget->getElementType();
+  if (!vecElemT->isFloatingType() && targetTy->isFloatingType()) {
+QualType floatVecTy = S->Context.getVectorType(
+S->Context.FloatTy, vecTyTarget->getNumElements(), 
VectorKind::Generic);
+
+S->Diag(BuiltinLoc, diag::warn_impcast_integer_float_precision)
+<< source.get()->getType() << floatVecTy
+<< source.get()->getSourceRange() << targetSrcRange;
+source = S->SemaConvertVectorExpr(
+source.get(), S->Context.CreateTypeSourceInfo(floatVecTy), BuiltinLoc,
+source.get()->getBeginLoc());
+  }
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+void PromoteVectorArgSplat(Sema *S, ExprResult , QualType targetTy) {
+  QualType sourceTy = source.get()->getType();
+  auto *vecTyTarget = targetTy->getAs();
+  QualType vecElemT = vecTyTarget->getElementType();
+  if (vecElemT->isFloatingType() && sourceTy != vecElemT)
+// if float vec splat wil do an unnecessary cast to double
+source = S->ImpCastExprToType(source.get(), vecElemT, CK_FloatingCast);
+  source = S->ImpCastExprToType(source.get(), targetTy, CK_VectorSplat);
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() > 1);
+  ExprResult A = TheCall->getArg(0);
+  ExprResult B = TheCall->getArg(1);
+  QualType ArgTyA = A.get()->getType();
+  QualType ArgTyB = B.get()->getType();
+  auto *VecTyA = ArgTyA->getAs();
+  auto *VecTyB = ArgTyB->getAs();
+
+  if (VecTyA == nullptr && VecTyB == nullptr)
+return false;
+
+  if (VecTyA && VecTyB) {
+if (VecTyA->getElementType() == VecTyB->getElementType()) {
+  TheCall->setType(VecTyA->getElementType());
+  return false;
+}
+// Note: type promotion is intended to be handeled via the intrinsics
+//  and not the builtin itself.
+S->Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_incompatible_vector)
+<< TheCall->getDirectCallee()
+<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc());
+return true;
+  }
+
+  if (VecTyB) {
+CheckVectorFloatPromotion(S, B, ArgTyA, A.get()->getSourceRange(),
+  TheCall->getBeginLoc());
+PromoteVectorArgSplat(S, A, B.get()->getType());
+  }
+  if (VecTyA) {
+CheckVectorFloatPromotion(S, A, ArgTyB, B.get()->getSourceRange(),
+  TheCall->getBeginLoc());
+PromoteVectorArgSplat(S, 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Farzon Lotfi via cfe-commits


@@ -5161,6 +5166,157 @@ bool Sema::CheckPPCMMAType(QualType Type, 
SourceLocation TypeLoc) {
   return false;
 }
 
+// Helper function for CheckHLSLBuiltinFunctionCall
+// Note: UsualArithmeticConversions handles the case where at least
+// one arg isn't a bool
+bool PromoteBoolsToInt(Sema *S, CallExpr *TheCall) {
+  unsigned NumArgs = TheCall->getNumArgs();
+
+  for (unsigned i = 0; i < NumArgs; ++i) {
+ExprResult A = TheCall->getArg(i);
+if (!A.get()->getType()->isBooleanType())
+  return false;
+  }
+  // if we got here all args are bool
+  for (unsigned i = 0; i < NumArgs; ++i) {
+ExprResult A = TheCall->getArg(i);
+ExprResult ResA = S->PerformImplicitConversion(A.get(), S->Context.IntTy,
+   Sema::AA_Converting);
+if (ResA.isInvalid())
+  return true;
+TheCall->setArg(i, ResA.get());
+  }
+  return false;
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+// Handles the CK_HLSLVectorTruncation case for builtins
+void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() > 1);
+  ExprResult A = TheCall->getArg(0);
+  ExprResult B = TheCall->getArg(1);
+  QualType ArgTyA = A.get()->getType();
+  QualType ArgTyB = B.get()->getType();
+
+  auto *VecTyA = ArgTyA->getAs();
+  auto *VecTyB = ArgTyB->getAs();
+  if (VecTyA == nullptr && VecTyB == nullptr)
+return;
+  if (VecTyA == nullptr || VecTyB == nullptr)
+return;
+  if (VecTyA->getNumElements() == VecTyB->getNumElements())
+return;
+
+  Expr *LargerArg = B.get();
+  Expr *SmallerArg = A.get();
+  int largerIndex = 1;
+  if (VecTyA->getNumElements() > VecTyB->getNumElements()) {
+LargerArg = A.get();
+SmallerArg = B.get();
+largerIndex = 0;
+  }
+
+  S->Diag(TheCall->getExprLoc(), diag::warn_hlsl_impcast_vector_truncation)
+  << LargerArg->getType() << SmallerArg->getType()
+  << LargerArg->getSourceRange() << SmallerArg->getSourceRange();
+  ExprResult ResLargerArg = S->ImpCastExprToType(
+  LargerArg, SmallerArg->getType(), CK_HLSLVectorTruncation);
+  TheCall->setArg(largerIndex, ResLargerArg.get());
+  return;
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+void CheckVectorFloatPromotion(Sema *S, ExprResult , QualType targetTy,
+   SourceRange targetSrcRange,
+   SourceLocation BuiltinLoc) {
+  auto *vecTyTarget = source.get()->getType()->getAs();
+  assert(vecTyTarget);
+  QualType vecElemT = vecTyTarget->getElementType();
+  if (!vecElemT->isFloatingType() && targetTy->isFloatingType()) {
+QualType floatVecTy = S->Context.getVectorType(
+S->Context.FloatTy, vecTyTarget->getNumElements(), 
VectorKind::Generic);
+
+S->Diag(BuiltinLoc, diag::warn_impcast_integer_float_precision)
+<< source.get()->getType() << floatVecTy
+<< source.get()->getSourceRange() << targetSrcRange;
+source = S->SemaConvertVectorExpr(
+source.get(), S->Context.CreateTypeSourceInfo(floatVecTy), BuiltinLoc,
+source.get()->getBeginLoc());
+  }
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+void PromoteVectorArgSplat(Sema *S, ExprResult , QualType targetTy) {
+  QualType sourceTy = source.get()->getType();
+  auto *vecTyTarget = targetTy->getAs();
+  QualType vecElemT = vecTyTarget->getElementType();
+  if (vecElemT->isFloatingType() && sourceTy != vecElemT)
+// if float vec splat wil do an unnecessary cast to double
+source = S->ImpCastExprToType(source.get(), vecElemT, CK_FloatingCast);
+  source = S->ImpCastExprToType(source.get(), targetTy, CK_VectorSplat);
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() > 1);
+  ExprResult A = TheCall->getArg(0);
+  ExprResult B = TheCall->getArg(1);
+  QualType ArgTyA = A.get()->getType();
+  QualType ArgTyB = B.get()->getType();
+  auto *VecTyA = ArgTyA->getAs();
+  auto *VecTyB = ArgTyB->getAs();
+
+  if (VecTyA == nullptr && VecTyB == nullptr)
+return false;
+
+  if (VecTyA && VecTyB) {
+if (VecTyA->getElementType() == VecTyB->getElementType()) {
+  TheCall->setType(VecTyA->getElementType());
+  return false;
+}
+// Note: type promotion is intended to be handeled via the intrinsics
+//  and not the builtin itself.
+S->Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_incompatible_vector)
+<< TheCall->getDirectCallee()
+<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc());
+return true;
+  }
+
+  if (VecTyB) {
+CheckVectorFloatPromotion(S, B, ArgTyA, A.get()->getSourceRange(),
+  TheCall->getBeginLoc());
+PromoteVectorArgSplat(S, A, B.get()->getType());
+  }
+  if (VecTyA) {
+CheckVectorFloatPromotion(S, A, ArgTyB, B.get()->getSourceRange(),
+  TheCall->getBeginLoc());
+PromoteVectorArgSplat(S, 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/4] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -17959,6 +17964,52 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  if (!getLangOpts().HLSL)
+return nullptr;
+
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }
+
+  if (T0->isIntegerTy()) {
+return Builder.CreateMul(Op0, Op1, "dx.dot");
+  }
+  // Bools should have been promoted
+  assert(
+  false &&
+  "Dot product on a scalar is only supported on integers and floats.");
+}
+// A VectorSplat should have happened
+assert(T0->isVectorTy() && T1->isVectorTy() &&
+   "Dot product of vector and scalar is not supported.");
+
+// A vector sext or sitofp should have happened
+assert(T0->getScalarType() == T1->getScalarType() &&
+   "Dot product of vectors need the same element types.");
+
+auto *VecTy0 = E->getArg(0)->getType()->getAs();
+auto *VecTy1 = E->getArg(1)->getType()->getAs();

llvm-beanz wrote:

These declarations need `[[maybe_unused]]` to avoid producing warnings in 
non-assert builds.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -2961,6 +2962,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
   }
   }
 
+  if (getLangOpts().HLSL && CheckHLSLBuiltinFunctionCall(BuiltinID, TheCall)) {
+return ExprError();
+  }

llvm-beanz wrote:

nit: unnecessary braces.

see: 
https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -5161,6 +5166,157 @@ bool Sema::CheckPPCMMAType(QualType Type, 
SourceLocation TypeLoc) {
   return false;
 }
 
+// Helper function for CheckHLSLBuiltinFunctionCall
+// Note: UsualArithmeticConversions handles the case where at least
+// one arg isn't a bool
+bool PromoteBoolsToInt(Sema *S, CallExpr *TheCall) {
+  unsigned NumArgs = TheCall->getNumArgs();
+
+  for (unsigned i = 0; i < NumArgs; ++i) {
+ExprResult A = TheCall->getArg(i);
+if (!A.get()->getType()->isBooleanType())
+  return false;
+  }
+  // if we got here all args are bool
+  for (unsigned i = 0; i < NumArgs; ++i) {
+ExprResult A = TheCall->getArg(i);
+ExprResult ResA = S->PerformImplicitConversion(A.get(), S->Context.IntTy,
+   Sema::AA_Converting);
+if (ResA.isInvalid())
+  return true;
+TheCall->setArg(i, ResA.get());
+  }
+  return false;
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+// Handles the CK_HLSLVectorTruncation case for builtins
+void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() > 1);
+  ExprResult A = TheCall->getArg(0);
+  ExprResult B = TheCall->getArg(1);
+  QualType ArgTyA = A.get()->getType();
+  QualType ArgTyB = B.get()->getType();
+
+  auto *VecTyA = ArgTyA->getAs();
+  auto *VecTyB = ArgTyB->getAs();
+  if (VecTyA == nullptr && VecTyB == nullptr)
+return;
+  if (VecTyA == nullptr || VecTyB == nullptr)
+return;
+  if (VecTyA->getNumElements() == VecTyB->getNumElements())
+return;
+
+  Expr *LargerArg = B.get();
+  Expr *SmallerArg = A.get();
+  int largerIndex = 1;
+  if (VecTyA->getNumElements() > VecTyB->getNumElements()) {
+LargerArg = A.get();
+SmallerArg = B.get();
+largerIndex = 0;
+  }
+
+  S->Diag(TheCall->getExprLoc(), diag::warn_hlsl_impcast_vector_truncation)
+  << LargerArg->getType() << SmallerArg->getType()
+  << LargerArg->getSourceRange() << SmallerArg->getSourceRange();
+  ExprResult ResLargerArg = S->ImpCastExprToType(
+  LargerArg, SmallerArg->getType(), CK_HLSLVectorTruncation);
+  TheCall->setArg(largerIndex, ResLargerArg.get());
+  return;
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+void CheckVectorFloatPromotion(Sema *S, ExprResult , QualType targetTy,
+   SourceRange targetSrcRange,
+   SourceLocation BuiltinLoc) {
+  auto *vecTyTarget = source.get()->getType()->getAs();
+  assert(vecTyTarget);
+  QualType vecElemT = vecTyTarget->getElementType();
+  if (!vecElemT->isFloatingType() && targetTy->isFloatingType()) {
+QualType floatVecTy = S->Context.getVectorType(
+S->Context.FloatTy, vecTyTarget->getNumElements(), 
VectorKind::Generic);
+
+S->Diag(BuiltinLoc, diag::warn_impcast_integer_float_precision)
+<< source.get()->getType() << floatVecTy
+<< source.get()->getSourceRange() << targetSrcRange;
+source = S->SemaConvertVectorExpr(
+source.get(), S->Context.CreateTypeSourceInfo(floatVecTy), BuiltinLoc,
+source.get()->getBeginLoc());
+  }
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+void PromoteVectorArgSplat(Sema *S, ExprResult , QualType targetTy) {
+  QualType sourceTy = source.get()->getType();
+  auto *vecTyTarget = targetTy->getAs();
+  QualType vecElemT = vecTyTarget->getElementType();
+  if (vecElemT->isFloatingType() && sourceTy != vecElemT)
+// if float vec splat wil do an unnecessary cast to double
+source = S->ImpCastExprToType(source.get(), vecElemT, CK_FloatingCast);
+  source = S->ImpCastExprToType(source.get(), targetTy, CK_VectorSplat);
+}
+
+// Helper function for CheckHLSLBuiltinFunctionCall
+bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() > 1);
+  ExprResult A = TheCall->getArg(0);
+  ExprResult B = TheCall->getArg(1);
+  QualType ArgTyA = A.get()->getType();
+  QualType ArgTyB = B.get()->getType();
+  auto *VecTyA = ArgTyA->getAs();
+  auto *VecTyB = ArgTyB->getAs();
+
+  if (VecTyA == nullptr && VecTyB == nullptr)
+return false;
+
+  if (VecTyA && VecTyB) {
+if (VecTyA->getElementType() == VecTyB->getElementType()) {
+  TheCall->setType(VecTyA->getElementType());
+  return false;
+}
+// Note: type promotion is intended to be handeled via the intrinsics
+//  and not the builtin itself.
+S->Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_incompatible_vector)
+<< TheCall->getDirectCallee()
+<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc());
+return true;
+  }
+
+  if (VecTyB) {
+CheckVectorFloatPromotion(S, B, ArgTyA, A.get()->getSourceRange(),
+  TheCall->getBeginLoc());
+PromoteVectorArgSplat(S, A, B.get()->getType());
+  }
+  if (VecTyA) {
+CheckVectorFloatPromotion(S, A, ArgTyB, B.get()->getSourceRange(),
+  TheCall->getBeginLoc());
+PromoteVectorArgSplat(S, 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -19594,23 +19750,45 @@ bool 
Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
   TheCall->setArg(0, A.get());
   QualType TyA = A.get()->getType();
 
-  if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA))
+  if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
 return true;
 
   TheCall->setType(TyA);
   return false;
 }
 
 bool Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall) {
+  QualType Res;
+  bool result = SemaBuiltinVectorMath(TheCall, Res);
+  if (result)

llvm-beanz wrote:

nit:

```suggestion
  if (SemaBuiltinVectorMath(TheCall, Res))
```

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -19594,23 +19750,45 @@ bool 
Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
   TheCall->setArg(0, A.get());
   QualType TyA = A.get()->getType();
 
-  if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA))
+  if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
 return true;
 
   TheCall->setType(TyA);
   return false;
 }
 
 bool Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall) {
+  QualType Res;
+  bool result = SemaBuiltinVectorMath(TheCall, Res);
+  if (result)
+return true;
+  TheCall->setType(Res);
+  return false;
+}
+
+bool Sema::SemaBuiltinVectorToScalarMath(CallExpr *TheCall) {
+  QualType Res;
+  bool result = SemaBuiltinVectorMath(TheCall, Res);
+  if (result)

llvm-beanz wrote:

nit:

```suggestion
  if (SemaBuiltinVectorMath(TheCall, Res))
```

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -19594,23 +19750,45 @@ bool 
Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
   TheCall->setArg(0, A.get());
   QualType TyA = A.get()->getType();
 
-  if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA))
+  if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
 return true;
 
   TheCall->setType(TyA);
   return false;
 }
 
 bool Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall) {
+  QualType Res;
+  bool result = SemaBuiltinVectorMath(TheCall, Res);
+  if (result)
+return true;
+  TheCall->setType(Res);
+  return false;
+}
+
+bool Sema::SemaBuiltinVectorToScalarMath(CallExpr *TheCall) {
+  QualType Res;
+  bool result = SemaBuiltinVectorMath(TheCall, Res);
+  if (result)
+return true;
+
+  if (auto *VecTy0 = Res->getAs()) {
+TheCall->setType(VecTy0->getElementType());
+  } else {
+TheCall->setType(Res);
+  }

llvm-beanz wrote:

Unnecessary braces.

See: 
https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Chris B via cfe-commits


@@ -179,6 +179,98 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)

llvm-beanz wrote:

Can you add a doxygen comment above the first declaration?

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-23 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/4] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl ready_for_review 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl deleted 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-22 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..5999b1ced36347 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..c76c0df28334f8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14057,6 +14057,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..393ab497fb15c4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-21 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 595ce41f71bd9e0f83679bd5c742b3015bf30626 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/2] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6e3cebc311eeb9..46f5424038d8b0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89215bf3d1c69a..6fe10fad45daff 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14055,6 +14055,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d454ccc1dd8613..4bad41a9be214e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-21 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl converted_to_draft 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-20 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 595ce41f71bd9e0f83679bd5c742b3015bf30626 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH 1/2] [HLSL] Implementation of dot intrinsic This change
 implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6e3cebc311eeb9..46f5424038d8b0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89215bf3d1c69a..6fe10fad45daff 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14055,6 +14055,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d454ccc1dd8613..4bad41a9be214e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-17 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 586ee65c5e820365a6fd150d7f246fbfa679ec3e Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6e3cebc311eeb9..46f5424038d8b0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e9cd42ae777df5..3557db56905ff8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14055,6 +14055,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d454ccc1dd8613..4bad41a9be214e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Xiang Li via cfe-commits

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


https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Farzon Lotfi (farzonl)


Changes

This change implements https://github.com/llvm/llvm-project/issues/70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp  SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr - EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h  SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, 
a language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.

---

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


10 Files Affected:

- (modified) clang/include/clang/Basic/Builtins.td (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/include/clang/Sema/Sema.h (+1) 
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+49) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+1) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+92) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+79-5) 
- (added) clang/test/CodeGenHLSL/builtins/dot.hlsl (+216) 
- (added) clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl (+46) 
- (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+5) 


``diff
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fb44495199ee56..9957f4e743e9cb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e9cd42ae777df5..3557db56905ff8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14055,6 +14055,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d454ccc1dd8613..4bad41a9be214e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
   }
 
+  // EmitHLSLBuiltinExpr will 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-x86

Author: Farzon Lotfi (farzonl)


Changes

This change implements https://github.com/llvm/llvm-project/issues/70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp  SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr - EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h  SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, 
a language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.

---

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


10 Files Affected:

- (modified) clang/include/clang/Basic/Builtins.td (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/include/clang/Sema/Sema.h (+1) 
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+49) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+1) 
- (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+92) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+79-5) 
- (added) clang/test/CodeGenHLSL/builtins/dot.hlsl (+216) 
- (added) clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl (+46) 
- (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+5) 


``diff
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fb44495199ee56..9957f4e743e9cb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e9cd42ae777df5..3557db56905ff8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14055,6 +14055,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d454ccc1dd8613..4bad41a9be214e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
   }
 
+  // EmitHLSLBuiltinExpr will check 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl ready_for_review 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread David Peixotto via cfe-commits

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

LGTM

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From bebb3ad19cc1793090265e68b25c282f90b35227 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fb44495199ee56..9957f4e743e9cb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e9cd42ae777df5..3557db56905ff8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14055,6 +14055,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d454ccc1dd8613..4bad41a9be214e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],
+[IntrNoMem, IntrWillReturn, Commutative] >;

farzonl wrote:

with inclusion of i64 I don't think this request is needed anymore. 

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl deleted 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

farzonl wrote:

I think we all came to agreement these should be added back so updated the pr 
to add support back.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-16 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From f6dbbfbf6b8aa221035e39735c5c6e2d0936219c Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  92 
 clang/lib/Sema/SemaChecking.cpp   |  84 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 216 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 497 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fb44495199ee56..9957f4e743e9cb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 53f06bcaeca166..d79fd07c8069e5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14054,6 +14054,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9bc60466d09be6..1d8c1d26470639 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread David Peixotto via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

dmpots wrote:

Why are there no hlsl dot overloads for the 64-bit integer vectors here? The 
32-bit integer vector dot functions also do not map to dxil ops (they are 
expanded to IMad). Since there are no dxil overloads for integer dot it seems 
like we should be consistent in what we support for the hlsl integer overloads.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread David Peixotto via cfe-commits


@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF

dmpots wrote:

The test looks much better now and makes a lot more sense to me.

I still think we are missing out on opportunities to strengthen our testing. 
The two RUN lines are checking the cases where we have native 16-bit types or 
not. There are many CHECKS here that are only being validated when 16-bit types 
are enabled, but are fully valid when 16-bit types are not enabled.

For example,
```
// CHECK: %dx.dot = mul i32 %0, %1
// CHECK: ret i32 %dx.dot
int test_dot_int ( int p0, int p1 ) {
  return dot ( p0, p1 );
}
```
is equally valid whether 16-bit types are enabled or not, but we only check it 
when 16-bit types are enabled. 

If we used 3 different check prefixes (`CHECK`, `NO_HALF`, `NATIVE_HALF`) then 
it would give better coverage and make it clearer where we expect the 
differences to be.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread Farzon Lotfi via cfe-commits


@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected
+
+float test_first_arg_is_not_vector ( float p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to 'dot' must be vectors}}
+}
+
+float test_second_arg_is_not_vector ( float2 p0, float p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to 'dot' must be vectors}}
+}
+
+int test_dot_unsupported_scalar_arg0 ( bool p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{1st argument must be a vector, integer or floating 
point type (was 'bool')}}
+}
+
+int test_dot_unsupported_scalar_arg1 ( int p0, bool p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{2nd argument must be a vector, integer or floating 
point type (was 'bool')}}
+}
+
+float test_dot_scalar_mismatch ( float p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{call to 'dot' is ambiguous}}
+}
+
+float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test__no_second_arg ( float2 p0) {
+  return dot ( p0 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}

farzonl wrote:

I've listed thes tests as `XFAIL` so that when the behavior changes this 
testcase won't fail with it.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread Farzon Lotfi via cfe-commits


@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF

farzonl wrote:

This Pr fixed a bunch of the  issues mentioned: 
https://github.com/llvm/llvm-project/pull/81782/files
I've updated these tests to be similar.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 2baaf5b41d80639fa7dfe739ad5501d2f5359bfa Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  80 
 clang/lib/Sema/SemaChecking.cpp   |  84 +++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 179 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 +
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 448 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fb44495199ee56..9957f4e743e9cb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 53f06bcaeca166..d79fd07c8069e5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14054,6 +14054,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9bc60466d09be6..1d8c1d26470639 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 4bf50e02554460df86903791380fb5ca17a28bdc 
23c277da327c595633d159c13bc710f413024cb2 -- clang/include/clang/Sema/Sema.h 
clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CodeGenFunction.h 
clang/lib/Headers/hlsl/hlsl_intrinsics.h clang/lib/Sema/SemaChecking.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c488eee456..b5f3f8b2e9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5212,7 +5212,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 if (VecTy0->getElementType() != VecTy1->getElementType()) {
   // Note: This case should never happen. If type promotion occurs
   // then element types won't be different. This diag error is here
-  // b\c EmitHLSLBuiltinExpr asserts on this case. 
+  // b\c EmitHLSLBuiltinExpr asserts on this case.
   Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
   << TheCall->getDirectCallee()
   << SourceRange(TheCall->getArg(0)->getBeginLoc(),

``




https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-15 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 23c277da327c595633d159c13bc710f413024cb2 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is language specific intrinsic and so is guarded behind 
getLangOpts().HLSL.
The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp

EmitHLSLBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
language specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  50 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  80 
 clang/lib/Sema/SemaChecking.cpp   |  84 +++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 179 ++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl  |  46 +
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   5 +
 10 files changed, 449 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index df74026c5d2d50..771c4f5d4121f4 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fb44495199ee56..9957f4e743e9cb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error<
  "first two arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<
   "first two arguments to %0 must have the same type">;
+def err_vec_builtin_incompatible_size : Error<
+  "first two arguments to %0 must have the same size">;
 def err_vsx_builtin_nonconstant_argument : Error<
   "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 53f06bcaeca166..d79fd07c8069e5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14054,6 +14054,7 @@ class Sema final {
   bool CheckPPCBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
   bool CheckRISCVBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
  CallExpr *TheCall);
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9bc60466d09be6..ae5d8ae36f0065 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -5982,6 +5983,10 @@ RValue 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread David Peixotto via cfe-commits


@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF

dmpots wrote:

I don't think this should be a special case. I think the existing pattern is 
confusing and I would rather not extend it here if not required and I think it 
would be good to update the other tests with something that is better (in my 
opinion).

I am also confused about how this is working. There are a number of test 
functions that are only defined under the `__HLSL_ENABLE_16_BIT` define,

```
#ifdef __HLSL_ENABLE_16_BIT
// CHECK: %dx.dot = mul i16 %0, %1
// CHECK: ret i16 %dx.dot
// NO_HALF: %dx.dot = mul i16 %0, %1
// NO_HALF: ret i16 %dx.dot
int16_t test_dot_short ( int16_t p0, int16_t p1 ) {
  return dot ( p0, p1 );
}
```

That define is only given on the second RUN line, but there are `CHECKS` for 
the first RUN line. How can those checks be passing if that define is not valid?

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread Farzon Lotfi via cfe-commits


@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF

farzonl wrote:

You are correct only lines 140-170 for the half cases are going to be 
different. They are supposed to be the same except for the float16 cases. I'm 
not sure I agree with the suggestion, `NO_HALF` is how we are doing all the 
other intrinsics I don't understand why this needs to be a special case..,

That said I can model these tests more like sin.hlsl where we only do the half 
checks on the half code:
https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenHLSL/builtins/sin.hlsl#L8C1-L35C2

And not like 
https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenHLSL/builtins/max.hlsl
 where we do it on every test case if you think that would add some clarity.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread Farzon Lotfi via cfe-commits


@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected
+
+float test_first_arg_is_not_vector ( float p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to 'dot' must be vectors}}
+}
+
+float test_second_arg_is_not_vector ( float2 p0, float p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to 'dot' must be vectors}}
+}
+
+int test_dot_unsupported_scalar_arg0 ( bool p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{1st argument must be a vector, integer or floating 
point type (was 'bool')}}
+}
+
+int test_dot_unsupported_scalar_arg1 ( int p0, bool p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{2nd argument must be a vector, integer or floating 
point type (was 'bool')}}
+}
+
+float test_dot_scalar_mismatch ( float p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{call to 'dot' is ambiguous}}
+}
+
+float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test__no_second_arg ( float2 p0) {
+  return dot ( p0 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}

farzonl wrote:

see @llvm-beanz  comment: 
https://github.com/llvm/llvm-project/pull/81190#discussion_r1488101504. His PR 
needs to land. Once it does I suspect I will be able to remove this test case.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread David Peixotto via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

dmpots wrote:

I am still not clear on exactly which overloads you are proposing that we 
support.

> my preference is to not have overloads that don't lower to DXIL ops

So that would mean no scalar overloads at all (since those lower to multiply) 
and no double overloads. But keep support for i64 and u64 vector overloads?

As for silently generating less efficient code I am somewhat skeptical that 
there is GPU hardware that will accelerate 64-bit dot operations. My guess is 
those all get expanded by the target anyway.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread David Peixotto via cfe-commits


@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected
+
+float test_first_arg_is_not_vector ( float p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to 'dot' must be vectors}}
+}
+
+float test_second_arg_is_not_vector ( float2 p0, float p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{first two arguments to 'dot' must be vectors}}
+}
+
+int test_dot_unsupported_scalar_arg0 ( bool p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{1st argument must be a vector, integer or floating 
point type (was 'bool')}}
+}
+
+int test_dot_unsupported_scalar_arg1 ( int p0, bool p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{2nd argument must be a vector, integer or floating 
point type (was 'bool')}}
+}
+
+float test_dot_scalar_mismatch ( float p0, int p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{call to 'dot' is ambiguous}}
+}
+
+float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test__no_second_arg ( float2 p0) {
+  return dot ( p0 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}
+}
+
+float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) {
+  return dot ( p0, p1 );
+  // expected-error@-1 {{no matching function for call to 'dot'}}

dmpots wrote:

I am a bit surprised by the error here. I would expect `p0` to be promoted to 
`float2` and then call the `dot(float2, float2)` overload.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread David Peixotto via cfe-commits


@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF

dmpots wrote:

I am having a hard time seeing the difference between the `CHECK` and `NO_HALF` 
checks below. It looks like a lot of them are the same.


>From the command line it looks like the difference is the `-fnative-half-type` 
>flag which means that only the `half` tests should be different. I think in 
>this case it is better to organize the check lines in a way that highlights 
>those differences.

I would suggest using 3 check prefixes like `CHECK`, `NATIVE_HALF`, `NO_HALF`. 
The CHECK prefix will be common to both run lines and the two half ones will 
depend on the native-half-type flag.

```
RUN: clang ... -fnative-half-type ... | FileCheck %s 
-check-prefixes=CHECK,NATIVE_HALF
RUN: clang ...... | FileCheck %s 
-check-prefixes=CHECK,NO_HALF
```

That way you only need to use the NATIVE_HALF and NO_HALF check prefixes when 
there should be actual differences between them.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread Chris B via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

llvm-beanz wrote:

There's two things I don't like about what DXC does here:
1) It is inconsistent. Which is painful to deal with...
2) It silently generates less efficient code without telling the user anything.

We might need to have a proper discussion about this, but my preference is to 
not have overloads that don't lower to DXIL ops. While that is different from 
DXC, and will result in different code generation, it will also result in 
conversion warnings, so the user at least has a way to know that it isn't 
working as expected.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread Chris B via cfe-commits


@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];

llvm-beanz wrote:

The overload resolution issues you're hitting are currently expected. PR 
#71098, implements handling for the vector element conversions, although there 
are still some issues lingering around HLSL's rules for promotions and 
conversions (https://github.com/llvm/llvm-project/issues/81047 & 
https://github.com/llvm/llvm-project/issues/81049).

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-13 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 73cc9fde36a44ba1715a3c9fc6d48196602d5dc4 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in BuiltinsHLSL.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

As a side note adding the dot product intrinsic to BuiltinsHLSL.td had a
significant impact on re-compile time speeds. I recommend we move the
other hlsl functions here. Further it lets us tap into the existing
target specifc code organizations that exist in Sema and CodeGen.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is a target specific intrinsic and so needed to establish
a pattern for Target builtins via EmitDXILBuiltinExpr.
The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> 
EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp

EmitDXILBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
target specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/BuiltinsHLSL.td|  15 ++
 clang/include/clang/Basic/CMakeLists.txt |   6 +-
 clang/include/clang/Basic/TargetBuiltins.h   |  10 +
 clang/include/clang/Sema/Sema.h  |   1 +
 clang/lib/Basic/Targets/DirectX.cpp  |  13 ++
 clang/lib/Basic/Targets/DirectX.h|   4 +-
 clang/lib/CodeGen/CGBuiltin.cpp  |  41 
 clang/lib/CodeGen/CodeGenFunction.h  |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h |  68 +++
 clang/lib/Sema/SemaChecking.cpp  |  71 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl | 202 +++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl |  43 
 llvm/include/llvm/IR/IntrinsicsDirectX.td|   5 +
 13 files changed, 471 insertions(+), 9 deletions(-)
 create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td 
b/clang/include/clang/Basic/BuiltinsHLSL.td
new file mode 100644
index 00..edff801f905641
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsHLSL.td
@@ -0,0 +1,15 @@
+//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+include "clang/Basic/BuiltinsBase.td"
+
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index 7785fb430c069b..01233eb44feffc 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -65,7 +65,11 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins
   SOURCE BuiltinsBPF.td
   TARGET ClangBuiltinsBPF)
 
-clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins
+clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins
+  SOURCE BuiltinsHLSL.td
+  TARGET ClangBuiltinsHLSL)
+
+  clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins
   SOURCE BuiltinsRISCV.td
   TARGET ClangBuiltinsRISCV)
 
diff --git a/clang/include/clang/Basic/TargetBuiltins.h 
b/clang/include/clang/Basic/TargetBuiltins.h
index 4333830bf34f24..15cf111ae5e9e5 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -89,6 +89,16 @@ namespace clang {
   };
   }
 
+  /// HLSL builtins
+  namespace hlsl {
+  enum {
+LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsHLSL.inc"
+LastTSBuiltin
+  };
+  } // namespace hlsl
+
   /// PPC 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 4103940b5a2578efc08df554ccdf80cb34925d09 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in BuiltinsHLSL.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

As a side note adding the dot product intrinsic to BuiltinsHLSL.td had a
significant impact on re-compile time speeds. I recommend we move the
other hlsl functions here. Further it lets us tap into the existing
target specifc code organizations that exist in Sema and CodeGen.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is a target specific intrinsic and so needed to establish
a pattern for Target builtins via EmitDXILBuiltinExpr.
The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> 
EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp

EmitDXILBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
target specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/BuiltinsHLSL.td|  15 ++
 clang/include/clang/Basic/CMakeLists.txt |   4 +
 clang/include/clang/Basic/TargetBuiltins.h   |  10 +
 clang/include/clang/Sema/Sema.h  |   1 +
 clang/lib/Basic/Targets/DirectX.cpp  |  13 ++
 clang/lib/Basic/Targets/DirectX.h|   4 +-
 clang/lib/CodeGen/CGBuiltin.cpp  |  41 
 clang/lib/CodeGen/CodeGenFunction.h  |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h |  68 +++
 clang/lib/Sema/SemaChecking.cpp  |  71 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl | 202 +++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl |  43 
 llvm/include/llvm/IR/IntrinsicsDirectX.td|   5 +
 13 files changed, 470 insertions(+), 8 deletions(-)
 create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td 
b/clang/include/clang/Basic/BuiltinsHLSL.td
new file mode 100644
index 00..edff801f905641
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsHLSL.td
@@ -0,0 +1,15 @@
+//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+include "clang/Basic/BuiltinsBase.td"
+
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index 9689a0f48c3ca3..29e5211602a9c8 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -65,6 +65,10 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins
   SOURCE BuiltinsBPF.td
   TARGET ClangBuiltinsBPF)
 
+  clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins
+  SOURCE BuiltinsHLSL.td
+  TARGET ClangBuiltinsHLSL)
+
 # ARM NEON and MVE
 clang_tablegen(arm_neon.inc -gen-arm-neon-sema
   SOURCE arm_neon.td
diff --git a/clang/include/clang/Basic/TargetBuiltins.h 
b/clang/include/clang/Basic/TargetBuiltins.h
index a4abaaef44c06c..38452553bd2df2 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -89,6 +89,16 @@ namespace clang {
   };
   }
 
+  /// HLSL builtins
+  namespace hlsl {
+  enum {
+LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsHLSL.inc"
+LastTSBuiltin
+  };
+  } // namespace hlsl
+
   /// PPC builtins
   namespace PPC {
 enum {
diff --git 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);

farzonl wrote:

mentioned in another conversation. only the scalar case of double remains. 

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],

farzonl wrote:

@python3kgae  Are you ok with leaving this as is?

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],
+[IntrNoMem, IntrWillReturn, Commutative] >;

farzonl wrote:

This might have to come later when I start to work  on lowering.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

farzonl wrote:

1. I removed the  `int64` and `uint64`  support and tests, but it does seem 
like it is supported see `fn6` and `fn7`. Left the scalar support for both.
2. You are correct no double vector support so removed it. However scalar 
double is supported see `fn8`. Left this one.

https://godbolt.org/z/vT9xTMffE


https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits


@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];

farzonl wrote:

I have added SemaChecking 
However I have 4 cases I can't check via `SemaChecking.cpp` Because
`BuildRecoveryCallExpr` is usurping calls to `BuildResolvedCallExpr`. 
This seems to be caused by how we are defining apis via `hlsl_intrinsics.h` and 
it doesn't seem to matter if I added Types to the table gen or not like so
```python
class HLSLMathTemplate : Template<["__fp16", "float", "double", "short", "int", 
"int64_t", "unsigned short", "uint32_t", "uint64_t" ],
  ["f16","",  "f64","i16",   "i32", 
"i64", "u16","u32",  "u64"]>;

def HLSLDotProduct : LangBuiltin<"HLSL_LANG">, HLSLMathTemplate {
  let Spellings = ["__builtin_hlsl_dot"];
  let Attributes = [NoThrow, Const, CustomTypeChecking];
  let Prototype = "T(_Complex T , _Complex T )";
}
```
Example test cases that hit `BuildRecoveryCallExpr`:
```hlsl
float test_dot_scalar_mismatch ( float p0, int p1 ) {
  return dot ( p0, p1 );
}

float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) {
  return dot ( p0, p1 );
}

float test__no_second_arg ( float2 p0) {
  return dot ( p0 );
}

float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) {
  return dot ( p0, p1 );
}
```

For example If we take `sin`:

```hlsl
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN:   -emit-llvm -disable-llvm-passes  -o -

float4 test( int4 p0) {
  return sin ( p0 );
}
```
I get the same errors:

```
clang\test\CodeGenHLSL\builtins\dot2.hlsl:6:10: error: no matching function for 
call to 'sin'
6 |   return sin ( p0 );
  |  ^~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:611:6:
 note: candidate function not viable: no known conversion from 'int4' (aka 
'vector') to 'half' for 1st argument
  611 | half sin(half);
  |  ^   
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:613:7:
 note: candidate function not viable: no known conversion from 'vector' 
to 'vector' for 1st argument
  613 | half2 sin(half2);
  |   ^   ~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:615:7:
 note: candidate function not viable: no known conversion from 'vector' 
to 'vector' for 1st argument
  615 | half3 sin(half3);
  |   ^   ~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:617:7:
 note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument
  617 | half4 sin(half4);
  |   ^   ~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:621:7:
 note: candidate function not viable: no known conversion from 'int4' (aka 
'vector') to 'float' for 1st argument
  621 | float sin(float);
  |   ^   ~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:623:8:
 note: candidate function not viable: no known conversion from 'vector' 
to 'vector' for 1st argument
  623 | float2 sin(float2);
  |^   ~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:625:8:
 note: candidate function not viable: no known conversion from 'vector' 
to 'vector' for 1st argument
  625 | float3 sin(float3);
  |^   ~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:627:8:
 note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument
  627 | float4 sin(float4);
  |^   ~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:630:8:
 note: candidate function not viable: no known conversion from 'int4' (aka 
'vector') to 'double' for 1st argument
  630 | double sin(double);
  |^   ~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:632:9:
 note: candidate function not viable: no known conversion from 'vector' 
to 'vector' for 1st argument
  632 | double2 sin(double2);
  | ^   ~~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:634:9:
 note: candidate function not viable: no known conversion from 'vector' 
to 'vector' for 1st argument
  634 | double3 sin(double3);
  | ^   ~~~
D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:636:9:
 note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument
  636 | double4 sin(double4);
  | ^   ~~~
1 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-12 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl updated 
https://github.com/llvm/llvm-project/pull/81190

>From 5082bc7fb49761424c7984a594a5afad9a03f04d Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in BuiltinsHLSL.td.
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp.

As a side note adding the dot product intrinsic to BuiltinsHLSL.td had a
significant impact on re-compile time speeds. I recommend we move the
other hlsl functions here. Further it lets us tap into the existing
target specifc code organizations that exist in Sema and CodeGen.

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is a target specific intrinsic and so needed to establish
a pattern for Target builtins via EmitDXILBuiltinExpr.
The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> 
EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp

EmitDXILBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.

Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a 
target specific semantic validation that can be expanded for other hlsl 
specific intrinsics.
---
 clang/include/clang/Basic/BuiltinsHLSL.td|  15 ++
 clang/include/clang/Basic/CMakeLists.txt |   4 +
 clang/include/clang/Basic/TargetBuiltins.h   |  10 +
 clang/include/clang/Sema/Sema.h  |   1 +
 clang/lib/Basic/Targets/DirectX.cpp  |  13 ++
 clang/lib/Basic/Targets/DirectX.h|   4 +-
 clang/lib/CodeGen/CGBuiltin.cpp  |  41 
 clang/lib/CodeGen/CodeGenFunction.h  |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h |  68 +++
 clang/lib/Sema/SemaChecking.cpp  |  74 ++-
 clang/test/CodeGenHLSL/builtins/dot.hlsl | 202 +++
 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl |  43 
 llvm/include/llvm/IR/IntrinsicsDirectX.td|   5 +
 13 files changed, 473 insertions(+), 8 deletions(-)
 create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl

diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td 
b/clang/include/clang/Basic/BuiltinsHLSL.td
new file mode 100644
index 00..edff801f905641
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsHLSL.td
@@ -0,0 +1,15 @@
+//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+include "clang/Basic/BuiltinsBase.td"
+
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index 9689a0f48c3ca3..29e5211602a9c8 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -65,6 +65,10 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins
   SOURCE BuiltinsBPF.td
   TARGET ClangBuiltinsBPF)
 
+  clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins
+  SOURCE BuiltinsHLSL.td
+  TARGET ClangBuiltinsHLSL)
+
 # ARM NEON and MVE
 clang_tablegen(arm_neon.inc -gen-arm-neon-sema
   SOURCE arm_neon.td
diff --git a/clang/include/clang/Basic/TargetBuiltins.h 
b/clang/include/clang/Basic/TargetBuiltins.h
index a4abaaef44c06c..38452553bd2df2 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -89,6 +89,16 @@ namespace clang {
   };
   }
 
+  /// HLSL builtins
+  namespace hlsl {
+  enum {
+LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsHLSL.inc"
+LastTSBuiltin
+  };
+  } // namespace hlsl
+
   /// PPC builtins
   namespace PPC {
 enum {
diff --git 

[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-10 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-09 Thread Farzon Lotfi via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],

farzonl wrote:

Thats a good question. What I was afraid of is that `LLVMMatchType<0>`  would 
do its match on the type enum like FixedVector since arg0 is 
`llvm_anyvector_ty` or if it would also consider match on vector width and 
element type so I thought to be more explicit. 

for example what I don't want is 

float2 and int2 to match.


https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-09 Thread Xiang Li via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],

python3kgae wrote:

Does LLVMMatchType<0> good enough here to replace 
LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>?

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Farzon Lotfi via cfe-commits


@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";

farzonl wrote:

Thats a place holder `clang\lib\Sema\SemaExpr.cpp` has these 
`hasCustomTypechecking` checks  that call `CheckBuiltinFunctionCall` in 
`clang\lib\Sema\SemaChecking.cpp` I want to do custom type checking but that 
piece was dragging the pr and I wanted to get some feedback. Since it isn't 
ready yet so I pulled it from the pr and disabled code gen for the bad cases as 
a stop gap

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread David Peixotto via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);

dmpots wrote:

But dxc does actually accept the double overload for the scalar case only. It 
generates a double multiply in the scalar case so there is no problem with the 
non-existent double overload of the dxil op.

In the vector case it generates a validation error because it tries to use the 
double overload of the dot dxil op.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread David Peixotto via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

dmpots wrote:

It looks like dxc accepts the 64-bit overload and generates a dxil op

https://godbolt.org/z/8Gf6xExhc

` %IMad = call i64 @dx.op.tertiary.i64(i32 48, i64 %14, i64 %9, i64 %16)`

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double2, double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double3, double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double4, double4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int, int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int2, int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int3, int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int dot(int4, int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint, uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint2, uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint3, uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint dot(uint4, uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t, int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t2, int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t3, int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int64_t dot(int64_t4, int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t, uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t2, uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t3, uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint64_t dot(uint64_t4, uint64_t4);

llvm-beanz wrote:

Same as with double, we shouldn't have 64-bit integer types here since DXIL 
doesn't support them.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);

llvm-beanz wrote:

I think we should remove the double overloads. Since the DXIL op is only half 
and float, we should only surface half and float variants. That allows us to 
correctly warn on implicit conversion rather than having the conversion happen 
magically during code generation.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];

llvm-beanz wrote:

We should add type checking for this builtin in SemaChecking.cpp so that the 
builtin can't be directly called with invalid argument types.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],
+[IntrNoMem, IntrWillReturn, Commutative] >;
+}

llvm-beanz wrote:

Be sure to set your editor to add a newline to the end of files.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -17895,6 +17898,52 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitDXILBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }
+
+  if (T0->isIntegerTy()) {
+return Builder.CreateMul(Op0, Op1, "dx.dot");
+  }
+  ErrorUnsupported(
+  E,
+  "Dot product on a scalar is only supported on integers and floats.");
+}
+
+if (T0->isVectorTy() && T1->isVectorTy()) {
+
+  if (T0->getScalarType() != T1->getScalarType()) {
+ErrorUnsupported(E,

llvm-beanz wrote:

We should also catch this in SemaChecking and not need an error here.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : 
Intrinsic<[llvm_i32_ty], [], [IntrNoMe
 
 def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
 Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-}
+
+def int_dx_dot : 
+Intrinsic<[LLVMVectorElementType<0>], 
+[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, 
LLVMVectorElementType<0>>],
+[IntrNoMem, IntrWillReturn, Commutative] >;

llvm-beanz wrote:

This intrinsic should probably only support 16 and 32-bit types because those 
are the only types we can map to DXIL.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits


@@ -17895,6 +17898,52 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitDXILBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }
+
+  if (T0->isIntegerTy()) {
+return Builder.CreateMul(Op0, Op1, "dx.dot");
+  }
+  ErrorUnsupported(

llvm-beanz wrote:

If we have checking in SemaChecking for this, this error should be unreachable 
so it could be an assert instead.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits

https://github.com/llvm-beanz edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Chris B via cfe-commits

https://github.com/llvm-beanz commented:

Super excited to see this coming along.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread David Peixotto via cfe-commits

https://github.com/dmpots edited https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Xiang Li via cfe-commits

https://github.com/python3kgae edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Xiang Li via cfe-commits

https://github.com/python3kgae edited 
https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Xiang Li via cfe-commits


@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";

python3kgae wrote:

The return type should not be void.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread David Peixotto via cfe-commits


@@ -144,6 +144,92 @@ double3 cos(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
 double4 cos(double4);
 
+//===--===//
+// dot product builtins
+//===--===//
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half, half);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half2, half2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half3, half3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+half dot(half4, half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t, int16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t2, int16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t3, int16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+int16_t dot(int16_t4, int16_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t, uint16_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t2, uint16_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t3, uint16_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+uint16_t dot(uint16_t4, uint16_t4);
+#endif
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float, float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float2, float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float3, float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+float dot(float4, float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
+double dot(double, double);

dmpots wrote:

I think the double case deserves some discussion about whether this is valid 
hlsl or not. Currently dxc will only accept the `dot(double, double)` overload 
because it happens to lower that to a scalar multiply.

The vector overloads are not supported because there is no double overload of 
the final dxil `dot` intrinsic.


https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread David Peixotto via cfe-commits


@@ -17895,6 +17898,52 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitDXILBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_dot: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+llvm::Type *T0 = Op0->getType();
+llvm::Type *T1 = Op1->getType();
+if (!T0->isVectorTy() && !T1->isVectorTy()) {
+  if (T0->isFloatingPointTy()) {
+return Builder.CreateFMul(Op0, Op1, "dx.dot");
+  }
+
+  if (T0->isIntegerTy()) {
+return Builder.CreateMul(Op0, Op1, "dx.dot");
+  }
+  ErrorUnsupported(
+  E,
+  "Dot product on a scalar is only supported on integers and floats.");
+}
+
+if (T0->isVectorTy() && T1->isVectorTy()) {
+
+  if (T0->getScalarType() != T1->getScalarType()) {
+ErrorUnsupported(E,

dmpots wrote:

I would expect to see tests for these error conditions to exercise this code.

https://github.com/llvm/llvm-project/pull/81190
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)

2024-02-08 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl created 
https://github.com/llvm/llvm-project/pull/81190

This change implements #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td This 
is used to associate all the dot product typdef defined hlsl_intrinsics.h with 
a single intrinsic check in CGBuiltin.cpp

In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals 
were in mind for this IR. First it should operate on only vectors. Second the 
return type should be the vector element type. Third the second parameter 
vector should be of the same size as the first parameter. Finally `a dot b` 
should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot product though is a target specific intrinsic and so 
needed to establish a pattern for Target builtins via EmitDXILBuiltinExpr. The 
call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> 
EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp

EmitDXILBuiltinExp dot product intrinsics makes a destinction between vectors 
and scalars. This is because HLSL supports dot product on scalars which 
simplifies down to multiply.

>From c966e50e1be171ce6a642083508faf43ae5f220a Mon Sep 17 00:00:00 2001
From: Farzon Lotfi 
Date: Thu, 8 Feb 2024 11:08:59 -0500
Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements
 #70073

HLSL has a dot intrinsic defined here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot

The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td
This is used to associate all the dot product typdef defined hlsl_intrinsics.h
with a single intrinsic check in CGBuiltin.cpp

In IntrinsicsDirectX.td we define the llvmIR for the dot product.
A few goals were in mind for this IR. First it should operate on only
vectors. Second the return type should be the vector element type. Third
the second parameter vector should be of the same size as the first
parameter. Finally `a dot b` should be the same as `b dot a`.

In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via 
EmitBuiltinExpr. Dot
product though is a target specific intrinsic and so needed to establish
a pattern for Target builtins via EmitDXILBuiltinExpr.
The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> 
EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp

EmitDXILBuiltinExp dot product intrinsics makes a destinction
between vectors and scalars. This is because HLSL supports dot product on 
scalars which simplifies down to multiply.
---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  49 
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  86 +++
 clang/test/CodeGenHLSL/builtins/dot.hlsl  | 260 ++
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   7 +-
 6 files changed, 408 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 31a2bdeb2d3e5..1d6fd969900ea 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void*(unsigned char)";
 }
 
+def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_dot"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 // Builtins for XRay.
 def XRayCustomEvent : Builtin {
   let Spellings = ["__xray_customevent"];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a7a410dab1a01..6916f40d265c7 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/IntrinsicsARM.h"
 #include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
 #include "llvm/IR/IntrinsicsHexagon.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
 #include "llvm/IR/IntrinsicsPowerPC.h"
@@ -6018,6 +6019,8 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction 
*CGF,
   case llvm::Triple::bpfeb:
   case llvm::Triple::bpfel:
 return CGF->EmitBPFBuiltinExpr(BuiltinID, E);
+  case llvm::Triple::dxil:
+return CGF->EmitDXILBuiltinExpr(BuiltinID, E);
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
 return CGF->EmitX86BuiltinExpr(BuiltinID, E);
@@ -17895,6 +17898,52 @@ llvm::Value 
*CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
   return Arg;
 }
 
+Value *CodeGenFunction::EmitDXILBuiltinExpr(unsigned BuiltinID,
+const CallExpr *E) {
+  switch (BuiltinID) {
+  case