[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-03 Thread Sarah Spall via cfe-commits


@@ -1545,6 +1605,30 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 break;
   }
   case Builtin::BI__builtin_hlsl_elementwise_saturate:

spall wrote:

No I did not; It is supposed to fall through to the next case, so I will 
reorder these.

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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-03 Thread Sarah Spall via cfe-commits


@@ -18695,6 +18695,50 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse, "hlsl.select");
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors

spall wrote:

I likely just forgot to remove them; because yes they were for my own 
bookkeeping.

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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-03 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/4] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-03 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/5] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-04 Thread Sarah Spall via cfe-commits


@@ -1544,6 +1604,30 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   return true;
 break;
   }
+  case Builtin::BI__builtin_hlsl_select: {

spall wrote:

I think it is slightly special. It is a template function, and the first 
argument must be either a bool or a vector of bools.  Both of those cases have 
slightly different checks; so I made a function for each. I don't believe any 
of the existing Check functions checked for the correct things; most of them 
require all args are the same type. 

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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-05 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/6] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-05 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK: %hlsl.select = select i1
+// CHECK: ret i32 %hlsl.select
+int test_select_bool_int(bool cond0, int tVal, int fVal) {
+  return select(cond0, tVal, fVal); }
+
+struct S { int a; };
+// CHECK: %hlsl.select = select i1
+// CHECK: store ptr %hlsl.select
+// CHECK: ret void
+struct S test_select_infer(bool cond0, struct S tVal, struct S fVal) {
+  return select(cond0, tVal, fVal); }
+
+// CHECK: %hlsl.select = select i1
+// CHECK: ret <2 x i32> %hlsl.select
+vector test_select_bool_vector(bool cond0, vector tVal,
+  vector fVal) {
+  return select >(cond0, tVal, fVal); }

spall wrote:

No, would it be better to use that form in all the tests? I can change that.

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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-05 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/7] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-05 Thread Sarah Spall via cfe-commits


@@ -1512,6 +1512,83 @@ void SetElementTypeAsReturnType(Sema *S, CallExpr 
*TheCall,
   TheCall->setType(ReturnType);
 }
 
+static bool CheckScalarOrVector(Sema *S, CallExpr *TheCall, QualType Scalar,
+   unsigned ArgIndex) {
+  assert(TheCall->getNumArgs() >= ArgIndex);
+  QualType ArgType = TheCall->getArg(ArgIndex)->getType();
+  auto *VTy = ArgType->getAs();
+  // not the scalar or vector
+  if (!(S->Context.hasSameUnqualifiedType(ArgType, Scalar) ||
+   (VTy && S->Context.hasSameUnqualifiedType(VTy->getElementType(),
+ Scalar {
+S->Diag(TheCall->getArg(0)->getBeginLoc(),
+  diag::err_typecheck_expect_scalar_or_vector)
+   << ArgType << Scalar;
+return true;
+  }
+  return false;
+}
+
+static bool CheckBoolSelect(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() == 3);
+  Expr *Arg1 = TheCall->getArg(1);
+  Expr *Arg2 = TheCall->getArg(2);
+  if(!S->Context.hasSameUnqualifiedType(Arg1->getType(),
+   Arg2->getType())) {
+S->Diag(TheCall->getBeginLoc(),
+   diag::err_typecheck_call_different_arg_types)
+  << Arg1->getType() << Arg2->getType()
+  << Arg1->getSourceRange() << Arg2->getSourceRange();
+return true;
+  }
+
+  TheCall->setType(Arg1->getType());
+  return false;
+}
+
+static bool CheckVectorSelect(Sema *S, CallExpr *TheCall) {
+  assert(TheCall->getNumArgs() == 3);
+  Expr *Arg1 = TheCall->getArg(1);
+  Expr *Arg2 = TheCall->getArg(2);
+  if (!Arg1->getType()->isVectorType()) {
+S->Diag(Arg1->getBeginLoc(),
+   diag::err_builtin_non_vector_type)
+  << "Second" << "__builtin_hlsl_select" << Arg1->getType()
+  << Arg1->getSourceRange();
+return true;
+  }
+  
+  if (!Arg2->getType()->isVectorType()) {
+S->Diag(Arg2->getBeginLoc(),
+   diag::err_builtin_non_vector_type)
+  << "Third" << "__builtin_hlsl_select" << Arg2->getType()
+  << Arg2->getSourceRange();
+return true;
+  }
+
+  if (!S->Context.hasSameUnqualifiedType(Arg1->getType(),
+Arg2->getType())) {
+S->Diag(TheCall->getBeginLoc(),
+   diag::err_typecheck_call_different_arg_types)
+  << Arg1->getType() << Arg2->getType()
+  << Arg1->getSourceRange() << Arg2->getSourceRange();
+return true;
+  }
+
+  // caller has checked that Arg0 is a vector.
+  // check all three args have the same length.
+  if (TheCall->getArg(0)->getType()->getAs()->getNumElements() !=

spall wrote:

checkVectorElementCallArgs, checks that all of the vector arguments are the 
same, as far as I can tell, for select only the last two vectors should be the 
same. I could generalize that function and use it instead.


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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-05 Thread Sarah Spall via cfe-commits


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

spall wrote:

How do I fix this?


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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-05 Thread Sarah Spall via cfe-commits

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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-06 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/8] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-06 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/9] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-10 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/108121

Implement elementwise popcount to support HLSL function 'countbits'. 
Closes #99094 

>From 365886deae6e35ee2761c2fae2a28caa0e214880 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Fri, 6 Sep 2024 21:03:05 +
Subject: [PATCH] implement elementwise popcount to implement countbits

---
 clang/docs/LanguageExtensions.rst |  1 +
 clang/include/clang/Basic/Builtins.td |  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp   |  3 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 71 +++
 clang/lib/Sema/SemaChecking.cpp   |  2 +-
 clang/lib/Sema/SemaHLSL.cpp   |  8 +++
 .../test/CodeGen/builtins-elementwise-math.c  | 37 ++
 clang/test/Sema/builtins-elementwise-math.c   | 21 ++
 .../SemaCXX/builtins-elementwise-math.cpp |  8 +++
 llvm/lib/Target/DirectX/DXIL.td   | 11 +++
 llvm/test/CodeGen/DirectX/countbits.ll| 31 
 llvm/test/CodeGen/DirectX/countbits_error.ll  | 10 +++
 .../SPIRV/hlsl-intrinsics/countbits.ll| 21 ++
 13 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/DirectX/countbits.ll
 create mode 100644 llvm/test/CodeGen/DirectX/countbits_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/countbits.ll

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c08697282cbfe8..f62f90fb9650a9 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -667,6 +667,7 @@ Unless specified otherwise operation(±0) = ±0 and 
operation(±infinity) = ±in
  T __builtin_elementwise_log(T x)return the natural logarithm of x 
   floating point types
  T __builtin_elementwise_log2(T x)   return the base 2 logarithm of x  
   floating point types
  T __builtin_elementwise_log10(T x)  return the base 10 logarithm of x 
   floating point types
+ T __builtin_elementwise_popcount(T x)   return the number of 1 bits in x  
   integer types 
  T __builtin_elementwise_pow(T x, T y)   return x raised to the power of y 
   floating point types
  T __builtin_elementwise_bitreverse(T x) return the integer represented 
after reversing the bits of x integer types
  T __builtin_elementwise_exp(T x)returns the base-e exponential, 
e^x, of the specified value  floating point types
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 92118418d9d459..6281fa144bae35 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1322,6 +1322,12 @@ def ElementwiseLog10 : Builtin {
   let Prototype = "void(...)";
 }
 
+def ElementwisePopcount : Builtin {
+  let Spellings = ["__builtin_elementwise_popcount"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 def ElementwisePow : Builtin {
   let Spellings = ["__builtin_elementwise_pow"];
   let Attributes = [NoThrow, Const, CustomTypeChecking];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index da7a1a55da5313..c5d50e57fa638c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3834,6 +3834,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_elementwise_floor:
 return RValue::get(emitBuiltinWithOneOverloadedType<1>(
 *this, E, llvm::Intrinsic::floor, "elt.floor"));
+  case Builtin::BI__builtin_elementwise_popcount:
+return RValue::get(emitBuiltinWithOneOverloadedType<1>(
+   *this, E, llvm::Intrinsic::ctpop, "elt.ctpop"));
   case Builtin::BI__builtin_elementwise_roundeven:
 return RValue::get(emitBuiltinWithOneOverloadedType<1>(
 *this, E, llvm::Intrinsic::roundeven, "elt.roundeven"));
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 5c08a45a35377d..9d667bb61b74ae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -614,6 +614,77 @@ float3 cosh(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cosh)
 float4 cosh(float4);
 
+//===--===//
+// count bits builtins
+//===--===//
+
+/// \fn T countbits(T Val)
+/// \brief Return the number of bits (per component) set in the input integer.
+/// \param Val The input value.
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
+int16_t countbits(int16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
+int16_t

[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-10 Thread Sarah Spall via cfe-commits

spall wrote:

This pull request is missing the appropriate text in 'ReleaseNotes.rst'. I am 
looking for advice on what is appropriate to put in that file, and where.

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


[clang] [HLSL] fix elementwise bitreverse test (PR #108128)

2024-09-10 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/108128

The test called 'ceil' instead of 'bitreverse', which I assume was a copy paste 
leftover.

>From 86e24b508c47ee6ad09cbaec299baeab32cf964b Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 11 Sep 2024 01:22:37 +
Subject: [PATCH] fix elementwise bitreverse test

---
 clang/test/Sema/builtins-elementwise-math.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Sema/builtins-elementwise-math.c 
b/clang/test/Sema/builtins-elementwise-math.c
index 2673f1f519af69..628274380ae5f2 100644
--- a/clang/test/Sema/builtins-elementwise-math.c
+++ b/clang/test/Sema/builtins-elementwise-math.c
@@ -275,8 +275,8 @@ void test_builtin_elementwise_min(int i, short s, double d, 
float4 v, int3 iv, u
 
 void test_builtin_elementwise_bitreverse(int i, float f, double d, float4 v, 
int3 iv, unsigned u, unsigned4 uv) {
 
-  struct Foo s = __builtin_elementwise_ceil(f);
-  // expected-error@-1 {{initializing 'struct Foo' with an expression of 
incompatible type 'float'}}
+  struct Foo s = __builtin_elementwise_bitreverse(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of 
incompatible type 'int'}}
 
   i = __builtin_elementwise_bitreverse();
   // expected-error@-1 {{too few arguments to function call, expected 1, have 
0}}

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


[clang] [HLSL] fix elementwise bitreverse test (PR #108128)

2024-09-11 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/108128

>From 8146b03b49a94532335f9bb238c6c41c9a800034 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 11 Sep 2024 01:22:37 +
Subject: [PATCH] fix elementwise bitreverse test

---
 clang/test/Sema/builtins-elementwise-math.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Sema/builtins-elementwise-math.c 
b/clang/test/Sema/builtins-elementwise-math.c
index 2673f1f519af69..628274380ae5f2 100644
--- a/clang/test/Sema/builtins-elementwise-math.c
+++ b/clang/test/Sema/builtins-elementwise-math.c
@@ -275,8 +275,8 @@ void test_builtin_elementwise_min(int i, short s, double d, 
float4 v, int3 iv, u
 
 void test_builtin_elementwise_bitreverse(int i, float f, double d, float4 v, 
int3 iv, unsigned u, unsigned4 uv) {
 
-  struct Foo s = __builtin_elementwise_ceil(f);
-  // expected-error@-1 {{initializing 'struct Foo' with an expression of 
incompatible type 'float'}}
+  struct Foo s = __builtin_elementwise_bitreverse(i);
+  // expected-error@-1 {{initializing 'struct Foo' with an expression of 
incompatible type 'int'}}
 
   i = __builtin_elementwise_bitreverse();
   // expected-error@-1 {{too few arguments to function call, expected 1, have 
0}}

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


[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-11 Thread Sarah Spall via cfe-commits

spall wrote:

> > This pull request is missing the appropriate text in 'ReleaseNotes.rst'. I 
> > am looking for advice on what is appropriate to put in that file, and where.
> 
> Here's a PR with ReleaseNotes.rst change 
> [57f879c#diff-ec770381d76c859f5f572db789175fe44410a72608f58ad5dbb14335ba56eb97](https://github.com/llvm/llvm-project/commit/57f879cdd4c63189c569bdc1ce4e87e7342eea46#diff-ec770381d76c859f5f572db789175fe44410a72608f58ad5dbb14335ba56eb97)

Yeah I saw this example but am unsure where to put my text because the contents 
of that file are not the same now.

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


[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-03 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/107129

Implement support for HLSL intrinsic select.
This would close issue #75377 

>From 226ea652f160b22922e9582c5a5c53511042d735 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/3] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index ac33672a32b336..291f417a7243d6 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 2a733e4d834cfa..ba18a2be319698 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select

[clang] [HLSL] Implement support for HLSL intrinsic - select (PR #107129)

2024-09-03 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/107129

>From 3e0cd3c450eb4aa28742c4879733987e9e2692e7 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 28 Aug 2024 01:44:35 +
Subject: [PATCH 1/3] implement select intrinsic

---
 clang/include/clang/Basic/Builtins.td|  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 41 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 24 +++
 clang/lib/Sema/SemaHLSL.cpp  | 84 
 4 files changed, 155 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 8668b25661dec8..7e89f84319877b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLSelect : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_select"];
+  let Attributes = [NoThrow, Const];
+  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 e4d169d2ad6030..7fe198c207ce22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18695,6 +18695,47 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 CGM.getHLSLRuntime().getSaturateIntrinsic(), ArrayRef{Op0},
 nullptr, "hlsl.saturate");
   }
+  case Builtin::BI__builtin_hlsl_select: {
+Value *OpCond = EmitScalarExpr(E->getArg(0));
+Value *OpTrue = EmitScalarExpr(E->getArg(1));
+Value *OpFalse = EmitScalarExpr(E->getArg(2));
+llvm::Type *TCond = OpCond->getType();
+
+// if cond is a bool emit a select instruction
+if (TCond->isIntegerTy(1))
+  return Builder.CreateSelect(OpCond, OpTrue, OpFalse);
+
+// if cond is a vector of bools lower to a shufflevector
+// todo check if that true and false are vectors
+// todo check that the size of true and false and cond are the same
+if (TCond->isVectorTy() &&
+   E->getArg(0)->getType()->getAs()->isBooleanType()) {
+  assert(OpTrue->getType()->isVectorTy() && 
OpFalse->getType()->isVectorTy() &&
+"Select's second and third operands must be vectors if first 
operand is a vector.");
+
+  auto *VecTyTrue = E->getArg(1)->getType()->getAs();
+  auto *VecTyFalse = E->getArg(2)->getType()->getAs();
+
+  assert(VecTyTrue->getElementType() == VecTyFalse->getElementType() &&
+"Select's second and third vectors need the same element types.");
+
+  const unsigned N = VecTyTrue->getNumElements();
+  assert(N == VecTyFalse->getNumElements() &&
+N == 
E->getArg(0)->getType()->getAs()->getNumElements() &&
+"Select requires vectors to be of the same size.");
+  
+  llvm::SmallVector Mask;
+  for (unsigned I = 0; I < N; I++) {
+   Value *Index = ConstantInt::get(IntTy, I);
+   Value *IndexBool = Builder.CreateExtractElement(OpCond, Index);
+   Mask.push_back(Builder.CreateSelect(IndexBool, Index, 
ConstantInt::get(IntTy, I + N)));
+  }
+  
+  return Builder.CreateShuffleVector(OpTrue, OpFalse, BuildVector(Mask));
+}
+
+llvm_unreachable("Select requires a bool or vector of bools as its first 
operand.");
+  }
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 return EmitRuntimeCall(CGM.CreateRuntimeFunction(
 llvm::FunctionType::get(IntTy, {}, false), 
"__hlsl_wave_get_lane_index",
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6d38b668fe770e..4319d9775c4bae 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1603,6 +1603,30 @@ double3 saturate(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_saturate)
 double4 saturate(double4);
 
+//===--===//
+// select builtins
+//===--===//
+
+/// \fn T select(bool Cond, T TrueVal, T FalseVal)
+/// \brief ternary operator.
+/// \param Cond The Condition input value.
+/// \param TrueVal The Value returned if Cond is true.
+/// \param FalseVal The Value returned if Cond is false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+T select(bool, T, T);
+  
+/// \fn vector select(vector Conds, vector TrueVals, 
vector, FalseVals)
+/// \brief ternary operator for vectors. All vectors must be the same size.
+/// \param Conds The Condition input values.
+/// \param TrueVals The vector values are chosen from when conditions are true.
+/// \param FalseVals The vector values are chosen from when conditions are 
false.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+template
+vector select(vector, vector, vector);
+  
 
//===

[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-12 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/108121

>From 4a892930ab4d97b5621d8066b23c48c7278d14e0 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Fri, 6 Sep 2024 21:03:05 +
Subject: [PATCH 1/2] implement elementwise popcount to implement countbits

---
 clang/docs/LanguageExtensions.rst |  1 +
 clang/include/clang/Basic/Builtins.td |  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp   |  3 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 71 +++
 clang/lib/Sema/SemaChecking.cpp   |  2 +-
 clang/lib/Sema/SemaHLSL.cpp   |  8 +++
 .../test/CodeGen/builtins-elementwise-math.c  | 37 ++
 clang/test/Sema/builtins-elementwise-math.c   | 21 ++
 .../SemaCXX/builtins-elementwise-math.cpp |  8 +++
 llvm/lib/Target/DirectX/DXIL.td   | 11 +++
 llvm/test/CodeGen/DirectX/countbits.ll| 31 
 llvm/test/CodeGen/DirectX/countbits_error.ll  | 10 +++
 .../SPIRV/hlsl-intrinsics/countbits.ll| 21 ++
 13 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/DirectX/countbits.ll
 create mode 100644 llvm/test/CodeGen/DirectX/countbits_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/countbits.ll

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c08697282cbfe8..f62f90fb9650a9 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -667,6 +667,7 @@ Unless specified otherwise operation(±0) = ±0 and 
operation(±infinity) = ±in
  T __builtin_elementwise_log(T x)return the natural logarithm of x 
   floating point types
  T __builtin_elementwise_log2(T x)   return the base 2 logarithm of x  
   floating point types
  T __builtin_elementwise_log10(T x)  return the base 10 logarithm of x 
   floating point types
+ T __builtin_elementwise_popcount(T x)   return the number of 1 bits in x  
   integer types 
  T __builtin_elementwise_pow(T x, T y)   return x raised to the power of y 
   floating point types
  T __builtin_elementwise_bitreverse(T x) return the integer represented 
after reversing the bits of x integer types
  T __builtin_elementwise_exp(T x)returns the base-e exponential, 
e^x, of the specified value  floating point types
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 3dc04f68b3172a..33aef520ad23c0 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1322,6 +1322,12 @@ def ElementwiseLog10 : Builtin {
   let Prototype = "void(...)";
 }
 
+def ElementwisePopcount : Builtin {
+  let Spellings = ["__builtin_elementwise_popcount"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 def ElementwisePow : Builtin {
   let Spellings = ["__builtin_elementwise_pow"];
   let Attributes = [NoThrow, Const, CustomTypeChecking];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9950c06a0b9a6b..91ed0806dcdbdb 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3834,6 +3834,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_elementwise_floor:
 return RValue::get(emitBuiltinWithOneOverloadedType<1>(
 *this, E, llvm::Intrinsic::floor, "elt.floor"));
+  case Builtin::BI__builtin_elementwise_popcount:
+return RValue::get(emitBuiltinWithOneOverloadedType<1>(
+   *this, E, llvm::Intrinsic::ctpop, "elt.ctpop"));
   case Builtin::BI__builtin_elementwise_roundeven:
 return RValue::get(emitBuiltinWithOneOverloadedType<1>(
 *this, E, llvm::Intrinsic::roundeven, "elt.roundeven"));
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 7a1edd93984de7..6ec5e0820026a0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -614,6 +614,77 @@ float3 cosh(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cosh)
 float4 cosh(float4);
 
+//===--===//
+// count bits builtins
+//===--===//
+
+/// \fn T countbits(T Val)
+/// \brief Return the number of bits (per component) set in the input integer.
+/// \param Val The input value.
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
+int16_t countbits(int16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
+int16_t2 countbits(int16_t2);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(

[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-12 Thread Sarah Spall via cfe-commits

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


[clang] [HLSL][Docs] Update function calls docs (PR #106860)

2024-09-16 Thread Sarah Spall via cfe-commits


@@ -248,13 +248,14 @@ which is a term made up for HLSL. A cx-value is a 
temporary value which may be
 the result of a cast, and stores its value back to an lvalue when the value
 expires.
 
-To represent this concept in Clang we introduce a new ``HLSLOutParamExpr``. An
-``HLSLOutParamExpr`` has two forms, one with a single sub-expression and one
-with two sub-expressions.
+To represent this concept in Clang we introduce a new ``HLSLOutArgExpr``. An
+``HLSLOutArgExpr`` has three sub-expressions:
 
-The single sub-expression form is used when the argument expression and the
-function parameter are the same type, so no cast is required. As in this
-example:
+* An OpaqueValueExpr of the argument lvalue expression.
+* An OpaqueValueExpr of the copy-initialized parameter temporary.

spall wrote:

This is not always copy-initialized.  It is clarified later in the docs, so 
maybe its not worth mentioning here, but thought I'd point it out.

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


[clang] [HLSL][Docs] Update function calls docs (PR #106860)

2024-09-16 Thread Sarah Spall via cfe-commits

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


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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-07 Thread Sarah Spall via cfe-commits

spall wrote:

> It is not correct to limit firstbithigh to 32 bit integers. There are a 
> couple of reasons that might make one think that it is, but we do in fact 
> want/need to support int16 and int64 here.
> 
> 1. The [HLSL 
> docs](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/firstbithigh)
>  only mention integer. Unfortunately that's true for most of these functions, 
> as many of these docs were not updated as 64 and 16 bit types gained support 
> in the language.
> 
> 2. DXC's SPIR-V implementation doesn't handle 16- and 64-bit for these 
> functions. As noted in [Incorrect SPIR-V generated when `firstbithigh` is 
> used on a `uint64_t` 
> microsoft/DirectXShaderCompiler#4702](https://github.com/microsoft/DirectXShaderCompiler/issues/4702)
>  we decided not to implement those overloads in DXC, but should reconsider 
> this for clang.
> 
> 
> Despite all of this, DXC does indeed support 16- and 64-bit overloads, as 
> seen here: https://hlsl.godbolt.org/z/qbc17xz35
> 
> Note that the return type of the operation is not overloaded - all of the 
> overloads of this function return uint.

Why is the return type not overloaded? It is overloaded for countbits which is 
a similar function.

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


[clang] [clang][HLSL] Add sign intrinsic part 4 (PR #108396)

2024-10-09 Thread Sarah Spall via cfe-commits

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


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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-04 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From e9ed9f9a0415544781f8334b305eb3916fc0862c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/4] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index a726a0ef4b4bd2..cc4630c281052d 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 43700ea9dd3cfd..6033dcffb3a6da 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18631,6 +18631,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18720,6 +18728,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 6722d2c7c50a2b..03ddef95800e1a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -88,6 +88,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index c3ecfc7c90d433..afb7bd33374111 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -928,6 +928,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===---

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-04 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,37 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val %}

spall wrote:

I removed the non-32 bit tests, except error tests, since it only supports 32 
bit integers.

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


[clang] [clang][HLSL] Add radians intrinsic (PR #110802)

2024-10-04 Thread Sarah Spall via cfe-commits

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

LGTM but I didn't look too closely at the tests.

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


[clang] [llvm] [HLSL] Implement the `degrees` intrinsic (PR #111209)

2024-10-04 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-04 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From e9ed9f9a0415544781f8334b305eb3916fc0862c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/3] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index a726a0ef4b4bd2..cc4630c281052d 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 43700ea9dd3cfd..6033dcffb3a6da 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18631,6 +18631,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18720,6 +18728,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 6722d2c7c50a2b..03ddef95800e1a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -88,6 +88,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index c3ecfc7c90d433..afb7bd33374111 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -928,6 +928,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===---

[clang] [llvm] [HLSL] Implement the `degrees` intrinsic (PR #111209)

2024-10-04 Thread Sarah Spall via cfe-commits


@@ -2625,6 +2645,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectFmix(ResVReg, ResType, I);
   case Intrinsic::spv_length:
 return selectLength(ResVReg, ResType, I);
+  case Intrinsic::spv_degrees:
+return selectDegrees(ResVReg, ResType, I);

spall wrote:

Assuming it does take 1 operand, can you use selectExtInst here instead of a 
custom function? 

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


[clang] [llvm] [HLSL] Implement the `degrees` intrinsic (PR #111209)

2024-10-04 Thread Sarah Spall via cfe-commits


@@ -1643,6 +1646,23 @@ bool SPIRVInstructionSelector::selectLength(Register 
ResVReg,
   .constrainAllUses(TII, TRI, RBI);
 }
 
+bool SPIRVInstructionSelector::selectDegrees(Register ResVReg,
+ const SPIRVType *ResType,
+ MachineInstr &I) const {
+
+  assert(I.getNumOperands() == 3);

spall wrote:

Doesn't degrees have 1 operand? 

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-16 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From 62af64102d96405d9a572a054ad4c2fa87ba8867 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/4] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 382fb6b7a3c031..5c482eba1f4f49 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4791,6 +4791,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f6d7db2c204c12..bce44257077ebd 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18639,6 +18639,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18728,6 +18736,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index f7621ee20b1243..bbe25a1b50c4e0 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -91,6 +91,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..4b3a4f50ceb981 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -958,6 +958,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-16 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From 62af64102d96405d9a572a054ad4c2fa87ba8867 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/5] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 382fb6b7a3c031..5c482eba1f4f49 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4791,6 +4791,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f6d7db2c204c12..bce44257077ebd 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18639,6 +18639,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18728,6 +18736,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index f7621ee20b1243..bbe25a1b50c4e0 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -91,6 +91,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..4b3a4f50ceb981 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -958,6 +958,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===

[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-21 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/113189

Restricts hlsl countbits to always return a uint32.
Implements a lowering from llvm.ctpop which has an overloaded return type to 
dxil cbits op which always returns uint32.
Closes #112779 

>From f110f3167769d91dd87b260b30c2a61cc754b619 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 16 Oct 2024 19:00:08 +
Subject: [PATCH] implement countbits correctly

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 126 +++---
 .../test/CodeGenHLSL/builtins/countbits.hlsl  |  42 +++---
 .../SemaHLSL/BuiltIns/countbits-errors.hlsl   |  14 +-
 llvm/lib/Target/DirectX/DXIL.td   |   5 +-
 llvm/lib/Target/DirectX/DXILOpLowering.cpp|  64 +
 llvm/test/CodeGen/DirectX/countbits.ll|  39 --
 6 files changed, 202 insertions(+), 88 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..2a612c3746076c 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -705,66 +705,90 @@ float4 cosh(float4);
 
 #ifdef __HLSL_ENABLE_16_BIT
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t countbits(int16_t);
+constexpr uint countbits(int16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t2 countbits(int16_t2);
+constexpr uint2 countbits(int16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t3 countbits(int16_t3);
+constexpr uint3 countbits(int16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t4 countbits(int16_t4);
+constexpr uint4 countbits(int16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t countbits(uint16_t);
+constexpr uint countbits(uint16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t2 countbits(uint16_t2);
+constexpr uint2 countbits(uint16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t3 countbits(uint16_t3);
+constexpr uint3 countbits(uint16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t4 countbits(uint16_t4);
+constexpr uint4 countbits(uint16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 #endif
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int countbits(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int2 countbits(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int3 countbits(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int4 countbits(int4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint countbits(uint);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint2 countbits(uint2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint3 countbits(uint3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint4 countbits(uint4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t countbits(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t2 countbits(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t3 countbits(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t4 countbits(int64_t4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t countbits(uint64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t2 countbits(uint64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t3 countbits(uint64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t4 countbits(uint64_t4);
+constexpr uint countbits(int x) {
+  return __builtin_elementwise_popcount(x);
+}  
+constexpr uint2 countbits(int2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(uint x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(uint2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(uint3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(uint4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(int64_t x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(int64_t2 x) {
+ 

[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-21 Thread Sarah Spall via cfe-commits


@@ -705,66 +705,74 @@ float4 cosh(float4);
 
 #ifdef __HLSL_ENABLE_16_BIT
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t countbits(int16_t);

spall wrote:

When I asked Justin about this he pointed to this link:
https://github.com/microsoft/DirectXShaderCompiler/blob/main/utils/hct/gen_intrin_main.txt#L114
and suggested it meant both signed and unsigned were supported. 

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-21 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/113189

>From f110f3167769d91dd87b260b30c2a61cc754b619 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 16 Oct 2024 19:00:08 +
Subject: [PATCH 1/2] implement countbits correctly

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 126 +++---
 .../test/CodeGenHLSL/builtins/countbits.hlsl  |  42 +++---
 .../SemaHLSL/BuiltIns/countbits-errors.hlsl   |  14 +-
 llvm/lib/Target/DirectX/DXIL.td   |   5 +-
 llvm/lib/Target/DirectX/DXILOpLowering.cpp|  64 +
 llvm/test/CodeGen/DirectX/countbits.ll|  39 --
 6 files changed, 202 insertions(+), 88 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..2a612c3746076c 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -705,66 +705,90 @@ float4 cosh(float4);
 
 #ifdef __HLSL_ENABLE_16_BIT
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t countbits(int16_t);
+constexpr uint countbits(int16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t2 countbits(int16_t2);
+constexpr uint2 countbits(int16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t3 countbits(int16_t3);
+constexpr uint3 countbits(int16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t4 countbits(int16_t4);
+constexpr uint4 countbits(int16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t countbits(uint16_t);
+constexpr uint countbits(uint16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t2 countbits(uint16_t2);
+constexpr uint2 countbits(uint16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t3 countbits(uint16_t3);
+constexpr uint3 countbits(uint16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t4 countbits(uint16_t4);
+constexpr uint4 countbits(uint16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 #endif
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int countbits(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int2 countbits(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int3 countbits(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int4 countbits(int4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint countbits(uint);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint2 countbits(uint2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint3 countbits(uint3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint4 countbits(uint4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t countbits(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t2 countbits(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t3 countbits(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t4 countbits(int64_t4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t countbits(uint64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t2 countbits(uint64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t3 countbits(uint64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t4 countbits(uint64_t4);
+constexpr uint countbits(int x) {
+  return __builtin_elementwise_popcount(x);
+}  
+constexpr uint2 countbits(int2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(uint x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(uint2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(uint3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(uint4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(int64_t x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(int64_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int64_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int64_t4 x) {
+  return 

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-21 Thread Sarah Spall via cfe-commits

spall wrote:

> > > Despite all of this, DXC does indeed support 16- and 64-bit overloads, as 
> > > seen here: https://hlsl.godbolt.org/z/qbc17xz35
> > > Note that the return type of the operation is not overloaded - all of the 
> > > overloads of this function return uint.
> > 
> > 
> > Why is the return type not overloaded? Isn't it overloaded for countbits 
> > which is a similar function.
> 
> The return type for countbits is also not overloaded: 
> https://hlsl.godbolt.org/z/oGYhsjEGc - in fact none of the operations that 
> use the `unaryBits` operation class are overloaded on the return type.
> 
> The code we're generating with clang for countbits right now actually just 
> looks like it's wrong. It doesn't match what DXC does at all: 
> https://hlsl.godbolt.org/z/K8n3j5o3K
Addressed here:
https://github.com/llvm/llvm-project/pull/113189

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-21 Thread Sarah Spall via cfe-commits


@@ -461,6 +461,67 @@ class OpLowerer {
 });
   }
 
+  [[nodiscard]] bool lowerCtpopToCBits(Function &F) {
+IRBuilder<> &IRB = OpBuilder.getIRB();
+Type *Int32Ty = IRB.getInt32Ty();
+
+return replaceFunction(F, [&](CallInst *CI) -> Error {
+  IRB.SetInsertPoint(CI);
+  SmallVector Args;
+  Args.append(CI->arg_begin(), CI->arg_end());
+
+  Type *RetTy = Int32Ty;
+  Type *FRT = F.getReturnType();
+  if (FRT->isVectorTy()) {
+VectorType *VT = cast(FRT);
+RetTy = VectorType::get(RetTy, VT);
+  }
+
+  Expected OpCall = OpBuilder.tryCreateOp(
+  dxil::OpCode::CBits, Args, CI->getName(), RetTy);
+  if (Error E = OpCall.takeError())
+return E;
+
+  // If the result type is 32 bits we can do a direct replacement.
+  if (FRT->isIntOrIntVectorTy(32)) {
+CI->replaceAllUsesWith(*OpCall);
+CI->eraseFromParent();
+return Error::success();
+  }
+
+  unsigned CastOp;
+  if (FRT->isIntOrIntVectorTy(16))
+CastOp = Instruction::ZExt;

spall wrote:

The extension should only be on the return value which is always unsigned.  Is 
this code wrong with that in mind?

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-16 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From 62af64102d96405d9a572a054ad4c2fa87ba8867 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/6] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 382fb6b7a3c031..5c482eba1f4f49 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4791,6 +4791,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f6d7db2c204c12..bce44257077ebd 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18639,6 +18639,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18728,6 +18736,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index f7621ee20b1243..bbe25a1b50c4e0 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -91,6 +91,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..4b3a4f50ceb981 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -958,6 +958,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===

[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-10-03 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/111047

Get inout/out parameters working for HLSL Arrays.
Utilizes the fix from #109323, and corrects the assignment behavior slightly to 
allow for Non-LValues on the RHS. 
Closes #106917 

>From c73ce3707e59242b8ccbb6757a290938c2d39e5e Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Tue, 17 Sep 2024 20:25:46 +
Subject: [PATCH 1/4] theoretically fix issue

---
 clang/lib/Sema/SemaType.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index c44fc9c4194ca4..8c80ece635fbff 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5675,6 +5675,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
   assert(!T.isNull() && "T must not be null at the end of this function");
   if (!AreDeclaratorChunksValid)
 return Context.getTrivialTypeSourceInfo(T);
+
+  if (state.didParseHLSLParamMod() && !T->isConstantArrayType())
+T = S.HLSL().getInoutParameterType(T);
   return GetTypeSourceInfoForDeclarator(state, T, TInfo);
 }
 
@@ -8562,7 +8565,6 @@ static void 
HandleHLSLParamModifierAttr(TypeProcessingState &State,
 return;
   if (Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_inout ||
   Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_out) {
-CurType = S.HLSL().getInoutParameterType(CurType);
 State.setParsedHLSLParamMod(true);
   }
 }

>From 0f64ad26f2218a037694b01649a4ebd5e2bf766c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 2 Oct 2024 21:34:02 +
Subject: [PATCH 2/4] get inout working

---
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp | 10 +++
 clang/lib/CodeGen/CGCall.cpp |  3 +-
 clang/lib/CodeGen/CGExpr.cpp |  7 +++--
 clang/lib/Sema/SemaExprCXX.cpp   | 13 +++--
 clang/lib/Sema/SemaOverload.cpp  | 43 
 6 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a4d36f2eacd5d1..bdd4d86c30d389 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1471,6 +1471,10 @@ class ASTContext : public RefCountedBase {
   /// type to the decayed type.
   QualType getDecayedType(QualType Orig, QualType Decayed) const;
 
+  /// Return the uniqued reference to a constant array type from the
+  /// original array parameter type.
+  QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
+
   /// Return the uniqued reference to a specified array parameter type from the
   /// original array type.
   QualType getArrayParameterType(QualType Ty) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 735def67f7840f..b49783176f79d8 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3830,6 +3830,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
   return getDecayedType(T, Decayed);
 }
 
+QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const 
{
+  if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
+return Ty;
+  assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
+  const auto *ATy = cast(Ty);
+  return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
+ ATy->getSizeExpr(), ATy->getSizeModifier(),
+ ATy->getIndexTypeQualifiers().getAsOpaqueValue());
+}
+
 QualType ASTContext::getArrayParameterType(QualType Ty) const {
   if (Ty->isArrayParameterType())
 return Ty;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4ae981e4013e9c..fe578cacc64de1 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4690,7 +4690,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
+  assert(type->isArrayParameterType() ||
+(type->isReferenceType() == E->isGLValue()) &&
  "reference binding to unmaterialized r-value!");
 
   // Add writeback for HLSLOutParamExpr.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4c7cbf2aec..9f7ce71b30b498 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5811,9 +5811,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
 // This function implements trivial copy assignment for HLSL's
 // assignable constant arrays.
 LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
-  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  // Don't emit an LValue for the RHS because it might not be an LValue
   LValue LHS = EmitLValue(E->getLHS());
-  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS(

[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-10-03 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111047

>From c73ce3707e59242b8ccbb6757a290938c2d39e5e Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Tue, 17 Sep 2024 20:25:46 +
Subject: [PATCH 1/5] theoretically fix issue

---
 clang/lib/Sema/SemaType.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index c44fc9c4194ca4..8c80ece635fbff 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5675,6 +5675,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
   assert(!T.isNull() && "T must not be null at the end of this function");
   if (!AreDeclaratorChunksValid)
 return Context.getTrivialTypeSourceInfo(T);
+
+  if (state.didParseHLSLParamMod() && !T->isConstantArrayType())
+T = S.HLSL().getInoutParameterType(T);
   return GetTypeSourceInfoForDeclarator(state, T, TInfo);
 }
 
@@ -8562,7 +8565,6 @@ static void 
HandleHLSLParamModifierAttr(TypeProcessingState &State,
 return;
   if (Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_inout ||
   Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_out) {
-CurType = S.HLSL().getInoutParameterType(CurType);
 State.setParsedHLSLParamMod(true);
   }
 }

>From 0f64ad26f2218a037694b01649a4ebd5e2bf766c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 2 Oct 2024 21:34:02 +
Subject: [PATCH 2/5] get inout working

---
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp | 10 +++
 clang/lib/CodeGen/CGCall.cpp |  3 +-
 clang/lib/CodeGen/CGExpr.cpp |  7 +++--
 clang/lib/Sema/SemaExprCXX.cpp   | 13 +++--
 clang/lib/Sema/SemaOverload.cpp  | 43 
 6 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a4d36f2eacd5d1..bdd4d86c30d389 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1471,6 +1471,10 @@ class ASTContext : public RefCountedBase {
   /// type to the decayed type.
   QualType getDecayedType(QualType Orig, QualType Decayed) const;
 
+  /// Return the uniqued reference to a constant array type from the
+  /// original array parameter type.
+  QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
+
   /// Return the uniqued reference to a specified array parameter type from the
   /// original array type.
   QualType getArrayParameterType(QualType Ty) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 735def67f7840f..b49783176f79d8 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3830,6 +3830,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
   return getDecayedType(T, Decayed);
 }
 
+QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const 
{
+  if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
+return Ty;
+  assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
+  const auto *ATy = cast(Ty);
+  return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
+ ATy->getSizeExpr(), ATy->getSizeModifier(),
+ ATy->getIndexTypeQualifiers().getAsOpaqueValue());
+}
+
 QualType ASTContext::getArrayParameterType(QualType Ty) const {
   if (Ty->isArrayParameterType())
 return Ty;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4ae981e4013e9c..fe578cacc64de1 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4690,7 +4690,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
+  assert(type->isArrayParameterType() ||
+(type->isReferenceType() == E->isGLValue()) &&
  "reference binding to unmaterialized r-value!");
 
   // Add writeback for HLSLOutParamExpr.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4c7cbf2aec..9f7ce71b30b498 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5811,9 +5811,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
 // This function implements trivial copy assignment for HLSL's
 // assignable constant arrays.
 LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
-  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  // Don't emit an LValue for the RHS because it might not be an LValue
   LValue LHS = EmitLValue(E->getLHS());
-  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
+  // In C assignment operator RHS is often an RValue.
+  // EmitAggregateAssign expects an LValue for the RHS so call the below
+  // function instead.
+  EmitInitiali

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-03 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/111082

Implements elementwise firstbithigh hlsl builtin.
Implements firstbituhigh intrinsic for spirv and directx, which handles 
unsigned integers
Implements firstbitshigh intrinsic for spirv and directx, which handles signed 
integers.
Closes #99115 

>From e9ed9f9a0415544781f8334b305eb3916fc0862c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index a726a0ef4b4bd2..cc4630c281052d 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 43700ea9dd3cfd..6033dcffb3a6da 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18631,6 +18631,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18720,6 +18728,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 6722d2c7c50a2b..03ddef95800e1a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -88,6 +88,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index c3ecfc7c90d433..afb7bd33374111 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -928,6 +928,78 @@ float3 exp2(float3);

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-03 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From e9ed9f9a0415544781f8334b305eb3916fc0862c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/2] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index a726a0ef4b4bd2..cc4630c281052d 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4751,6 +4751,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 43700ea9dd3cfd..6033dcffb3a6da 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18631,6 +18631,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18720,6 +18728,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 6722d2c7c50a2b..03ddef95800e1a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -88,6 +88,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   
//===--===//
   // End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index c3ecfc7c90d433..afb7bd33374111 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -928,6 +928,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===---

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-04 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,37 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK: OpMemoryModel Logical GLSL450
+
+define noundef i32 @firstbituhigh_i32(i32 noundef %a) {
+entry:
+; CHECK: %[[#]] = OpExtInst %[[#]] %[[#]] FindUMsb %[[#]]
+  %elt.firstbituhigh = call i32 @llvm.spv.firstbituhigh.i32(i32 %a)
+  ret i32 %elt.firstbituhigh
+}
+
+define noundef i16 @firstbituhigh_i16(i16 noundef %a) {
+entry:
+; CHECK: %[[#]] = OpExtInst %[[#]] %[[#]] FindUMsb %[[#]]
+  %elt.firstbituhigh = call i16 @llvm.spv.firstbituhigh.i16(i16 %a)

spall wrote:

this was removed since only 32 bit is supported.

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-04 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-05 Thread Sarah Spall via cfe-commits

spall wrote:

> It is not correct to limit firstbithigh to 32 bit integers. There are a 
> couple of reasons that might make one think that it is, but we do in fact 
> want/need to support int16 and int64 here.
> 
> 1. The [HLSL 
> docs](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/firstbithigh)
>  only mention integer. Unfortunately that's true for most of these functions, 
> as many of these docs were not updated as 64 and 16 bit types gained support 
> in the language.
> 
If you click through the definition of Int it defines it to be 32 bits.
> 2. DXC's SPIR-V implementation doesn't handle 16- and 64-bit for these 
> functions. As noted in [Incorrect SPIR-V generated when `firstbithigh` is 
> used on a `uint64_t` 
> microsoft/DirectXShaderCompiler#4702](https://github.com/microsoft/DirectXShaderCompiler/issues/4702)
>  we decided not to implement those overloads in DXC, but should reconsider 
> this for clang.
> 
> 
> Despite all of this, DXC does indeed support 16- and 64-bit overloads, as 
> seen here: https://hlsl.godbolt.org/z/qbc17xz35
> 
> Note that the return type of the operation is not overloaded - all of the 
> overloads of this function return uint.

https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst#firstbithi
FirstBitHi does explicitly mention only 32 bit integers. 

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-22 Thread Sarah Spall via cfe-commits


@@ -808,6 +835,20 @@ bool SPIRVInstructionSelector::selectExtInst(Register 
ResVReg,
   return false;
 }
 
+bool SPIRVInstructionSelector::selectNAryOpWithSrcs(Register ResVReg,
+const SPIRVType *ResType,
+MachineInstr &I,
+std::vector Srcs,
+unsigned Opcode) const {
+  auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType));
+  for (Register SReg : Srcs) {
+MIB.addUse(SReg);

spall wrote:

Should I do that as part of this PR?


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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-22 Thread Sarah Spall via cfe-commits


@@ -424,7 +424,7 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
 LLT LLTy = LLT::scalar(64);
 Register SpvVecConst =
 CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
-CurMF->getRegInfo().setRegClass(SpvVecConst, &SPIRV::iIDRegClass);
+CurMF->getRegInfo().setRegClass(SpvVecConst, getRegClass(SpvType));

spall wrote:

Happy to put it in its own PR if that is what people want. I just left it here 
since it is such a small change.

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-22 Thread Sarah Spall via cfe-commits


@@ -461,6 +461,67 @@ class OpLowerer {
 });
   }
 
+  [[nodiscard]] bool lowerCtpopToCBits(Function &F) {
+IRBuilder<> &IRB = OpBuilder.getIRB();
+Type *Int32Ty = IRB.getInt32Ty();
+
+return replaceFunction(F, [&](CallInst *CI) -> Error {
+  IRB.SetInsertPoint(CI);
+  SmallVector Args;
+  Args.append(CI->arg_begin(), CI->arg_end());
+
+  Type *RetTy = Int32Ty;
+  Type *FRT = F.getReturnType();
+  if (FRT->isVectorTy()) {
+VectorType *VT = cast(FRT);
+RetTy = VectorType::get(RetTy, VT);
+  }
+
+  Expected OpCall = OpBuilder.tryCreateOp(
+  dxil::OpCode::CBits, Args, CI->getName(), RetTy);
+  if (Error E = OpCall.takeError())
+return E;
+
+  // If the result type is 32 bits we can do a direct replacement.
+  if (FRT->isIntOrIntVectorTy(32)) {
+CI->replaceAllUsesWith(*OpCall);
+CI->eraseFromParent();
+return Error::success();
+  }
+
+  unsigned CastOp;
+  if (FRT->isIntOrIntVectorTy(16))
+CastOp = Instruction::ZExt;
+  else // must be 64 bits
+CastOp = Instruction::Trunc;
+
+  // It is correct to replace the ctpop with the dxil op and
+  // remove an existing cast iff the cast is the only usage of
+  // the ctpop

spall wrote:

This is true, I'll update the language.

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


[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-10-22 Thread Sarah Spall via cfe-commits


@@ -4690,8 +4690,9 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
- "reference binding to unmaterialized r-value!");
+  assert(type->isArrayParameterType() ||
+ (type->isReferenceType() == E->isGLValue()) &&
+ "reference binding to unmaterialized r-value!");

spall wrote:

I think failing the original assert means its an r-value, so its both an array 
parameter type and an r value?

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-28 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/113189

>From 23d62026c8338e6ad92495cfcaa54ff1fa5d08f0 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 16 Oct 2024 19:00:08 +
Subject: [PATCH 1/5] implement countbits correctly

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 126 +++---
 .../test/CodeGenHLSL/builtins/countbits.hlsl  |  42 +++---
 .../SemaHLSL/BuiltIns/countbits-errors.hlsl   |  14 +-
 llvm/lib/Target/DirectX/DXIL.td   |   5 +-
 llvm/lib/Target/DirectX/DXILOpLowering.cpp|  64 +
 llvm/test/CodeGen/DirectX/countbits.ll|  39 --
 6 files changed, 202 insertions(+), 88 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 8ade4b27f360fb..7936506a0461b6 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -723,66 +723,90 @@ float4 cosh(float4);
 
 #ifdef __HLSL_ENABLE_16_BIT
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t countbits(int16_t);
+constexpr uint countbits(int16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t2 countbits(int16_t2);
+constexpr uint2 countbits(int16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t3 countbits(int16_t3);
+constexpr uint3 countbits(int16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t4 countbits(int16_t4);
+constexpr uint4 countbits(int16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t countbits(uint16_t);
+constexpr uint countbits(uint16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t2 countbits(uint16_t2);
+constexpr uint2 countbits(uint16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t3 countbits(uint16_t3);
+constexpr uint3 countbits(uint16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t4 countbits(uint16_t4);
+constexpr uint4 countbits(uint16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 #endif
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int countbits(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int2 countbits(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int3 countbits(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int4 countbits(int4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint countbits(uint);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint2 countbits(uint2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint3 countbits(uint3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint4 countbits(uint4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t countbits(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t2 countbits(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t3 countbits(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t4 countbits(int64_t4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t countbits(uint64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t2 countbits(uint64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t3 countbits(uint64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t4 countbits(uint64_t4);
+constexpr uint countbits(int x) {
+  return __builtin_elementwise_popcount(x);
+}  
+constexpr uint2 countbits(int2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(uint x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(uint2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(uint3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(uint4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(int64_t x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(int64_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int64_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int64_t4 x) {
+  return 

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-24 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,107 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | 
FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK: OpMemoryModel Logical GLSL450
+
+define noundef i32 @firstbituhigh_i32(i32 noundef %a) {

spall wrote:

Yes I saw I am working on fixing it.

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-29 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-11-04 Thread Sarah Spall via cfe-commits

spall wrote:

Waiting on #114482 

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-30 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-30 Thread Sarah Spall via cfe-commits


@@ -449,6 +449,15 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
   return Res;
 }
 
+Register SPIRVGlobalRegistry::getOrCreateConstScalarOrVector(
+uint64_t Val, MachineInstr &I, SPIRVType *SpvType,
+const SPIRVInstrInfo &TII, bool ZeroAsNull) {
+  if (SpvType->getOpcode() == SPIRV::OpTypeVector)
+return getOrCreateConstVector(Val, I, SpvType, TII, ZeroAsNull);
+  else
+return getOrCreateConstInt(Val, I, SpvType, TII, ZeroAsNull);

spall wrote:

No, because the Val is a uint64_t so its assumed to be an int. Following how 
'getOrCreateConstVectr' is written, someone would write an overload of this 
that takes a float if they wanted it for floats.

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


[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-10-30 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111047

>From 0797f19cad4ca9cf605725de1ac838cccacda1fc Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Tue, 17 Sep 2024 20:25:46 +
Subject: [PATCH 1/6] theoretically fix issue

---
 clang/lib/Sema/SemaType.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 5d043e6684573c..a7fc7b692f5db3 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5675,6 +5675,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
   assert(!T.isNull() && "T must not be null at the end of this function");
   if (!AreDeclaratorChunksValid)
 return Context.getTrivialTypeSourceInfo(T);
+
+  if (state.didParseHLSLParamMod() && !T->isConstantArrayType())
+T = S.HLSL().getInoutParameterType(T);
   return GetTypeSourceInfoForDeclarator(state, T, TInfo);
 }
 
@@ -8562,7 +8565,6 @@ static void 
HandleHLSLParamModifierAttr(TypeProcessingState &State,
 return;
   if (Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_inout ||
   Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_out) {
-CurType = S.HLSL().getInoutParameterType(CurType);
 State.setParsedHLSLParamMod(true);
   }
 }

>From 7f9c7e0c249771c4e6fc7b09e2788f1000cb31b0 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 2 Oct 2024 21:34:02 +
Subject: [PATCH 2/6] get inout working

---
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp | 10 +++
 clang/lib/CodeGen/CGCall.cpp |  3 +-
 clang/lib/CodeGen/CGExpr.cpp |  7 +++--
 clang/lib/Sema/SemaExprCXX.cpp   | 13 +++--
 clang/lib/Sema/SemaOverload.cpp  | 43 
 6 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a4d36f2eacd5d1..bdd4d86c30d389 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1471,6 +1471,10 @@ class ASTContext : public RefCountedBase {
   /// type to the decayed type.
   QualType getDecayedType(QualType Orig, QualType Decayed) const;
 
+  /// Return the uniqued reference to a constant array type from the
+  /// original array parameter type.
+  QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
+
   /// Return the uniqued reference to a specified array parameter type from the
   /// original array type.
   QualType getArrayParameterType(QualType Ty) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 69892bda42b256..8a21d8c5eec779 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3839,6 +3839,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
   return getDecayedType(T, Decayed);
 }
 
+QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const 
{
+  if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
+return Ty;
+  assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
+  const auto *ATy = cast(Ty);
+  return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
+ ATy->getSizeExpr(), ATy->getSizeModifier(),
+ ATy->getIndexTypeQualifiers().getAsOpaqueValue());
+}
+
 QualType ASTContext::getArrayParameterType(QualType Ty) const {
   if (Ty->isArrayParameterType())
 return Ty;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8f4f5d3ed81601..0206d2c1360d47 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4726,7 +4726,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
+  assert(type->isArrayParameterType() ||
+(type->isReferenceType() == E->isGLValue()) &&
  "reference binding to unmaterialized r-value!");
 
   // Add writeback for HLSLOutParamExpr.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e90e8da3e9f1ea..a2a4c8d819581e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5821,9 +5821,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
 // This function implements trivial copy assignment for HLSL's
 // assignable constant arrays.
 LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
-  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  // Don't emit an LValue for the RHS because it might not be an LValue
   LValue LHS = EmitLValue(E->getLHS());
-  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
+  // In C assignment operator RHS is often an RValue.
+  // EmitAggregateAssign expects an LValue for the RHS so call the below
+  // function instead.
+  EmitInitiali

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-30 Thread Sarah Spall via cfe-commits


@@ -37,13 +39,12 @@ define noundef i32 @firstbituhigh_i64(i64 noundef %a) {
 entry:
 ; CHECK: [[O:%.*]] = OpBitcast %[[#]] %[[#]]
 ; CHECK: [[N:%.*]] = OpExtInst %[[#]] %[[#]] FindUMsb [[O]]
-; CHECK: [[M:%.*]] = OpVectorShuffle %[[#]] [[N]] [[N]] 0
-; CHECK: [[L:%.*]] = OpVectorShuffle %[[#]] [[N]] [[N]] 1
+; CHECK: [[M:%.*]] = OpVectorExtractDynamic %[[#]] [[N]] [[Z]]
+; CHECK: [[L:%.*]] = OpVectorExtractDynamic %[[#]] [[N]] [[X]]

spall wrote:

OpVectorShuffle requires the result type to be a vector. In the case we have a 
scalar i64, that would result in a vector of length 1 which is not supported in 
SPIRV.  So, instead in the scalar case we do a OpVectorExtractDynamic. 

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-30 Thread Sarah Spall via cfe-commits


@@ -2717,82 +2717,82 @@ bool 
SPIRVInstructionSelector::selectFirstBitHigh64(Register ResVReg,
   Register FBHReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
   Result &= selectFirstBitHigh32(FBHReg, postCastT, I, bitcastReg, IsSigned);
 
-  // 3. check if result of each top 32 bits is == -1
-  // split result vector into vector of high bits and vector of low bits
-  // get high bits
-  // if ResType is a scalar we need a vector anyways because our code
-  // operates on vectors, even vectors of length one.
-  SPIRVType *VResType = ResType;
+  // 3. split result vector into high bits and low bits
+  Register HighReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+  Register LowReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+
+  bool ZeroAsNull = STI.isOpenCLEnv();
   bool isScalarRes = ResType->getOpcode() != SPIRV::OpTypeVector;
-  if (isScalarRes)
-VResType = GR.getOrCreateSPIRVVectorType(ResType, count, MIRBuilder);
-  // count should be one.
+  if (isScalarRes) {
+// if scalar do a vector extract
+Result &= selectNAryOpWithSrcs(
+HighReg, ResType, I,
+{FBHReg, GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull)},
+SPIRV::OpVectorExtractDynamic);
+Result &= selectNAryOpWithSrcs(
+LowReg, ResType, I,
+{FBHReg, GR.getOrCreateConstInt(1, I, ResType, TII, ZeroAsNull)},
+SPIRV::OpVectorExtractDynamic);
+  } else { // vector case do a shufflevector
+auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+   TII.get(SPIRV::OpVectorShuffle))
+   .addDef(HighReg)
+   .addUse(GR.getSPIRVTypeID(ResType))
+   .addUse(FBHReg)
+   .addUse(FBHReg);
+// ^^ this vector will not be selected from; could be empty
+unsigned j;
+for (j = 0; j < count * 2; j += 2) {
+  MIB.addImm(j);
+}
+Result &= MIB.constrainAllUses(TII, TRI, RBI);
+
+// get low bits
+MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+  TII.get(SPIRV::OpVectorShuffle))
+  .addDef(LowReg)
+  .addUse(GR.getSPIRVTypeID(ResType))
+  .addUse(FBHReg)
+  .addUse(FBHReg);
+// ^^ this vector will not be selected from; could be empty
+for (j = 1; j < count * 2; j += 2) {
+  MIB.addImm(j);
+}
+Result &= MIB.constrainAllUses(TII, TRI, RBI);
+  }
+
+  // 4. check if result of each top 32 bits is == -1
+  SPIRVType *BoolType = GR.getOrCreateSPIRVBoolType(I, TII);
+  if (!isScalarRes)
+BoolType = GR.getOrCreateSPIRVVectorType(BoolType, count, MIRBuilder);
 
-  Register HighReg = MRI->createVirtualRegister(GR.getRegClass(VResType));
-  auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpVectorShuffle))
- .addDef(HighReg)
- .addUse(GR.getSPIRVTypeID(VResType))
- .addUse(FBHReg)
- .addUse(FBHReg);
-  // ^^ this vector will not be selected from; could be empty
-  unsigned j;
-  for (j = 0; j < count * 2; j += 2) {
-MIB.addImm(j);
-  }
-  Result &= MIB.constrainAllUses(TII, TRI, RBI);
-
-  // get low bits
-  Register LowReg = MRI->createVirtualRegister(GR.getRegClass(VResType));
-  MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
-TII.get(SPIRV::OpVectorShuffle))
-.addDef(LowReg)
-.addUse(GR.getSPIRVTypeID(VResType))
-.addUse(FBHReg)
-.addUse(FBHReg);
-  // ^^ this vector will not be selected from; could be empty
-  for (j = 1; j < count * 2; j += 2) {
-MIB.addImm(j);
-  }
-  Result &= MIB.constrainAllUses(TII, TRI, RBI);
-
-  SPIRVType *BoolType = GR.getOrCreateSPIRVVectorType(
-  GR.getOrCreateSPIRVBoolType(I, TII), count, MIRBuilder);
   // check if the high bits are == -1;
-  Register NegOneReg = GR.getOrCreateConstVector(-1, I, VResType, TII);
+  Register NegOneReg =
+  GR.getOrCreateConstScalarOrVector(-1, I, ResType, TII, ZeroAsNull);

spall wrote:

Sure If I do that I can probably delete the helper function I added in 
SPIRVGlobalRegistry. I thought this style would be less ugly than a big block.

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


[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-10-30 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111047

>From 0797f19cad4ca9cf605725de1ac838cccacda1fc Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Tue, 17 Sep 2024 20:25:46 +
Subject: [PATCH 1/6] theoretically fix issue

---
 clang/lib/Sema/SemaType.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 5d043e6684573c..a7fc7b692f5db3 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5675,6 +5675,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
   assert(!T.isNull() && "T must not be null at the end of this function");
   if (!AreDeclaratorChunksValid)
 return Context.getTrivialTypeSourceInfo(T);
+
+  if (state.didParseHLSLParamMod() && !T->isConstantArrayType())
+T = S.HLSL().getInoutParameterType(T);
   return GetTypeSourceInfoForDeclarator(state, T, TInfo);
 }
 
@@ -8562,7 +8565,6 @@ static void 
HandleHLSLParamModifierAttr(TypeProcessingState &State,
 return;
   if (Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_inout ||
   Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_out) {
-CurType = S.HLSL().getInoutParameterType(CurType);
 State.setParsedHLSLParamMod(true);
   }
 }

>From 7f9c7e0c249771c4e6fc7b09e2788f1000cb31b0 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 2 Oct 2024 21:34:02 +
Subject: [PATCH 2/6] get inout working

---
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp | 10 +++
 clang/lib/CodeGen/CGCall.cpp |  3 +-
 clang/lib/CodeGen/CGExpr.cpp |  7 +++--
 clang/lib/Sema/SemaExprCXX.cpp   | 13 +++--
 clang/lib/Sema/SemaOverload.cpp  | 43 
 6 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a4d36f2eacd5d1..bdd4d86c30d389 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1471,6 +1471,10 @@ class ASTContext : public RefCountedBase {
   /// type to the decayed type.
   QualType getDecayedType(QualType Orig, QualType Decayed) const;
 
+  /// Return the uniqued reference to a constant array type from the
+  /// original array parameter type.
+  QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
+
   /// Return the uniqued reference to a specified array parameter type from the
   /// original array type.
   QualType getArrayParameterType(QualType Ty) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 69892bda42b256..8a21d8c5eec779 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3839,6 +3839,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
   return getDecayedType(T, Decayed);
 }
 
+QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const 
{
+  if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
+return Ty;
+  assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
+  const auto *ATy = cast(Ty);
+  return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
+ ATy->getSizeExpr(), ATy->getSizeModifier(),
+ ATy->getIndexTypeQualifiers().getAsOpaqueValue());
+}
+
 QualType ASTContext::getArrayParameterType(QualType Ty) const {
   if (Ty->isArrayParameterType())
 return Ty;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8f4f5d3ed81601..0206d2c1360d47 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4726,7 +4726,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
+  assert(type->isArrayParameterType() ||
+(type->isReferenceType() == E->isGLValue()) &&
  "reference binding to unmaterialized r-value!");
 
   // Add writeback for HLSLOutParamExpr.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e90e8da3e9f1ea..a2a4c8d819581e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5821,9 +5821,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
 // This function implements trivial copy assignment for HLSL's
 // assignable constant arrays.
 LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
-  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  // Don't emit an LValue for the RHS because it might not be an LValue
   LValue LHS = EmitLValue(E->getLHS());
-  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
+  // In C assignment operator RHS is often an RValue.
+  // EmitAggregateAssign expects an LValue for the RHS so call the below
+  // function instead.
+  EmitInitiali

[clang] [llvm] [HLSL][SPIRV][DXIL] Implement `WaveActiveSum` intrinsic (PR #112400)

2024-11-01 Thread Sarah Spall via cfe-commits


@@ -85,6 +85,8 @@ def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], 
[LLVMMatchType<0>, LLV
 def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
 def int_dx_rsqrt  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], 
[IntrConvergent, IntrNoMem]>;
+def int_dx_wave_active_sum : DefaultAttrsIntrinsic<[llvm_any_ty], 
[LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;

spall wrote:

I think it would be good for consistency reasons to rename this to 
int_dx_wave_active_ssum

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


[clang] [llvm] [HLSL][SPIRV][DXIL] Implement `WaveActiveSum` intrinsic (PR #112400)

2024-11-01 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL][SPIRV][DXIL] Implement `WaveActiveSum` intrinsic (PR #112400)

2024-11-01 Thread Sarah Spall via cfe-commits


@@ -85,6 +85,8 @@ def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], 
[LLVMMatchType<0>, LLV
 def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], 
[llvm_anyfloat_ty], [IntrNoMem]>;
 def int_dx_rsqrt  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], 
[LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], 
[IntrConvergent, IntrNoMem]>;
+def int_dx_wave_active_sum : DefaultAttrsIntrinsic<[llvm_any_ty], 
[LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;

spall wrote:

Is there a difference between float and signed?

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-23 Thread Sarah Spall via cfe-commits


@@ -461,6 +461,67 @@ class OpLowerer {
 });
   }
 
+  [[nodiscard]] bool lowerCtpopToCBits(Function &F) {
+IRBuilder<> &IRB = OpBuilder.getIRB();
+Type *Int32Ty = IRB.getInt32Ty();
+
+return replaceFunction(F, [&](CallInst *CI) -> Error {
+  IRB.SetInsertPoint(CI);
+  SmallVector Args;
+  Args.append(CI->arg_begin(), CI->arg_end());
+
+  Type *RetTy = Int32Ty;
+  Type *FRT = F.getReturnType();
+  if (FRT->isVectorTy()) {
+VectorType *VT = cast(FRT);
+RetTy = VectorType::get(RetTy, VT);
+  }
+
+  Expected OpCall = OpBuilder.tryCreateOp(
+  dxil::OpCode::CBits, Args, CI->getName(), RetTy);
+  if (Error E = OpCall.takeError())
+return E;
+
+  // If the result type is 32 bits we can do a direct replacement.
+  if (FRT->isIntOrIntVectorTy(32)) {
+CI->replaceAllUsesWith(*OpCall);
+CI->eraseFromParent();
+return Error::success();
+  }
+
+  unsigned CastOp;
+  if (FRT->isIntOrIntVectorTy(16))
+CastOp = Instruction::ZExt;
+  else // must be 64 bits
+CastOp = Instruction::Trunc;
+
+  // It is correct to replace the ctpop with the dxil op and
+  // remove an existing cast iff the cast is the only usage of
+  // the ctpop

spall wrote:

I actually re-wrote this to be much less conservative.

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


[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-11-08 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111047

>From 119def060924f13bd1fe07f6d73ce27a1b52ea12 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Tue, 17 Sep 2024 20:25:46 +
Subject: [PATCH 1/7] theoretically fix issue

---
 clang/lib/Sema/SemaType.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index e526a11973975d..4874a4902a5cc6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5675,6 +5675,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
   assert(!T.isNull() && "T must not be null at the end of this function");
   if (!AreDeclaratorChunksValid)
 return Context.getTrivialTypeSourceInfo(T);
+
+  if (state.didParseHLSLParamMod() && !T->isConstantArrayType())
+T = S.HLSL().getInoutParameterType(T);
   return GetTypeSourceInfoForDeclarator(state, T, TInfo);
 }
 
@@ -8616,7 +8619,6 @@ static void 
HandleHLSLParamModifierAttr(TypeProcessingState &State,
 return;
   if (Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_inout ||
   Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_out) {
-CurType = S.HLSL().getInoutParameterType(CurType);
 State.setParsedHLSLParamMod(true);
   }
 }

>From 3231a7b7327b6550291dfbeeec5a1907a7473e7f Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 2 Oct 2024 21:34:02 +
Subject: [PATCH 2/7] get inout working

---
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp | 10 +++
 clang/lib/CodeGen/CGCall.cpp |  3 +-
 clang/lib/CodeGen/CGExpr.cpp |  7 +++--
 clang/lib/Sema/SemaExprCXX.cpp   | 13 +++--
 clang/lib/Sema/SemaOverload.cpp  | 43 
 6 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 89fcb6789d880a..e9bacf8d7391c4 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1480,6 +1480,10 @@ class ASTContext : public RefCountedBase {
   /// type to the decayed type.
   QualType getDecayedType(QualType Orig, QualType Decayed) const;
 
+  /// Return the uniqued reference to a constant array type from the
+  /// original array parameter type.
+  QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
+
   /// Return the uniqued reference to a specified array parameter type from the
   /// original array type.
   QualType getArrayParameterType(QualType Ty) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 09d159e5c3efd6..202d17d3999658 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3852,6 +3852,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
   return getDecayedType(T, Decayed);
 }
 
+QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const 
{
+  if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
+return Ty;
+  assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
+  const auto *ATy = cast(Ty);
+  return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
+ ATy->getSizeExpr(), ATy->getSizeModifier(),
+ ATy->getIndexTypeQualifiers().getAsOpaqueValue());
+}
+
 QualType ASTContext::getArrayParameterType(QualType Ty) const {
   if (Ty->isArrayParameterType())
 return Ty;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8f4f5d3ed81601..0206d2c1360d47 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4726,7 +4726,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
+  assert(type->isArrayParameterType() ||
+(type->isReferenceType() == E->isGLValue()) &&
  "reference binding to unmaterialized r-value!");
 
   // Add writeback for HLSLOutParamExpr.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 096f4c4f550435..fcab838be40f2b 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5830,9 +5830,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
 // This function implements trivial copy assignment for HLSL's
 // assignable constant arrays.
 LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
-  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  // Don't emit an LValue for the RHS because it might not be an LValue
   LValue LHS = EmitLValue(E->getLHS());
-  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
+  // In C assignment operator RHS is often an RValue.
+  // EmitAggregateAssign expects an LValue for the RHS so call the below
+  // function instead.
+  EmitInitiali

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-23 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From 6239941c302f616f87ed652151e828a8eae1054c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/7] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 90475a361bb8f8..d294f680bb244d 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4792,6 +4792,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 3f28b7f26c36fe..51fc0245fd5517 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18641,6 +18641,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18730,6 +18738,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index ff7df41b5c62e7..4e37123e3f110a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -91,6 +91,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, handle_fromBinding)
 
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..4b3a4f50ceb981 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -958,6 +958,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===--===//
+
+/// \fn T firs

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-24 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111082

>From 6239941c302f616f87ed652151e828a8eae1054c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Mon, 23 Sep 2024 22:10:59 +
Subject: [PATCH 1/8] implement firstbithigh hlsl builtin

---
 clang/include/clang/Basic/Builtins.td |   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 ++
 clang/lib/CodeGen/CGHLSLRuntime.h |   2 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  72 +
 clang/lib/Sema/SemaHLSL.cpp   |  18 +++
 .../CodeGenHLSL/builtins/firstbithigh.hlsl| 153 ++
 .../BuiltIns/firstbithigh-errors.hlsl |  28 
 llvm/include/llvm/IR/IntrinsicsDirectX.td |   2 +
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   2 +
 llvm/lib/Target/DirectX/DXIL.td   |  24 +++
 .../DirectX/DirectXTargetTransformInfo.cpp|   2 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  14 ++
 llvm/test/CodeGen/DirectX/firstbithigh.ll |  91 +++
 .../CodeGen/DirectX/firstbitshigh_error.ll|  10 ++
 .../CodeGen/DirectX/firstbituhigh_error.ll|  10 ++
 .../SPIRV/hlsl-intrinsics/firstbithigh.ll |  37 +
 16 files changed, 488 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/firstbithigh.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbitshigh_error.ll
 create mode 100644 llvm/test/CodeGen/DirectX/firstbituhigh_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbithigh.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 90475a361bb8f8..d294f680bb244d 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4792,6 +4792,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "void(...)";
 }
 
+def HLSLFirstBitHigh : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_elementwise_firstbithigh"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_frac"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 3f28b7f26c36fe..51fc0245fd5517 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18641,6 +18641,14 @@ static Intrinsic::ID 
getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
   return RT.getUDotIntrinsic();
 }
 
+Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT) {
+  if (QT->hasSignedIntegerRepresentation()) {
+return RT.getFirstBitSHighIntrinsic();
+  }
+
+  return RT.getFirstBitUHighIntrinsic();
+}
+
 Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -18730,6 +18738,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
 ArrayRef{Op0, Op1}, nullptr, "hlsl.dot");
   } break;
+  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
+
+Value *X = EmitScalarExpr(E->getArg(0));
+
+return Builder.CreateIntrinsic(
+   /*ReturnType=*/X->getType(),
+   getFirstBitHighIntrinsic(CGM.getHLSLRuntime(), E->getArg(0)->getType()),
+   ArrayRef{X}, nullptr, "hlsl.firstbithigh");
+  }
   case Builtin::BI__builtin_hlsl_lerp: {
 Value *X = EmitScalarExpr(E->getArg(0));
 Value *Y = EmitScalarExpr(E->getArg(1));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index ff7df41b5c62e7..4e37123e3f110a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -91,6 +91,8 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
 
   GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, handle_fromBinding)
 
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..4b3a4f50ceb981 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -958,6 +958,78 @@ float3 exp2(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
 float4 exp2(float4);
 
+//===--===//
+// firstbithigh builtins
+//===--===//
+
+/// \fn T firs

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-23 Thread Sarah Spall via cfe-commits


@@ -424,7 +424,7 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
 LLT LLTy = LLT::scalar(64);
 Register SpvVecConst =
 CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
-CurMF->getRegInfo().setRegClass(SpvVecConst, &SPIRV::iIDRegClass);
+CurMF->getRegInfo().setRegClass(SpvVecConst, getRegClass(SpvType));

spall wrote:

I created issue #113486 and mentioned it in this PR.

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-23 Thread Sarah Spall via cfe-commits


@@ -2626,6 +2671,148 @@ Register 
SPIRVInstructionSelector::buildPointerToResource(
  MIRBuilder);
 }
 
+bool SPIRVInstructionSelector::selectFirstBitHigh16(Register ResVReg,
+const SPIRVType *ResType,
+MachineInstr &I,
+bool IsSigned) const {
+  unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
+  // zero or sign extend
+  Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+  bool Result =
+  selectUnOpWithSrc(ExtReg, ResType, I, I.getOperand(2).getReg(), Opcode);
+  return Result & selectFirstBitHigh32(ResVReg, ResType, I, ExtReg, IsSigned);
+}
+
+bool SPIRVInstructionSelector::selectFirstBitHigh32(Register ResVReg,
+const SPIRVType *ResType,
+MachineInstr &I,
+Register SrcReg,
+bool IsSigned) const {
+  unsigned Opcode = IsSigned ? GL::FindSMsb : GL::FindUMsb;
+  return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
+  .addDef(ResVReg)
+  .addUse(GR.getSPIRVTypeID(ResType))
+  .addImm(static_cast(SPIRV::InstructionSet::GLSL_std_450))
+  .addImm(Opcode)
+  .addUse(SrcReg)
+  .constrainAllUses(TII, TRI, RBI);
+}
+
+bool SPIRVInstructionSelector::selectFirstBitHigh64(Register ResVReg,
+const SPIRVType *ResType,
+MachineInstr &I,
+bool IsSigned) const {
+  Register OpReg = I.getOperand(2).getReg();
+  // 1. split our int64 into 2 pieces using a bitcast
+  unsigned count = GR.getScalarOrVectorComponentCount(ResType);
+  SPIRVType *baseType = GR.retrieveScalarOrVectorIntType(ResType);
+  MachineIRBuilder MIRBuilder(I);
+  SPIRVType *postCastT =
+  GR.getOrCreateSPIRVVectorType(baseType, 2 * count, MIRBuilder);
+  Register bitcastReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
+  bool Result =
+  selectUnOpWithSrc(bitcastReg, postCastT, I, OpReg, SPIRV::OpBitcast);
+
+  // 2. call firstbithigh
+  Register FBHReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
+  Result &= selectFirstBitHigh32(FBHReg, postCastT, I, bitcastReg, IsSigned);
+
+  // 3. check if result of each top 32 bits is == -1
+  // split result vector into vector of high bits and vector of low bits
+  // get high bits
+  // if ResType is a scalar we need a vector anyways because our code
+  // operates on vectors, even vectors of length one.
+  SPIRVType *VResType = ResType;
+  bool isScalarRes = ResType->getOpcode() != SPIRV::OpTypeVector;
+  if (isScalarRes)
+VResType = GR.getOrCreateSPIRVVectorType(ResType, count, MIRBuilder);
+  // count should be one.
+
+  Register HighReg = MRI->createVirtualRegister(GR.getRegClass(VResType));
+  auto MIB =
+  BuildMI(*I.getParent(), I, I.getDebugLoc(),
+  TII.get(SPIRV::OpVectorShuffle))
+  .addDef(HighReg)
+  .addUse(GR.getSPIRVTypeID(VResType))
+  .addUse(FBHReg)
+  .addUse(
+  FBHReg); // this vector will not be selected from; could be empty
+  unsigned i;
+  for (i = 0; i < count * 2; i += 2) {
+MIB.addImm(i);
+  }

spall wrote:

It is actually re-used in the for-loop below this one. I will rename one of 
them.

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-23 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-23 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/113189

>From 12cac48dcc10ef9c5fccba2c22911f420298b98b Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 16 Oct 2024 19:00:08 +
Subject: [PATCH 1/3] implement countbits correctly

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 126 +++---
 .../test/CodeGenHLSL/builtins/countbits.hlsl  |  42 +++---
 .../SemaHLSL/BuiltIns/countbits-errors.hlsl   |  14 +-
 llvm/lib/Target/DirectX/DXIL.td   |   5 +-
 llvm/lib/Target/DirectX/DXILOpLowering.cpp|  64 +
 llvm/test/CodeGen/DirectX/countbits.ll|  39 --
 6 files changed, 202 insertions(+), 88 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..2a612c3746076c 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -705,66 +705,90 @@ float4 cosh(float4);
 
 #ifdef __HLSL_ENABLE_16_BIT
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t countbits(int16_t);
+constexpr uint countbits(int16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t2 countbits(int16_t2);
+constexpr uint2 countbits(int16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t3 countbits(int16_t3);
+constexpr uint3 countbits(int16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t4 countbits(int16_t4);
+constexpr uint4 countbits(int16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t countbits(uint16_t);
+constexpr uint countbits(uint16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t2 countbits(uint16_t2);
+constexpr uint2 countbits(uint16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t3 countbits(uint16_t3);
+constexpr uint3 countbits(uint16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t4 countbits(uint16_t4);
+constexpr uint4 countbits(uint16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 #endif
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int countbits(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int2 countbits(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int3 countbits(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int4 countbits(int4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint countbits(uint);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint2 countbits(uint2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint3 countbits(uint3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint4 countbits(uint4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t countbits(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t2 countbits(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t3 countbits(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t4 countbits(int64_t4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t countbits(uint64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t2 countbits(uint64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t3 countbits(uint64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t4 countbits(uint64_t4);
+constexpr uint countbits(int x) {
+  return __builtin_elementwise_popcount(x);
+}  
+constexpr uint2 countbits(int2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(uint x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(uint2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(uint3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(uint4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(int64_t x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(int64_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int64_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int64_t4 x) {
+  return 

[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-10-31 Thread Sarah Spall via cfe-commits


@@ -4690,8 +4690,9 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
- "reference binding to unmaterialized r-value!");
+  assert(type->isArrayParameterType() ||
+ (type->isReferenceType() == E->isGLValue()) &&
+ "reference binding to unmaterialized r-value!");

spall wrote:

I think that its an LValue if its an HLSLArgOutExpr, so I did move the assert 
below.

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


[clang] [HLSL] Array by-value assignment (PR #109323)

2024-09-23 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --enable-var-scope
+
+// CHECK-LABEL: define void {{.*}}arr_assign1
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)

spall wrote:

Yes, and that would enable Arr = Arr2 = Arr3 = Arr4 and so on.   Is it not an 
rvalue? 

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


[clang] [HLSL] Array by-value assignment (PR #109323)

2024-09-23 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --enable-var-scope
+
+// CHECK-LABEL: define void {{.*}}arr_assign1
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)

spall wrote:

I believe the Tmp exists so 'A = B =C' is possible. 

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


[clang] [HLSL] Array by-value assignment (PR #109323)

2024-09-23 Thread Sarah Spall via cfe-commits


@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --enable-var-scope
+
+// CHECK-LABEL: define void {{.*}}arr_assign1
+// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Arr2:%.*]] = alloca [2 x i32], align 4
+// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
{{@.*}}, i32 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr2]], i8 0, i32 8, i1 
false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 
[[Arr2]], i32 8, i1 false)
+// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 
[[Arr]], i32 8, i1 false)

spall wrote:

Is this a bug? I thought that was the correct behavior.

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


[clang] [HLSL] Implementation of the elementwise fmod builtin (PR #108849)

2024-09-26 Thread Sarah Spall via cfe-commits

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


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


[clang] [HLSL][clang] Add elementwise builtin for atan2 (p3) (PR #110187)

2024-09-27 Thread Sarah Spall via cfe-commits

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

Code LGTM; didn't look at the tests too closely.

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


[clang] [HLSL] Array by-value assignment (PR #109323)

2024-09-27 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/109323

>From f4d72ce6faca5498f184069b7c5d22841a449e74 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 18 Sep 2024 22:19:07 +
Subject: [PATCH 1/3] enable array by value assignment

---
 clang/include/clang/AST/CanonicalType.h |  1 +
 clang/lib/AST/ExprClassification.cpp|  3 ++-
 clang/lib/Sema/SemaOverload.cpp | 11 ---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/CanonicalType.h 
b/clang/include/clang/AST/CanonicalType.h
index dde08f0394c98d..6102eb01793530 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -299,6 +299,7 @@ class CanProxyBase {
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantArrayType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index 5dde923312698f..9d97633309ada2 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -704,7 +704,8 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, 
const Expr *E,
 return Cl::CM_ConstAddrSpace;
 
   // Arrays are not modifiable, only their elements are.
-  if (CT->isArrayType())
+  if (CT->isArrayType() &&
+  !(Ctx.getLangOpts().HLSL && CT->isConstantArrayType()))
 return Cl::CM_ArrayType;
   // Incomplete types are not modifiable.
   if (CT->isIncompleteType())
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0c1e054f7c30a4..2cde8131108fbe 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2232,16 +2232,21 @@ static bool IsStandardConversion(Sema &S, Expr* From, 
QualType ToType,
 // just strip the qualifiers because they don't matter.
 FromType = FromType.getUnqualifiedType();
   } else if (S.getLangOpts().HLSL && FromType->isConstantArrayType() &&
- ToType->isArrayParameterType()) {
+ ToType->isConstantArrayType()) {
 // HLSL constant array parameters do not decay, so if the argument is a
 // constant array and the parameter is an ArrayParameterType we have 
special
 // handling here.
-FromType = S.Context.getArrayParameterType(FromType);
+if (ToType->isArrayParameterType()) {
+  FromType = S.Context.getArrayParameterType(FromType);
+  SCS.First = ICK_HLSL_Array_RValue;
+} else {
+  SCS.First = ICK_Identity;
+}
+
 if (S.Context.getCanonicalType(FromType) !=
 S.Context.getCanonicalType(ToType))
   return false;
 
-SCS.First = ICK_HLSL_Array_RValue;
 SCS.setAllToTypes(ToType);
 return true;
   } else if (FromType->isArrayType()) {

>From 76c7a7d2be4427b7660773566f203ba56ec573b2 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Thu, 19 Sep 2024 19:33:39 +
Subject: [PATCH 2/3] test assignable arrays

---
 clang/test/AST/HLSL/ArrayAssignable.hlsl  | 80 +++
 clang/test/CodeGenHLSL/ArrayAssignable.hlsl   | 50 
 .../test/SemaHLSL/ArrayAssignable_errors.hlsl | 29 +++
 3 files changed, 159 insertions(+)
 create mode 100644 clang/test/AST/HLSL/ArrayAssignable.hlsl
 create mode 100644 clang/test/CodeGenHLSL/ArrayAssignable.hlsl
 create mode 100644 clang/test/SemaHLSL/ArrayAssignable_errors.hlsl

diff --git a/clang/test/AST/HLSL/ArrayAssignable.hlsl 
b/clang/test/AST/HLSL/ArrayAssignable.hlsl
new file mode 100644
index 00..52c9918aa85334
--- /dev/null
+++ b/clang/test/AST/HLSL/ArrayAssignable.hlsl
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump %s 
| FileCheck %s
+
+// CHECK-LABEL: arr_assign1
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[A]] 'Arr' 
'int[2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[B]] 'Arr2' 
'int[2]'
+void arr_assign1() {
+  int Arr[2] = {0, 1};
+  in

[clang] [HLSL] Array by-value assignment (PR #109323)

2024-09-19 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/109323

Make Constant Arrays in HLSL assignable. 
Closes #109043 

>From b24aed9771a415a4dc896c48cfc0481574a0773c Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 18 Sep 2024 22:19:07 +
Subject: [PATCH 1/2] enable array by value assignment

---
 clang/include/clang/AST/CanonicalType.h |  1 +
 clang/lib/AST/ExprClassification.cpp|  3 ++-
 clang/lib/Sema/SemaOverload.cpp | 11 ---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/CanonicalType.h 
b/clang/include/clang/AST/CanonicalType.h
index dde08f0394c98d..6102eb01793530 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -299,6 +299,7 @@ class CanProxyBase {
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantArrayType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index 5dde923312698f..9d97633309ada2 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -704,7 +704,8 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, 
const Expr *E,
 return Cl::CM_ConstAddrSpace;
 
   // Arrays are not modifiable, only their elements are.
-  if (CT->isArrayType())
+  if (CT->isArrayType() &&
+  !(Ctx.getLangOpts().HLSL && CT->isConstantArrayType()))
 return Cl::CM_ArrayType;
   // Incomplete types are not modifiable.
   if (CT->isIncompleteType())
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d304f322aced64..ce503f9c69b411 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2232,16 +2232,21 @@ static bool IsStandardConversion(Sema &S, Expr* From, 
QualType ToType,
 // just strip the qualifiers because they don't matter.
 FromType = FromType.getUnqualifiedType();
   } else if (S.getLangOpts().HLSL && FromType->isConstantArrayType() &&
- ToType->isArrayParameterType()) {
+ ToType->isConstantArrayType()) {
 // HLSL constant array parameters do not decay, so if the argument is a
 // constant array and the parameter is an ArrayParameterType we have 
special
 // handling here.
-FromType = S.Context.getArrayParameterType(FromType);
+if (ToType->isArrayParameterType()) {
+  FromType = S.Context.getArrayParameterType(FromType);
+  SCS.First = ICK_HLSL_Array_RValue;
+} else {
+  SCS.First = ICK_Identity;
+}
+
 if (S.Context.getCanonicalType(FromType) !=
 S.Context.getCanonicalType(ToType))
   return false;
 
-SCS.First = ICK_HLSL_Array_RValue;
 SCS.setAllToTypes(ToType);
 return true;
   } else if (FromType->isArrayType()) {

>From a81247d0992a3fb2376a9b3dc60e5fbfd782ffbf Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Thu, 19 Sep 2024 19:33:39 +
Subject: [PATCH 2/2] test assignable arrays

---
 clang/test/AST/HLSL/ArrayAssignable.hlsl  | 80 +++
 clang/test/CodeGenHLSL/ArrayAssignable.hlsl   | 50 
 .../test/SemaHLSL/ArrayAssignable_errors.hlsl | 29 +++
 3 files changed, 159 insertions(+)
 create mode 100644 clang/test/AST/HLSL/ArrayAssignable.hlsl
 create mode 100644 clang/test/CodeGenHLSL/ArrayAssignable.hlsl
 create mode 100644 clang/test/SemaHLSL/ArrayAssignable_errors.hlsl

diff --git a/clang/test/AST/HLSL/ArrayAssignable.hlsl 
b/clang/test/AST/HLSL/ArrayAssignable.hlsl
new file mode 100644
index 00..52c9918aa85334
--- /dev/null
+++ b/clang/test/AST/HLSL/ArrayAssignable.hlsl
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump %s 
| FileCheck %s
+
+// CHECK-LABEL: arr_assign1
+// CHECK: CompoundStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[A:0x[0-9a-f]+]] {{.*}} col:7 used Arr 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 1
+// CHECK: DeclStmt 0x{{[0-9a-f]+}} {{.*}}
+// CHECK: VarDecl [[B:0x[0-9a-f]+]] {{.*}} col:7 used Arr2 'int[2]' cinit
+// CHECK: InitListExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]'
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: IntegerLiteral 0x{{[0-9a-f]+}} {{.*}} 'int' 0
+// CHECK: BinaryOperator 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue '='
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[A]] 'Arr' 
'int[2]'
+// CHECK: DeclRefExpr 0x{{[0-9a-f]+}} {{.*}} 'int[2]' lvalue Var [[B]] 'Arr2' 
'

[clang] [llvm] adding clang codegen (PR #109331)

2024-09-19 Thread Sarah Spall via cfe-commits


@@ -18824,6 +18824,40 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 retType, CGM.getHLSLRuntime().getSignIntrinsic(),
 ArrayRef{Op0}, nullptr, "hlsl.sign");
   }
+  // This should only be called when targeting DXIL
+  case Builtin::BI__builtin_hlsl_asuint_splitdouble: {
+
+assert((E->getArg(0)->getType()->isDoubleType() ||

spall wrote:

Shouldn't this assert use && here instead of || because all of those need to be 
true? As it is now if any of them are true the assert won't be triggered, and 
the code should assert if any one of them are false. 

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


[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-18 Thread Sarah Spall via cfe-commits

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


[clang] [HLSL] Array by-value assignment (PR #109323)

2024-10-01 Thread Sarah Spall via cfe-commits

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


[clang] [HLSL] Implementation of the fmod intrinsic (PR #108849)

2024-09-25 Thread Sarah Spall via cfe-commits




spall wrote:

This code only runs if the language option is HLSL right?

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


[clang] [HLSL] Implementation of the fmod intrinsic (PR #108849)

2024-09-25 Thread Sarah Spall via cfe-commits




spall wrote:

If this builtin is for clang and not just HLSL should the semantics checking be 
in this file and not 'SemaChecking'?

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


[clang] [HLSL] Implementation of the fmod intrinsic (PR #108849)

2024-09-25 Thread Sarah Spall via cfe-commits




spall wrote:

Glad to approve after this gets updated then!

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


[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)

2024-11-07 Thread Sarah Spall via cfe-commits

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


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


[clang] [llvm] [DXIL][SPIRV] Lower `WaveActiveCountBits` intrinsic (PR #113382)

2024-11-07 Thread Sarah Spall via cfe-commits


@@ -1762,6 +1765,37 @@ bool SPIRVInstructionSelector::selectSign(Register 
ResVReg,
   return Result;
 }
 
+bool SPIRVInstructionSelector::selectWaveActiveCountBits(
+Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const {
+  assert(I.getNumOperands() == 3);
+  assert(I.getOperand(2).isReg());
+  MachineBasicBlock &BB = *I.getParent();
+
+  Register BallotReg = MRI->createVirtualRegister(&SPIRV::IDRegClass);

spall wrote:

Is SPIRV::IDRegClass just a register class for all types? Because there are 
others like SPIRV::vIDRegClass, which is for vectors. 

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


[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-10-23 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL] Re-implement countbits with the correct return type (PR #113189)

2024-10-25 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/113189

>From 12cac48dcc10ef9c5fccba2c22911f420298b98b Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 16 Oct 2024 19:00:08 +
Subject: [PATCH 1/4] implement countbits correctly

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 126 +++---
 .../test/CodeGenHLSL/builtins/countbits.hlsl  |  42 +++---
 .../SemaHLSL/BuiltIns/countbits-errors.hlsl   |  14 +-
 llvm/lib/Target/DirectX/DXIL.td   |   5 +-
 llvm/lib/Target/DirectX/DXILOpLowering.cpp|  64 +
 llvm/test/CodeGen/DirectX/countbits.ll|  39 --
 6 files changed, 202 insertions(+), 88 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 30dce60b3ff702..2a612c3746076c 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -705,66 +705,90 @@ float4 cosh(float4);
 
 #ifdef __HLSL_ENABLE_16_BIT
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t countbits(int16_t);
+constexpr uint countbits(int16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t2 countbits(int16_t2);
+constexpr uint2 countbits(int16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t3 countbits(int16_t3);
+constexpr uint3 countbits(int16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int16_t4 countbits(int16_t4);
+constexpr uint4 countbits(int16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t countbits(uint16_t);
+constexpr uint countbits(uint16_t x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t2 countbits(uint16_t2);
+constexpr uint2 countbits(uint16_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t3 countbits(uint16_t3);
+constexpr uint3 countbits(uint16_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
 _HLSL_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint16_t4 countbits(uint16_t4);
+constexpr uint4 countbits(uint16_t4 x) {
+  return __builtin_elementwise_popcount(x);
+}
 #endif
 
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int countbits(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int2 countbits(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int3 countbits(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int4 countbits(int4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint countbits(uint);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint2 countbits(uint2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint3 countbits(uint3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint4 countbits(uint4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t countbits(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t2 countbits(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t3 countbits(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-int64_t4 countbits(int64_t4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t countbits(uint64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t2 countbits(uint64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t3 countbits(uint64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
-uint64_t4 countbits(uint64_t4);
+constexpr uint countbits(int x) {
+  return __builtin_elementwise_popcount(x);
+}  
+constexpr uint2 countbits(int2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(uint x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(uint2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(uint3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(uint4 x) {
+  return __builtin_elementwise_popcount(x);
+}
+
+constexpr uint countbits(int64_t x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint2 countbits(int64_t2 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint3 countbits(int64_t3 x) {
+  return __builtin_elementwise_popcount(x);
+}
+constexpr uint4 countbits(int64_t4 x) {
+  return 

[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

2024-11-06 Thread Sarah Spall via cfe-commits

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


[clang] [llvm] [HLSL][DXIL] Implement `asdouble` intrinsic (PR #114847)

2024-11-07 Thread Sarah Spall via cfe-commits

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

LGTM

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


[clang] [llvm] [HLSL] Implement elementwise popcount (PR #108121)

2024-09-17 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/108121

>From ebb4078d485559f70d79d3b10dc9f4ce401a3261 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Fri, 6 Sep 2024 21:03:05 +
Subject: [PATCH 1/3] implement elementwise popcount to implement countbits

---
 clang/docs/LanguageExtensions.rst |  1 +
 clang/include/clang/Basic/Builtins.td |  6 ++
 clang/lib/CodeGen/CGBuiltin.cpp   |  3 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 71 +++
 clang/lib/Sema/SemaChecking.cpp   |  2 +-
 clang/lib/Sema/SemaHLSL.cpp   |  8 +++
 .../test/CodeGen/builtins-elementwise-math.c  | 37 ++
 clang/test/Sema/builtins-elementwise-math.c   | 21 ++
 .../SemaCXX/builtins-elementwise-math.cpp |  8 +++
 llvm/lib/Target/DirectX/DXIL.td   | 11 +++
 llvm/test/CodeGen/DirectX/countbits.ll| 31 
 llvm/test/CodeGen/DirectX/countbits_error.ll  | 10 +++
 .../SPIRV/hlsl-intrinsics/countbits.ll| 21 ++
 13 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/DirectX/countbits.ll
 create mode 100644 llvm/test/CodeGen/DirectX/countbits_error.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/countbits.ll

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c08697282cbfe8..f62f90fb9650a9 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -667,6 +667,7 @@ Unless specified otherwise operation(±0) = ±0 and 
operation(±infinity) = ±in
  T __builtin_elementwise_log(T x)return the natural logarithm of x 
   floating point types
  T __builtin_elementwise_log2(T x)   return the base 2 logarithm of x  
   floating point types
  T __builtin_elementwise_log10(T x)  return the base 10 logarithm of x 
   floating point types
+ T __builtin_elementwise_popcount(T x)   return the number of 1 bits in x  
   integer types 
  T __builtin_elementwise_pow(T x, T y)   return x raised to the power of y 
   floating point types
  T __builtin_elementwise_bitreverse(T x) return the integer represented 
after reversing the bits of x integer types
  T __builtin_elementwise_exp(T x)returns the base-e exponential, 
e^x, of the specified value  floating point types
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 6cf03d27055cd9..8c5d7ad763bf97 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1322,6 +1322,12 @@ def ElementwiseLog10 : Builtin {
   let Prototype = "void(...)";
 }
 
+def ElementwisePopcount : Builtin {
+  let Spellings = ["__builtin_elementwise_popcount"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 def ElementwisePow : Builtin {
   let Spellings = ["__builtin_elementwise_pow"];
   let Attributes = [NoThrow, Const, CustomTypeChecking];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a52e880a764252..df2b8b5595e8b3 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3834,6 +3834,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_elementwise_floor:
 return RValue::get(emitBuiltinWithOneOverloadedType<1>(
 *this, E, llvm::Intrinsic::floor, "elt.floor"));
+  case Builtin::BI__builtin_elementwise_popcount:
+return RValue::get(emitBuiltinWithOneOverloadedType<1>(
+   *this, E, llvm::Intrinsic::ctpop, "elt.ctpop"));
   case Builtin::BI__builtin_elementwise_roundeven:
 return RValue::get(emitBuiltinWithOneOverloadedType<1>(
 *this, E, llvm::Intrinsic::roundeven, "elt.roundeven"));
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6a50d50ebd3479..6cd6a2caf19994 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -650,6 +650,77 @@ float3 cosh(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cosh)
 float4 cosh(float4);
 
+//===--===//
+// count bits builtins
+//===--===//
+
+/// \fn T countbits(T Val)
+/// \brief Return the number of bits (per component) set in the input integer.
+/// \param Val The input value.
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
+int16_t countbits(int16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_popcount)
+int16_t2 countbits(int16_t2);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(

[clang] Implement HLSL Flat casting (excluding splat cases) (PR #118842)

2024-12-05 Thread Sarah Spall via cfe-commits

spall wrote:

I'm going to change the name of the Cast to HLSLFlatCast.

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


[clang] Implement HLSL Flat casting (excluding splat cases) (PR #118842)

2024-12-05 Thread Sarah Spall via cfe-commits

https://github.com/spall created 
https://github.com/llvm/llvm-project/pull/118842

Implement HLSL Flat casting excluding splat cases
Partly closes #100609 and #100619 

>From 2e932a57ccb992b856b58bec4c30c6b64f24f711 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Thu, 28 Nov 2024 16:23:57 +
Subject: [PATCH 1/4] Flat casts WIP

---
 clang/include/clang/AST/OperationKinds.def|   3 +
 clang/include/clang/Sema/SemaHLSL.h   |   2 +
 clang/lib/AST/Expr.cpp|   1 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGExpr.cpp  |  84 ++
 clang/lib/CodeGen/CGExprAgg.cpp   |  83 +-
 clang/lib/CodeGen/CGExprComplex.cpp   |   1 +
 clang/lib/CodeGen/CGExprConstant.cpp  |   1 +
 clang/lib/CodeGen/CGExprScalar.cpp|  39 +
 clang/lib/CodeGen/CodeGenFunction.h   |   7 +
 clang/lib/Edit/RewriteObjCFoundationAPI.cpp   |   1 +
 clang/lib/Sema/Sema.cpp   |   1 +
 clang/lib/Sema/SemaCast.cpp   |  20 ++-
 clang/lib/Sema/SemaHLSL.cpp   | 143 ++
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp |   1 +
 15 files changed, 384 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/OperationKinds.def 
b/clang/include/clang/AST/OperationKinds.def
index 8788b8ff0ef0a4..9323d4e861a734 100644
--- a/clang/include/clang/AST/OperationKinds.def
+++ b/clang/include/clang/AST/OperationKinds.def
@@ -367,6 +367,9 @@ CAST_OPERATION(HLSLVectorTruncation)
 // Non-decaying array RValue cast (HLSL only).
 CAST_OPERATION(HLSLArrayRValue)
 
+// Aggregate by Value cast (HLSL only).
+CAST_OPERATION(HLSLAggregateCast)
+
 //===- Binary Operations  
-===//
 // Operators listed in order of precedence.
 // Note that additions to this should also update the StmtVisitor class,
diff --git a/clang/include/clang/Sema/SemaHLSL.h 
b/clang/include/clang/Sema/SemaHLSL.h
index ee685d95c96154..6bda1e8ce0ea5b 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -140,6 +140,8 @@ class SemaHLSL : public SemaBase {
   // Diagnose whether the input ID is uint/unit2/uint3 type.
   bool diagnoseInputIDType(QualType T, const ParsedAttr &AL);
 
+  bool CanPerformScalarCast(QualType SrcTy, QualType DestTy);
+  bool CanPerformAggregateCast(Expr *Src, QualType DestType);
   ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg);
 
   QualType getInoutParameterType(QualType Ty);
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index a4fb4d5a1f2ec4..4764bc84ce498a 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1942,6 +1942,7 @@ bool CastExpr::CastConsistency() const {
   case CK_FixedPointToBoolean:
   case CK_HLSLArrayRValue:
   case CK_HLSLVectorTruncation:
+  case CK_HLSLAggregateCast:
   CheckNoBasePath:
 assert(path_empty() && "Cast kind should not have a base path!");
 break;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6b5b95aee35522..b548cef41b7525 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15733,6 +15733,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr 
*E) {
   case CK_IntegralToFixedPoint:
   case CK_MatrixCast:
   case CK_HLSLVectorTruncation:
+  case CK_HLSLAggregateCast:
 llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5fccc9cbb37ec1..b7608b1226758d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5320,6 +5320,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) 
{
   case CK_MatrixCast:
   case CK_HLSLVectorTruncation:
   case CK_HLSLArrayRValue:
+  case CK_HLSLAggregateCast:
 return EmitUnsupportedLValue(E, "unexpected cast lvalue");
 
   case CK_Dependent:
@@ -6358,3 +6359,86 @@ RValue CodeGenFunction::EmitPseudoObjectRValue(const 
PseudoObjectExpr *E,
 LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) {
   return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV;
 }
+
+llvm::Value* CodeGenFunction::PerformLoad(std::pair 
&GEP) {
+  Address GEPAddress = GEP.first;
+  llvm::Value *Idx = GEP.second;
+  llvm::Value *V = Builder.CreateLoad(GEPAddress, "load");
+  if (Idx) { // loading from a vector so perform an extract as well
+return Builder.CreateExtractElement(V, Idx, "vec.load");
+  }
+  return V;
+}
+
+llvm::Value* CodeGenFunction::PerformStore(std::pair 
&GEP,
+  llvm::Value *Val) {
+  Address GEPAddress = GEP.first;
+  llvm::Value *Idx = GEP.second;
+  if (Idx) {
+llvm::Value *V = Builder.CreateLoad(GEPAddress, "load.for.insert");
+return Builder.CreateInsertElement(V, Val, Idx);
+  } else {
+return Builder.CreateStore(Val, GEPAddress);
+  }
+}
+
+void CodeGen

[clang] [HLSL] Implement HLSL Flat casting (excluding splat cases) (PR #118842)

2024-12-05 Thread Sarah Spall via cfe-commits

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


[clang] [HLSL] Implement HLSL Flat casting (excluding splat cases) (PR #118842)

2024-12-05 Thread Sarah Spall via cfe-commits

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


[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-12-03 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/111047

>From 119def060924f13bd1fe07f6d73ce27a1b52ea12 Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Tue, 17 Sep 2024 20:25:46 +
Subject: [PATCH 1/8] theoretically fix issue

---
 clang/lib/Sema/SemaType.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index e526a11973975d..4874a4902a5cc6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5675,6 +5675,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
   assert(!T.isNull() && "T must not be null at the end of this function");
   if (!AreDeclaratorChunksValid)
 return Context.getTrivialTypeSourceInfo(T);
+
+  if (state.didParseHLSLParamMod() && !T->isConstantArrayType())
+T = S.HLSL().getInoutParameterType(T);
   return GetTypeSourceInfoForDeclarator(state, T, TInfo);
 }
 
@@ -8616,7 +8619,6 @@ static void 
HandleHLSLParamModifierAttr(TypeProcessingState &State,
 return;
   if (Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_inout ||
   Attr.getSemanticSpelling() == HLSLParamModifierAttr::Keyword_out) {
-CurType = S.HLSL().getInoutParameterType(CurType);
 State.setParsedHLSLParamMod(true);
   }
 }

>From 3231a7b7327b6550291dfbeeec5a1907a7473e7f Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Wed, 2 Oct 2024 21:34:02 +
Subject: [PATCH 2/8] get inout working

---
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp | 10 +++
 clang/lib/CodeGen/CGCall.cpp |  3 +-
 clang/lib/CodeGen/CGExpr.cpp |  7 +++--
 clang/lib/Sema/SemaExprCXX.cpp   | 13 +++--
 clang/lib/Sema/SemaOverload.cpp  | 43 
 6 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 89fcb6789d880a..e9bacf8d7391c4 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1480,6 +1480,10 @@ class ASTContext : public RefCountedBase {
   /// type to the decayed type.
   QualType getDecayedType(QualType Orig, QualType Decayed) const;
 
+  /// Return the uniqued reference to a constant array type from the
+  /// original array parameter type.
+  QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
+
   /// Return the uniqued reference to a specified array parameter type from the
   /// original array type.
   QualType getArrayParameterType(QualType Ty) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 09d159e5c3efd6..202d17d3999658 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3852,6 +3852,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
   return getDecayedType(T, Decayed);
 }
 
+QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const 
{
+  if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
+return Ty;
+  assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
+  const auto *ATy = cast(Ty);
+  return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
+ ATy->getSizeExpr(), ATy->getSizeModifier(),
+ ATy->getIndexTypeQualifiers().getAsOpaqueValue());
+}
+
 QualType ASTContext::getArrayParameterType(QualType Ty) const {
   if (Ty->isArrayParameterType())
 return Ty;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8f4f5d3ed81601..0206d2c1360d47 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4726,7 +4726,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return emitWritebackArg(*this, args, CRE);
   }
 
-  assert(type->isReferenceType() == E->isGLValue() &&
+  assert(type->isArrayParameterType() ||
+(type->isReferenceType() == E->isGLValue()) &&
  "reference binding to unmaterialized r-value!");
 
   // Add writeback for HLSLOutParamExpr.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 096f4c4f550435..fcab838be40f2b 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5830,9 +5830,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const 
BinaryOperator *E) {
 // This function implements trivial copy assignment for HLSL's
 // assignable constant arrays.
 LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
-  LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
+  // Don't emit an LValue for the RHS because it might not be an LValue
   LValue LHS = EmitLValue(E->getLHS());
-  EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
+  // In C assignment operator RHS is often an RValue.
+  // EmitAggregateAssign expects an LValue for the RHS so call the below
+  // function instead.
+  EmitInitiali

[clang] [HLSL] get inout/out ABI for array parameters working (PR #111047)

2024-12-03 Thread Sarah Spall via cfe-commits

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


  1   2   3   4   >