[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-03 Thread Deric Cheung via cfe-commits


@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {

Icohedron wrote:

`__builtin_addc` was not able to be used to implement `AddUint64` in 
`hlsl_intrinsics.h` and (by extension) `hlsl_detail.h` because its `carryout` 
argument is a pointer (as documented 
[here](https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGBuiltin.cpp#L5508)).

Since pointers are not supported in HLSL, an error is emitted when running HLSL 
codegen tests with an example implementation like the following in 
`hlsl_intrinsics.h`.

```cpp
_HLSL_AVAILABILITY(shadermodel, 6.0)
const inline uint32_t2 AddUint64(uint32_t2 a, uint32_t2 b) {
  uint32_t carry;
  uint32_t low_sum = __builtin_addc(a.x, b.x, 0, &carry);
  uint32_t high_sum = __builtin_addc(a.y, b.y, carry, nullptr);
  return uint32_t2(low_sum, high_sum);
}
```

```
build/lib/clang/20/include/hlsl/hlsl_intrinsics.h:158:50: error: the '&' 
operator is unsupported in HLSL
  158 |   uint32_t low_sum = __builtin_addc(a.x, b.x, 0, &carry);
```


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


[clang] [llvm] Reland "[HLSL] Implement the reflect HLSL function" (PR #125599)

2025-02-03 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron created 
https://github.com/llvm/llvm-project/pull/125599

This PR relands #122992.

A reland was attempted before (#123853), but it [failed to pass the 
`sanitizer-aarch64-linux-bootstrap-hwasan` 
buildbot](https://github.com/llvm/llvm-project/pull/123853#issuecomment-2608389396).
 

An issue (#124045) was made to document the failure and to try to determine the 
cause.

Currently we do not have working local reproduction of the issue, so it is 
difficult to debug and test fixes.
Our current guess is that the hwasan check is being aborted when an error is 
reported via  `report_fatal_error` in the test 
[`reflect-error.ll`](https://github.com/Icohedron/llvm-project/blob/4363cd2685ad5a1772c8a66796d644783bce0951/clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl).
Hence, a fix we are attempting is to define `HWASAN_OPTIONS="abort_on_error=0"` 
when running the test.

@vitalybuka Could you test this PR on the 
`sanitizer-aarch64-linux-bootstrap-hwasan` build bot? I will ask @inbelic to 
commit the PR to an upstream users/ branch.



>From d72c55528a71c9d529ee854cf49d57417f2708b1 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 3 Feb 2025 23:10:16 +
Subject: [PATCH 1/2] Reapply "Reland "[HLSL] Implement the `reflect` HLSL
 function"" (#124046)

This reverts commit 0fe8e70c6609ff86cd40fbb45a85a8ed04c153c2.
---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  16 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 +
 clang/lib/Sema/SemaSPIRV.cpp  |  32 
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 177 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  16 +-
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 
 .../CodeGen/SPIRV/opencl/reflect-error.ll |  13 ++
 13 files changed, 434 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/reflect-error.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index f72c555921dfe68..34933e889ba314b 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -19,3 +19,9 @@ def SPIRVLength : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 11fa295dad9524c..c7b7d048dd2a9b3 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20786,6 +20786,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_length,
 ArrayRef{X}, nullptr, "spv.length");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index b2c8cc6c5c3dbb0..0d568539cd66a85 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -79,6 +79,22 @@ constexpr enable_if_t::value || 
is_same::value, T>
 distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr vector reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --gi

[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -359,18 +359,21 @@ class OpLowerer {
 return lowerToBindAndAnnotateHandle(F);
   }
 
-  Error replaceSplitDoubleCallUsages(CallInst *Intrin, CallInst *Op) {
+  Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
 for (Use &U : make_early_inc_range(Intrin->uses())) {
   if (auto *EVI = dyn_cast(U.getUser())) {
 
 if (EVI->getNumIndices() != 1)
-  return createStringError(std::errc::invalid_argument,
-   "Splitdouble has only 2 elements");
+  return createStringError(

Icohedron wrote:

To be as generic as possible, I could replace the entire function so that it 
reads:
```c++
  Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
for (Use &U : make_early_inc_range(Intrin->uses())) {
  U.set(Op);
}
Intrin->eraseFromParent();
return Error::success();
  }
```
This function would just replace all uses of the intrinsic with one to match 
the new named struct op return type. The function name would need to be 
changed, or it could be inlined into `replaceFunctionWithNamedStructOp`, since 
that is the only user of `replaceExtractElementTypeOfCallUsages`.

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -359,18 +359,21 @@ class OpLowerer {
 return lowerToBindAndAnnotateHandle(F);
   }
 
-  Error replaceSplitDoubleCallUsages(CallInst *Intrin, CallInst *Op) {
+  Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
 for (Use &U : make_early_inc_range(Intrin->uses())) {
   if (auto *EVI = dyn_cast(U.getUser())) {
 
 if (EVI->getNumIndices() != 1)
-  return createStringError(std::errc::invalid_argument,
-   "Splitdouble has only 2 elements");
+  return createStringError(

Icohedron wrote:

The new `replaceFunctionWithNamedStructOp` would look like this

```c++
  [[nodiscard]] bool replaceFunctionWithNamedStructOp(Function &F,
  dxil::OpCode DXILOp,
  Type *NewRetTy) {
bool IsVectorArgExpansion = isVectorArgExpansion(F);
return replaceFunction(F, [&](CallInst *CI) -> Error {
  SmallVector Args;
  OpBuilder.getIRB().SetInsertPoint(CI);
  if (IsVectorArgExpansion) {
SmallVector NewArgs = argVectorFlatten(CI, OpBuilder.getIRB());
Args.append(NewArgs.begin(), NewArgs.end());
  } else
Args.append(CI->arg_begin(), CI->arg_end());

  Expected OpCall =
  OpBuilder.tryCreateOp(DXILOp, Args, CI->getName(), NewRetTy);
  if (Error E = OpCall.takeError())
return E;

  for (Use &U : make_early_inc_range(CI->uses())) {
U.set(*OpCall);
  }
  CI->eraseFromParent();

  return Error::success();
});
  }
```

It works. All aggregate operations (`extractvalue`, `insertvalue`) get replaced 
correctly.
The only issue is if a function returns the result directly:
```c++
define noundef { i32, i1 } @test_UAddc2(i32 noundef %a, i32 noundef %b) {
; CHECK-LABEL: define noundef %dx.types.i32c @test_UAddc2(
; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) {
; CHECK-NEXT:[[UAddc:%.*]] = call %dx.types.i32c 
@dx.op.binaryWithCarryOrBorrow.i32(i32 44, i32 [[A]], i32 [[B]])
; CHECK-NEXT:ret %dx.types.i32c [[Result]]
; 
  %uaddc = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
  ret { i32, i1 } %uaddc
}
```
It results in an error that reads:
```
opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library 
/home/icohedron/workspace/feature-uaddc/llvm/test/CodeGen/DirectX/UAddc.ll
Function return type does not match operand type of return inst!
  ret %dx.types.i32c %uaddc1
 { i32, i1 }in function test_UAddc2
LLVM ERROR: Broken function found, compilation aborted!
...
```


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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125319

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/5] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e075..ffa60bf98aea06 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e7..2d7d306a207417 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e..3a2c74f39afa78 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry
+  llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
+  llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
+
+  // Insert the low and high word sums into the result vector
+  Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
+  Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
+   "hlsl.AddUint64");
+}
+return Result;
+  }
   case Builtin::BI__builtin_hlsl_resource_getpointer: {
 Value *HandleOp = EmitScalarE

[clang] [llvm] Reland "[HLSL] Implement the reflect HLSL function" (PR #125599)

2025-02-04 Thread Deric Cheung via cfe-commits

Icohedron wrote:

@vitalybuka Could you get more details as to why the original PR failed in the 
hwasan-check from the `sanitizer-aarch64-linux-bootstrap-hwasan` buildbot? The 
buildbot's report is linked here: 
[https://lab.llvm.org/buildbot/#/builders/55/builds/5962](https://lab.llvm.org/buildbot/#/builders/55/builds/5962)


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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;

Icohedron wrote:

@inbelic 
[suggested](https://github.com/llvm/llvm-project/pull/125319#discussion_r1941619629)
 using `diag::err_vec_builtin_non_vector` instead.
It has the message "%select{first two|all}1 arguments to %0 must be vectors"


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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -2023,6 +2024,18 @@ static bool CheckAllArgsHaveFloatRepresentation(Sema *S, 
CallExpr *TheCall) {
 checkAllFloatTypes);
 }
 
+static bool CheckUnsignedIntegerRepresentation(Sema *S, CallExpr *TheCall) {
+  auto checkUnsignedInteger = [](clang::QualType PassedType) -> bool {
+clang::QualType BaseType =
+PassedType->isVectorType()
+? PassedType->getAs()->getElementType()
+: PassedType;
+return !BaseType->isUnsignedIntegerType();

Icohedron wrote:

According to what I see in the original issue and in the DXC implementation, 
only unsigned integers are allowed (specifically, `uint2` and `uint4`). 
`clang/test/SemaHLSL/BuiltIns/AddUIint64-errors.hlsl` has a test with `int2` 
passed as arguments that is expected to fail.

As for checking if the integer is 32-bits, that is a good idea. The following 
test is currently valid and does not emit an error.
```c++
uint2 test_16_bit_integer_type(uint16_t2 a, uint16_t2 b) {
  return __builtin_hlsl_adduint64(a, b);
}
```
I am having trouble trying to implement a check on the integer bit count 
however. 
I do not know how to get access to `llvm::IntegerType::getIntegerBitWidth()` 
from a `clang::QualType`.




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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;

Icohedron wrote:

I would still need this change for the other error message when a uint3 is 
passed.
We don't know if the programmer intended to use the uint2 or the uint4 version 
of the function, so uint3 has neither more or less elements than expected -- 
it's just an incorrect number.

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125319

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/4] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e0759..ffa60bf98aea06f 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e75..2d7d306a2074179 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e5..3a2c74f39afa78f 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry
+  llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
+  llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
+
+  // Insert the low and high word sums into the result vector
+  Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
+  Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
+   "hlsl.AddUint64");
+}
+return Result;
+  }
   case Builtin::BI__builtin_hlsl_resource_getpointer: {
 Value *HandleOp = EmitS

[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,17 @@
+; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 
2>&1 | FileCheck %s
+
+; DXIL operation UAddc only supports i32. Other integer types are unsupported.
+; CHECK: in function uaddc_i16

Icohedron wrote:

LLVM ERROR is not output there.

The full error message is: `error: :0:0: in function uaddc_i16 i16 
(i16, i16): Cannot create UAddc operation: Invalid overload type`

This is similar to the way other directx error tests were written, such as 
[cos](https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/DirectX/cos_error.ll)

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only 
-disable-llvm-passes -verify
+
+uint2 test_too_few_arg() {
+  return __builtin_hlsl_adduint64();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
0}}
+}
+
+uint4 test_too_many_arg(uint4 a) {
+  return __builtin_hlsl_adduint64(a, a, a);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+uint2 test_mismatched_arg_types(uint2 a, uint4 b) {
+  return __builtin_hlsl_adduint64(a, b);
+  // expected-error@-1 {{all arguments to '__builtin_hlsl_adduint64' must have 
the same type}}
+}
+
+uint2 test_too_many_arg_elements(uint3 a, uint3 b) {

Icohedron wrote:

Renamed the test in commit 
[28b7eb8](https://github.com/llvm/llvm-project/pull/125319/commits/28b7eb8c6ac603ef1c316e7731b07cb6f6f3a34e)

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -21,6 +21,7 @@
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Builtins.h"
+#include "clang/Basic/DiagnosticParse.h"

Icohedron wrote:

Removed with commit 
[28b7eb8](https://github.com/llvm/llvm-project/pull/125319/commits/28b7eb8c6ac603ef1c316e7731b07cb6f6f3a34e)

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only 
-disable-llvm-passes -verify
+
+uint2 test_too_few_arg() {
+  return __builtin_hlsl_adduint64();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
0}}
+}
+
+uint4 test_too_many_arg(uint4 a) {
+  return __builtin_hlsl_adduint64(a, a, a);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+uint2 test_mismatched_arg_types(uint2 a, uint4 b) {
+  return __builtin_hlsl_adduint64(a, b);
+  // expected-error@-1 {{all arguments to '__builtin_hlsl_adduint64' must have 
the same type}}
+}
+
+uint2 test_too_many_arg_elements(uint3 a, uint3 b) {
+  return __builtin_hlsl_adduint64(a, b);
+  // expected-error@-1 {{incorrect number of elements in vector operand 
(expected 2 or 4 elements, have 3)}}
+}
+
+uint4 test_too_few_arg_elements(uint3 a, uint3 b) {
+  return __builtin_hlsl_adduint64(a, b);
+  // expected-error@-1 {{incorrect number of elements in vector operand 
(expected 2 or 4 elements, have 3)}}
+}

Icohedron wrote:

Removed in commit 
[28b7eb8](https://github.com/llvm/llvm-project/pull/125319/commits/28b7eb8c6ac603ef1c316e7731b07cb6f6f3a34e)

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -2214,6 +2227,42 @@ static bool CheckResourceHandle(
 // returning an ExprError
 bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) 
{
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+if (CheckUnsignedIntegerRepresentation(&SemaRef, TheCall))
+  return true;
+
+// CheckVectorElementCallArgs(...) guarantees both args are the same type.
+assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() &&
+   "Both args must be of the same type");
+
+// ensure both args are vectors
+auto *VTy = TheCall->getArg(0)->getType()->getAs();
+if (!VTy) {
+  SemaRef.Diag(TheCall->getBeginLoc(),
+   diag::err_vector_incorrect_num_elements)

Icohedron wrote:

I changed the error message for this in commit 
[28b7eb8](https://github.com/llvm/llvm-project/pull/125319/commits/28b7eb8c6ac603ef1c316e7731b07cb6f6f3a34e)

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;

Icohedron wrote:

My latest commit 
([28b7eb8](https://github.com/llvm/llvm-project/pull/125319/commits/28b7eb8c6ac603ef1c316e7731b07cb6f6f3a34e))
 changed the diag message. Is it now to your liking, or do you still think the 
diag message should be changed?

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -359,18 +359,21 @@ class OpLowerer {
 return lowerToBindAndAnnotateHandle(F);
   }
 
-  Error replaceSplitDoubleCallUsages(CallInst *Intrin, CallInst *Op) {
+  Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
 for (Use &U : make_early_inc_range(Intrin->uses())) {
   if (auto *EVI = dyn_cast(U.getUser())) {
 
 if (EVI->getNumIndices() != 1)
-  return createStringError(std::errc::invalid_argument,
-   "Splitdouble has only 2 elements");
+  return createStringError(

Icohedron wrote:

I don't think it is possible to make an HLSL test that exercises the error on 
`if (EVI->getNumIndices() != 1)`. It's just invalid LLVM IR to have more 
indices than allowed for the struct type. It is caught by some other error 
handler:
```
$ opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library 
/home/icohedron/workspace/feature-uaddc/llvm/test/CodeGen/DirectX/UAddc.ll
/home/icohedron/workspace/feature-uaddc/build/bin/opt: 
/home/icohedron/workspace/feature-uaddc/llvm/test/CodeGen/DirectX/UAddc.ll:35:25:
 error: invalid indices for extractvalue
  %carry = extractvalue { i32, i1 } %uaddc, 1, 0
```

The other error is able to be exercised just by having a use that is not an 
extractvalue. For example, returning the `{ i32, i1 }`:
```
$ opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library 
/home/icohedron/workspace/feature-uaddc/llvm/test/CodeGen/DirectX/UAddc.ll
error: :0:0: in function test_UAddc2 { i32, i1 } (i32, i32): call use 
is not ExtractValueInst
```

I also see now that `std::string(Intrin->getOpcodeName()` only says "call" and 
doesn't mention the name of the actual intrinsic being called. So that needs to 
be fixed, and an error test should be made.

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -359,18 +359,21 @@ class OpLowerer {
 return lowerToBindAndAnnotateHandle(F);
   }
 
-  Error replaceSplitDoubleCallUsages(CallInst *Intrin, CallInst *Op) {
+  Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
 for (Use &U : make_early_inc_range(Intrin->uses())) {
   if (auto *EVI = dyn_cast(U.getUser())) {
 
 if (EVI->getNumIndices() != 1)
-  return createStringError(std::errc::invalid_argument,
-   "Splitdouble has only 2 elements");
+  return createStringError(

Icohedron wrote:

I can replace the error (that checks the number of indicies = 1) with an 
assert, but since I changed the function name to be more generic, I don't think 
it should even be present.

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits


@@ -359,18 +359,21 @@ class OpLowerer {
 return lowerToBindAndAnnotateHandle(F);
   }
 
-  Error replaceSplitDoubleCallUsages(CallInst *Intrin, CallInst *Op) {
+  Error replaceExtractElementTypeOfCallUsages(CallInst *Intrin, CallInst *Op) {
 for (Use &U : make_early_inc_range(Intrin->uses())) {
   if (auto *EVI = dyn_cast(U.getUser())) {
 
 if (EVI->getNumIndices() != 1)
-  return createStringError(std::errc::invalid_argument,
-   "Splitdouble has only 2 elements");
+  return createStringError(

Icohedron wrote:

Should there even be an error if there are non-`extractvalue` instructions 
using the result?
The function name I chose (`replaceExtractElementTypeOfCallUsages`) implies it 
will just change the type of `extractelement` instructions that use the result 
of the call.

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-04 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-06 Thread Deric Cheung via cfe-commits


@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {

Icohedron wrote:

Do you think it is something I should do for this implementation?
Are there other HLSL functions that would benefit from / reuse the new builtin 
using the out args?

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits


@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;

Icohedron wrote:

I made a new commit 
([d2b315a](https://github.com/llvm/llvm-project/pull/125319/commits/d2b315a24f850c6115675ee99c804873f19a8f40))
 that creates a new diag message specifically for AddUint64, as per your 
suggestion (which I can't seem to find anymore?).
Is this better?

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125319

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/6] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e0759..ffa60bf98aea06f 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e75..2d7d306a2074179 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e5..3a2c74f39afa78f 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry
+  llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
+  llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
+
+  // Insert the low and high word sums into the result vector
+  Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
+  Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
+   "hlsl.AddUint64");
+}
+return Result;
+  }
   case Builtin::BI__builtin_hlsl_resource_getpointer: {
 Value *HandleOp = EmitS

[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125319

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/6] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e075..ffa60bf98aea06 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e7..2d7d306a207417 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e..3a2c74f39afa78 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry
+  llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
+  llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
+
+  // Insert the low and high word sums into the result vector
+  Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
+  Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
+   "hlsl.AddUint64");
+}
+return Result;
+  }
   case Builtin::BI__builtin_hlsl_resource_getpointer: {
 Value *HandleOp = EmitScalarE

[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125319

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/8] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e0759..ffa60bf98aea06f 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e75..2d7d306a2074179 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e5..3a2c74f39afa78f 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry
+  llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
+  llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
+
+  // Insert the low and high word sums into the result vector
+  Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
+  Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
+   "hlsl.AddUint64");
+}
+return Result;
+  }
   case Builtin::BI__builtin_hlsl_resource_getpointer: {
 Value *HandleOp = EmitS

[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-05 Thread Deric Cheung via cfe-commits


@@ -12553,6 +12553,8 @@ def err_std_initializer_list_malformed : Error<
   "%0 layout not recognized. Must be a non-polymorphic class type with no 
bases and two fields: a 'const E *' and either another 'const E *' or a 
'std::size_t'">;
 
 // HLSL Diagnostics
+def err_hlsl_adduint64_invalid_arguments: Error<

Icohedron wrote:

I pushed a new commit 
([eac0fe5](https://github.com/llvm/llvm-project/pull/125319/commits/eac0fe53c4a306886256ea52b308b3e842572170)).

The case of a scalar being passed as an argument is now back to using 
`err_vec_builtin_non_vector` to emit an example error message of: `all 
arguments to AddUint64 must be vectors`

The case of a `uint3` being passed as an argument is now using a new diag 
called `err_invalid_even_odd_vector_element_count` which emits an example error 
message of: `invalid element count of 3 in vector operand (expected an even 
element count in the range of 2 and 4)`.

I omitted the expected type from the error message, because passing in an 
invalid type would hit a separate error handler anyways. (The error would be 
`passing 'int3' (aka 'vector') to parameter of incompatible type 
'__attribute__((__vector_size__(3 * sizeof(unsigned int unsigned int' 
(vector of 3 'unsigned int' values)`

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


[clang] [llvm] Reland "[HLSL] Implement the reflect HLSL function" (PR #125599)

2025-02-10 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125599

>From dc616212f496098776d30f56151213d530917ba2 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 3 Feb 2025 23:10:16 +
Subject: [PATCH 1/2] Reapply "Reland "[HLSL] Implement the `reflect` HLSL
 function"" (#124046)

This reverts commit 0fe8e70c6609ff86cd40fbb45a85a8ed04c153c2.
---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  16 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 +
 clang/lib/Sema/SemaSPIRV.cpp  |  32 
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 177 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  16 +-
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 
 .../CodeGen/SPIRV/opencl/reflect-error.ll |  13 ++
 13 files changed, 434 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/reflect-error.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index f72c555921dfe68..34933e889ba314b 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -19,3 +19,9 @@ def SPIRVLength : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2edb..509784888b445b1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20790,6 +20790,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_length,
 ArrayRef{X}, nullptr, "spv.length");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index b2c8cc6c5c3dbb0..0d568539cd66a85 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -79,6 +79,22 @@ constexpr enable_if_t::value || 
is_same::value, T>
 distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr vector reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d1f5fdff8b6008d..4e416ffc0e1e36a 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -2008,6 +2008,49 @@ double3 rcp(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp)
 double4 rcp(double4);
 
+//===--===//
+// reflect builtin
+//===--===//
+
+/// \fn T reflect(T I, T N)
+/// \brief Returns a reflection using an incident ray, \a I, and a surface
+/// normal, \a N.
+/// \param I The incident ray.
+/// \param N The surface normal.
+///
+/// The return value is a floating-point vector that represents the reflection
+/// of the incident ray, \a I, off a surface with the normal \a N.
+///
+/// This function calculates the reflection vector using the following formula:
+/// V = I - 2 * N 

[clang] [llvm] Reland "[HLSL] Implement the reflect HLSL function" (PR #125599)

2025-02-10 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-11 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-02-10 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,40 @@
+; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | 
FileCheck %s
+
+; CHECK: %dx.types.i32c = type { i32, i1 }

Icohedron wrote:

Perhaps I made the incorrect assumption that UAddc only accepts scalars. In the 
current implementation, UAddc is only used with scalar i32 arguments because 
the codegen for AddUint64 only uses the scalar version of the 
uadd_with_overflow llvm intrinsic. 

The only case where the resulting front-end IR, DXIL, and SPIR-V will differ 
from the current implementation is when `AddUint64` receives `uint4` arguments.

With the current version of the PR, I can do a successful end-to-end 
compilation of of the [`AddUint64.hlsl` 
test](https://github.com/llvm/llvm-project/blob/55f764e23e8b14328192ed05b3d8429f70b22277/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl)
 (which uses uint2 and uint4 vectors) using the command:
`build/bin/clang -cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-library clang/test/CodeGenHLSL/builtins/AddUint64.hlsl 
-emit-llvm -o - | build/bin/opt -S -scalarizer -dxil-op-lower 
-mtriple=dxil-pc-shadermodel6.3-library -o -`.
This works because the vector is already scalarized in the clang/front-end 
codegen.

I will work on reimplementing AddUint64 for the uint4 case by using vectors, 
and make UAddc scalarizable.


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


[clang] [llvm] Reland "[HLSL] Implement the reflect HLSL function" (PR #125599)

2025-02-11 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] Reland "[HLSL] Implement the reflect HLSL function" (PR #125599)

2025-02-11 Thread Deric Cheung via cfe-commits

Icohedron wrote:

To get the PR up and running, I am just marking hwasan as unsupported for now.
A proper fix will be implemented later. The Issue #124045 will remain open to 
track this.

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


[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-01-31 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron created 
https://github.com/llvm/llvm-project/pull/125319

This PR addresses #99205 

- Implements the HLSL intrinsic `AddUint64` used to perform unsigned 64-bit 
integer addition by using pairs of unsigned 32-bit integers instead of native 
64-bit types
  - The LLVM intrinsic `uadd_with_overflow` is used in the implementation of 
`AddUint64` in `CGBuiltin.cpp`
- The DXIL op `UAddc` was defined in `DXIL.td`, and a lowering of the LLVM 
intrinsic `uadd_with_overflow` to the `UAddc` DXIL op was implemented in 
`DXILOpLowering.cpp`

Notes:
- `__builtin_addc` was not able to be used to implement `AddUint64` in 
`hlsl_intrinsics.h` because its `CarryOut` argument is a pointer, and pointers 
are not supported in HLSL
- A lowering of the LLVM intrinsic `uadd_with_overflow` to SPIR-V [already 
exists](https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll)
 
- When lowering the LLVM intrinsic `uadd_with_overflow` to the `UAddc` DXIL op, 
the anonymous struct type `{ i32, i1 }` is replaced with a named struct type 
`%dx.types.i32c`. This aspect of the implementation may be changed when issue 
#113192 gets addressed

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/2] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e075..ffa60bf98aea06 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e7..2d7d306a207417 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e..3a2c74f39afa78 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Bui

[clang] [llvm] [HLSL] [DXIL] Implement the `AddUint64` HLSL function and the `UAddc` DXIL op (PR #125319)

2025-01-31 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/125319

>From 1e194fdf6dc731276cd867501708b348e3bbc97c Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/3] Implement AddUint64 HLSL codegen and sema

---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 49 +
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 46 
 7 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 60c360d4a9e075..ffa60bf98aea06 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e7..2d7d306a207417 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10623,7 +10623,7 @@ def err_second_argument_to_cwsc_not_pointer : Error<
   "second argument to __builtin_call_with_static_chain must be of pointer 
type">;
 
 def err_vector_incorrect_num_elements : Error<
-  "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+  "%select{too many|too few|incorrect number of}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 26bdc5e36e..3a2c74f39afa78 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19105,6 +19105,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry
+  llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB);
+  llvm::Value *HighSumPlusCarry = Builder.CreateAdd(HighSum, ZExtCarry);
+
+  // Insert the low and high word sums into the result vector
+  Result = Builder.CreateInsertElement(Result, LowSum, 2 * i + 0);
+  Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, 2 * i + 1,
+   "hlsl.AddUint64");
+}
+return Result;
+  }
   case Builtin::BI__builtin_hlsl_resource_getpointer: {
 Value *HandleOp = EmitScalarE

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-09 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From 07112471edfc569eb12b2a6178ddc28b4f3a36d5 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH 1/5] Implement D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h|  8 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h| 17 +
 .../CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl  | 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl   | 13 +
 4 files changed, 50 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..6e48800dae6698
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4 ( float4 p1 ) {
+  // CHECK: %[[SCALED:.*]] = fmul <4 x float> %{{.*}}, splat (float 
0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4 ( p1 );
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..fb41c212bd0be3
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}

>From d8632ec0526536afb5ce9c3d242079be777c15c0 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 17:30:45 +
Subject: [PATCH 2/5] Add additional sema tests for D3DCOLORtoUBYTE4 for
 invalid arg types

---
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl| 16 
 1 file changed, 16 insertions(+)

diff --

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-09 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From 5610b225e76b046e911c1a7a0c1e4ccc128d35a1 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH] [HLSL] Implement the D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h  |  8 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 17 +++
 .../builtins/D3DCOLORtoUBYTE4.hlsl| 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl | 29 +++
 4 files changed, 66 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..7021de7192b5e5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4(float4 p1) {
+  // CHECK: %[[SCALED:.*]] = fmul [[FMFLAGS:.*]]<4 x float> %{{.*}}, splat 
(float 0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4(p1);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..e9ba851007c941
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}
+
+int4 float2_arg(float2 v) {
+return D3DCOLORtoUBYTE4(v);
+// expected-error@-1 {{no matching function for call to 
'D3DCOLORtoUBYTE4'}}
+// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
no known conversion from 'vector<[...], 2>' to 'vector<[...], 4>' for 1st 
argument}}
+}
+
+struct S {
+  flo

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-10 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From 5610b225e76b046e911c1a7a0c1e4ccc128d35a1 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH 1/2] [HLSL] Implement the D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h  |  8 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 17 +++
 .../builtins/D3DCOLORtoUBYTE4.hlsl| 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl | 29 +++
 4 files changed, 66 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..7021de7192b5e5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4(float4 p1) {
+  // CHECK: %[[SCALED:.*]] = fmul [[FMFLAGS:.*]]<4 x float> %{{.*}}, splat 
(float 0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4(p1);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..e9ba851007c941
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}
+
+int4 float2_arg(float2 v) {
+return D3DCOLORtoUBYTE4(v);
+// expected-error@-1 {{no matching function for call to 
'D3DCOLORtoUBYTE4'}}
+// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
no known conversion from 'vector<[...], 2>' to 'vector<[...], 4>' for 1st 
argument}}
+}
+
+struct S {
+ 

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-21 Thread Deric Cheung via cfe-commits

Icohedron wrote:

> Will a follow-up issue be created to move the useful Sema helpers into a 
> common file?

I just created issue #123831 for this.

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


[clang] [llvm] Reland "[HLSL] Implement the `reflect` HLSL function" (PR #123853)

2025-01-21 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron created 
https://github.com/llvm/llvm-project/pull/123853

This PR relands [#122992](https://github.com/llvm/llvm-project/pull/122992).

Some machines were failing to run the `reflect-error.ll` test due to the RUN 
lines
```llvm
; RUN: not %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o 
/dev/null 2>&1 -filetype=obj %}
; RUN: not %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o 
/dev/null 2>&1 -filetype=obj %}
```
which failed when `spirv-tools` was not present on the machine due to running 
the command `not` without any arguments.

These RUN lines have been removed since they don't actually test anything new 
compared to the other two RUN lines due to the expected error during 
instruction selection.
```llvm
; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o 
/dev/null 2>&1 | FileCheck %s
; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o 
/dev/null 2>&1 | FileCheck %s
```

>From f9fd109c4038f5646586c70c40bc298c20996d40 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH 1/4] Implement the `reflect` HLSL function

---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  16 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 +
 clang/lib/Sema/SemaSPIRV.cpp  |  32 
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 177 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  12 ++
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 
 .../CodeGen/SPIRV/opencl/reflect-error.ll |  22 +++
 13 files changed, 443 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/reflect-error.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index f72c555921dfe6..34933e889ba314 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -19,3 +19,9 @@ def SPIRVLength : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index b80833fd91884d..ab61609ab35a99 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20538,6 +20538,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_length,
 ArrayRef{X}, nullptr, "spv.length");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index b2c8cc6c5c3dbb..0d568539cd66a8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -79,6 +79,22 @@ constexpr enable_if_t::value || 
is_same::value, T>
 distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr vector reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d1e4eb08aa7646..3b47074f07ecf4 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-21 Thread Deric Cheung via cfe-commits


@@ -34,6 +34,7 @@
 #include "llvm/IR/IntrinsicsSPIRV.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"

Icohedron wrote:

I don't recall adding that. I think my IDE did that for me :P 
I will remove it

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-17 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122992

>From 7ddd5b264731ef375d99d012d9fbfd54c744e5b2 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH 1/5] Implement `reflect` HLSL function

---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  17 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 
 clang/lib/Sema/SemaSPIRV.cpp  |  32 +++
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 195 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 +++
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 +++
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |   2 +
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 +++
 12 files changed, 430 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index f72c555921dfe68..34933e889ba314b 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -19,3 +19,9 @@ def SPIRVLength : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index b80833fd91884d8..ab61609ab35a99f 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20538,6 +20538,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_length,
 ArrayRef{X}, nullptr, "spv.length");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index b2c8cc6c5c3dbb0..3e09f8b10735122 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -79,6 +79,23 @@ constexpr enable_if_t::value || 
is_same::value, T>
 distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d1e4eb08aa7646a..54454cf0ea0d0bd 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -2008,6 +2008,49 @@ double3 rcp(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp)
 double4 rcp(double4);
 
+//===--===//
+// reflect builtin
+//===--===//
+
+/// \fn T reflect(T I, T N)
+/// \brief Returns a reflection using an incident ray, \a I, and a surface
+/// normal, \a N.
+/// \param I The incident ray.
+/// \param N The surface normal.
+///
+/// The return value is a floating-point vector that represents the reflection
+/// of the incident ray, \a I, off a surface with the normal \a N.
+///
+/// This function calculates the reflection vector using the following formula:
+/// V = I - 2 * N * dot(I N) .
+///
+/// N must already be normalized in order to achieve the desired result.
+///
+/// The operands must all be a scalar or vector whose component type is
+/// floating-point.
+///
+/// Result type 

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-20 Thread Deric Cheung via cfe-commits


@@ -3030,6 +3031,15 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register 
ResVReg,
 return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
   case Intrinsic::spv_normalize:
 return selectExtInst(ResVReg, ResType, I, CL::normalize, GL::Normalize);
+  case Intrinsic::spv_reflect:
+if 
(!STI.canUseExtInstSet(SPIRV::InstructionSet::InstructionSet::GLSL_std_450)) {

Icohedron wrote:

Should I add a similar conditional to the OpenCL overloaded version of 
selectExtInst? Just to keep the OpenCL and GLSL functions similar.

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-20 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122992

>From f9fd109c4038f5646586c70c40bc298c20996d40 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH 1/2] Implement the `reflect` HLSL function

---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  16 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 +
 clang/lib/Sema/SemaSPIRV.cpp  |  32 
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 177 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  12 ++
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 
 .../CodeGen/SPIRV/opencl/reflect-error.ll |  22 +++
 13 files changed, 443 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/reflect-error.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index f72c555921dfe6..34933e889ba314 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -19,3 +19,9 @@ def SPIRVLength : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index b80833fd91884d..ab61609ab35a99 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20538,6 +20538,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_length,
 ArrayRef{X}, nullptr, "spv.length");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index b2c8cc6c5c3dbb..0d568539cd66a8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -79,6 +79,22 @@ constexpr enable_if_t::value || 
is_same::value, T>
 distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr vector reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d1e4eb08aa7646..3b47074f07ecf4 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -2008,6 +2008,49 @@ double3 rcp(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp)
 double4 rcp(double4);
 
+//===--===//
+// reflect builtin
+//===--===//
+
+/// \fn T reflect(T I, T N)
+/// \brief Returns a reflection using an incident ray, \a I, and a surface
+/// normal, \a N.
+/// \param I The incident ray.
+/// \param N The surface normal.
+///
+/// The return value is a floating-point vector that represents the reflection
+/// of the incident ray, \a I, off a surface with the normal \a N.
+///
+/// This function calculates the reflection vector using the following formula:
+/// V = I - 2 * N * dot(I N) .
+///
+/// N must already be normalized in order to achieve the desired result.
+///
+/// The operands must a

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-21 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-21 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,22 @@
+; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s 
-o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s 
-o /dev/null 2>&1 | FileCheck %s
+; RUN: not %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o 
/dev/null 2>&1 -filetype=obj %}
+; RUN: not %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o 
/dev/null 2>&1 -filetype=obj %}
+
+; CHECK: LLVM ERROR: Intrinsic selection not supported for this instruction 
set: %{{.*}} = G_INTRINSIC intrinsic(@llvm.spv.reflect), %{{.*}}, %{{.*}}

Icohedron wrote:

I have changed the error message to read `LLVM ERROR: %{{.*}} = G_INTRINSIC 
intrinsic(@llvm.spv.reflect), %{{.*}}, %{{.*}} is only supported with the GLSL 
extended instruction set.`

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


[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-13 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From 5610b225e76b046e911c1a7a0c1e4ccc128d35a1 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH 1/3] [HLSL] Implement the D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h  |  8 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 17 +++
 .../builtins/D3DCOLORtoUBYTE4.hlsl| 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl | 29 +++
 4 files changed, 66 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..7021de7192b5e5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4(float4 p1) {
+  // CHECK: %[[SCALED:.*]] = fmul [[FMFLAGS:.*]]<4 x float> %{{.*}}, splat 
(float 0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4(p1);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..e9ba851007c941
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}
+
+int4 float2_arg(float2 v) {
+return D3DCOLORtoUBYTE4(v);
+// expected-error@-1 {{no matching function for call to 
'D3DCOLORtoUBYTE4'}}
+// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
no known conversion from 'vector<[...], 2>' to 'vector<[...], 4>' for 1st 
argument}}
+}
+
+struct S {
+ 

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-13 Thread Deric Cheung via cfe-commits


@@ -41,6 +41,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4_impl(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f

Icohedron wrote:

I revised the comment to mention that the scaling factor is the same as FXC and 
also the DXC DXIL implementation.
I also kept the link to the stackoverflow discussion, as the comments in the 
DXC DXIL implementation referred to it but did not provide a link, which I 
think is kind of important.

Are these new comments more suitable? Or should I just simply just provide a 
link to the DXC implementation and cut out the repetition?

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-14 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)

2025-01-14 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron created 
https://github.com/llvm/llvm-project/pull/122992

Fixes #99152

Tasks completed:

- Implement `reflect` in `clang/lib/Headers/hlsl/hlsl_intrinsics.h`
- Implement the `reflect` SPIR-V target built-in in 
`clang/include/clang/Basic/BuiltinsSPIRV.td`
- Add a SPIR-V fast path in `clang/lib/Headers/hlsl/hlsl_detail.h` in the form
 ```c++
#if (__has_builtin(__builtin_spirv_reflect))
  return __builtin_spirv_reflect(...);
 #else
   return ...; // regular behavior
 #endif
 ```
- Add codegen for the SPIR-V `reflect` built-in to `EmitSPIRVBuiltinExpr` in 
`clang/lib/CodeGen/CGBuiltin.cpp`
- Add HLSL codegen tests to `clang/test/CodeGenHLSL/builtins/reflect.hlsl`
- Add SPIR-V built-in codegen tests to 
`clang/test/CodeGenSPIRV/Builtins/reflect.c`
- Add sema tests to `clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl`
- Add SPIR-V sema tests to `clang/test/CodeGenSPIRV/Builtins/reflect-errors.c`
- Create the `int_spv_reflect` intrinsic in 
`llvm/include/llvm/IR/IntrinsicsSPIRV.td`
- In `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` create the `reflect` 
lowering and map it to `int_spv_reflect` in 
`SPIRVInstructionSelector::selectIntrinsic`
- Create a SPIR-V backend test case in 
`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll`

Additional tasks completed:

- Implement sema check for the `reflect` SPIR-V built-in in 
`clang/lib/Sema/SemaSPIRV.cpp`
  - Required for HLSL codegen to work via the SPIR-V fast path, otherwise the 
test  `clang/test/CodeGenHLSL/builtins/reflect.hlsl` outright fails to compile

Incomplete tasks:

- Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/opencl/reflect.ll
  - I do not think an OpenCL test is applicable in this case because the 
[OpenCL SPIR-V extended instruction 
set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html)
 does not include a `reflect` function

>From 3f3b8c75c14bb9b3ed611c9cddec49d0e9339705 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH] Implement `reflect` HLSL function

---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  17 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 
 clang/lib/Sema/SemaSPIRV.cpp  |  32 +++
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 195 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 +++
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 +++
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |   2 +
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 +++
 12 files changed, 430 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
 ArrayRef{X, Y}, nullptr, "spv.distance");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.

[clang] [llvm] [HLSL] Implement `reflect` HLSL function (PR #122992)

2025-01-14 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-16 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122992

>From 3f3b8c75c14bb9b3ed611c9cddec49d0e9339705 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH 1/3] Implement `reflect` HLSL function

---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  17 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 
 clang/lib/Sema/SemaSPIRV.cpp  |  32 +++
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 195 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 +++
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 +++
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |   2 +
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 +++
 12 files changed, 430 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
 ArrayRef{X, Y}, nullptr, "spv.distance");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -68,6 +68,23 @@ distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 #endif
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d2d3abd92ea6a8..484ae708342a59 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1919,6 +1919,49 @@ double3 rcp(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp)
 double4 rcp(double4);
 
+//===--===//
+// reflect builtin
+//===--===//
+
+/// \fn T reflect(T I, T N)
+/// \brief Returns a reflection using an incident ray, \a I, and a surface
+/// normal, \a N.
+/// \param I The incident ray.
+/// \param N The surface normal.
+///
+/// The return value is a floating-point vector that represents the reflection
+/// of the incident ray, \a I, off a surface with the normal \a N.
+///
+/// This function calculates the reflection vector using the following formula:
+/// V = I - 2 * N * dot(I N) .
+///
+/// N must already be normalized in order to achieve the desired result.
+///
+/// The operands must all be a scalar or vector whose component type is
+/// floating-point.
+///
+/// Result type and the type of all operands must be the sam

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-16 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122992

>From 3f3b8c75c14bb9b3ed611c9cddec49d0e9339705 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 13 Jan 2025 21:23:31 +
Subject: [PATCH 1/4] Implement `reflect` HLSL function

---
 clang/include/clang/Basic/BuiltinsSPIRV.td|   6 +
 clang/lib/CodeGen/CGBuiltin.cpp   |  13 ++
 clang/lib/Headers/hlsl/hlsl_detail.h  |  17 ++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  |  43 
 clang/lib/Sema/SemaSPIRV.cpp  |  32 +++
 clang/test/CodeGenHLSL/builtins/reflect.hlsl  | 195 ++
 clang/test/CodeGenSPIRV/Builtins/reflect.c|  32 +++
 .../SemaHLSL/BuiltIns/reflect-errors.hlsl |  33 +++
 .../test/SemaSPIRV/BuiltIns/reflect-errors.c  |  23 +++
 llvm/include/llvm/IR/IntrinsicsSPIRV.td   |   1 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |   2 +
 .../CodeGen/SPIRV/hlsl-intrinsics/reflect.ll  |  33 +++
 12 files changed, 430 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/reflect.hlsl
 create mode 100644 clang/test/CodeGenSPIRV/Builtins/reflect.c
 create mode 100644 clang/test/SemaHLSL/BuiltIns/reflect-errors.hlsl
 create mode 100644 clang/test/SemaSPIRV/BuiltIns/reflect-errors.c
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll

diff --git a/clang/include/clang/Basic/BuiltinsSPIRV.td 
b/clang/include/clang/Basic/BuiltinsSPIRV.td
index 1e66939b822ef8..ce00459fc8ede7 100644
--- a/clang/include/clang/Basic/BuiltinsSPIRV.td
+++ b/clang/include/clang/Basic/BuiltinsSPIRV.td
@@ -13,3 +13,9 @@ def SPIRVDistance : Builtin {
   let Attributes = [NoThrow, Const];
   let Prototype = "void(...)";
 }
+
+def SPIRVReflect : Builtin {
+  let Spellings = ["__builtin_spirv_reflect"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b25d365932c30..b9e680685b05e0 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20487,6 +20487,19 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned 
BuiltinID,
 /*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
 ArrayRef{X, Y}, nullptr, "spv.distance");
   }
+  case SPIRV::BI__builtin_spirv_reflect: {
+Value *I = EmitScalarExpr(E->getArg(0));
+Value *N = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
+   E->getArg(1)->getType()->hasFloatingRepresentation() &&
+   "Reflect operands must have a float representation");
+assert(E->getArg(0)->getType()->isVectorType() &&
+   E->getArg(1)->getType()->isVectorType() &&
+   "Reflect operands must be a vector");
+return Builder.CreateIntrinsic(
+/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
+ArrayRef{I, N}, nullptr, "spv.reflect");
+  }
   }
   return nullptr;
 }
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 19d83ea5471c7c..624a7b05b56ad0 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -68,6 +68,23 @@ distance_vec_impl(vector X, vector Y) {
   return length_vec_impl(X - Y);
 #endif
 }
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_impl(T I, T N) {
+  return I - 2 * N * I * N;
+}
+
+template 
+constexpr enable_if_t::value || is_same::value, T>
+reflect_vec_impl(vector I, vector N) {
+#if (__has_builtin(__builtin_spirv_reflect))
+  return __builtin_spirv_reflect(I, N);
+#else
+  return I - 2 * N * __builtin_hlsl_dot(I, N);
+#endif
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d2d3abd92ea6a8..484ae708342a59 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1919,6 +1919,49 @@ double3 rcp(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp)
 double4 rcp(double4);
 
+//===--===//
+// reflect builtin
+//===--===//
+
+/// \fn T reflect(T I, T N)
+/// \brief Returns a reflection using an incident ray, \a I, and a surface
+/// normal, \a N.
+/// \param I The incident ray.
+/// \param N The surface normal.
+///
+/// The return value is a floating-point vector that represents the reflection
+/// of the incident ray, \a I, off a surface with the normal \a N.
+///
+/// This function calculates the reflection vector using the following formula:
+/// V = I - 2 * N * dot(I N) .
+///
+/// N must already be normalized in order to achieve the desired result.
+///
+/// The operands must all be a scalar or vector whose component type is
+/// floating-point.
+///
+/// Result type and the type of all operands must be the sam

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-16 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-08 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron created 
https://github.com/llvm/llvm-project/pull/122202

Fixes #99092.

1. Defines the function `D3DCOLORtoUBYTE4` in 
`clang/lib/Headers/hlsl/hlsl_intrinsics.h`.
2. Implements the function `D3DCOLORtoUBYTE4` as `d3d_color_to_ubyte4` in 
`clang/lib/Headers/hlsl/hlsl_detail.h`
3. Adds a HLSL codegen test to 
`clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl`
4. Adds error tests to 
`clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl`

>From 0ef5e0217c04aa16c2f54b5f0edf0a6dc4cdc28d Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH] Implement D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h|  8 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h| 17 +
 .../CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl  | 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl   | 13 +
 4 files changed, 50 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..6e48800dae6698
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4 ( float4 p1 ) {
+  // CHECK: %[[SCALED:.*]] = fmul <4 x float> %{{.*}}, splat (float 
0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4 ( p1 );
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..fb41c212bd0be3
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires sing

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-09 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-09 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From 0ef5e0217c04aa16c2f54b5f0edf0a6dc4cdc28d Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH 1/4] Implement D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h|  8 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h| 17 +
 .../CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl  | 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl   | 13 +
 4 files changed, 50 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..6e48800dae6698
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4 ( float4 p1 ) {
+  // CHECK: %[[SCALED:.*]] = fmul <4 x float> %{{.*}}, splat (float 
0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4 ( p1 );
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..fb41c212bd0be3
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}

>From cb89098fd6223a61b4e08ece8b50456c1ea3fcd7 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 17:30:45 +
Subject: [PATCH 2/4] Add additional sema tests for D3DCOLORtoUBYTE4 for
 invalid arg types

---
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl| 16 
 1 file changed, 16 insertions(+)

diff --

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-10 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From 5610b225e76b046e911c1a7a0c1e4ccc128d35a1 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH 1/2] [HLSL] Implement the D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h  |  8 +
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 17 +++
 .../builtins/D3DCOLORtoUBYTE4.hlsl| 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl | 29 +++
 4 files changed, 66 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8d5fd941331531..470fa4214a12f8 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 } // namespace __detail
 } // namespace hlsl
 #endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index b745997f1d5a2b..e44403c6c802e0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1857,6 +1857,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..7021de7192b5e5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4(float4 p1) {
+  // CHECK: %[[SCALED:.*]] = fmul [[FMFLAGS:.*]]<4 x float> %{{.*}}, splat 
(float 0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4(p1);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..e9ba851007c941
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}
+
+int4 float2_arg(float2 v) {
+return D3DCOLORtoUBYTE4(v);
+// expected-error@-1 {{no matching function for call to 
'D3DCOLORtoUBYTE4'}}
+// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
no known conversion from 'vector<[...], 2>' to 'vector<[...], 4>' for 1st 
argument}}
+}
+
+struct S {
+ 

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-09 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/122202

>From f76d5038811c72d1e185cdceeb24d5014c5c8281 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 01:14:52 +
Subject: [PATCH 1/5] Implement D3DCOLORtoUBYTE4 intrinsic

---
 clang/lib/Headers/hlsl/hlsl_detail.h|  8 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h| 17 +
 .../CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl  | 12 
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl   | 13 +
 4 files changed, 50 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 392075d276b188..3d78f01b6be464 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -41,6 +41,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;
+}
+
 template 
 constexpr enable_if_t::value || is_same::value, T>
 length_impl(T X) {
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index cf287e598f76ba..1ec1038190ca53 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -1846,6 +1846,23 @@ half3 cross(half3, half3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_cross)
 float3 cross(float3, float3);
 
+//===--===//
+// D3DCOLORtoUBYTE4 builtins
+//===--===//
+
+/// \fn T D3DCOLORtoUBYTE4(T x)
+/// \brief Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
+/// \param x [in] The floating-point vector4 to convert.
+///
+/// The return value is the UBYTE4 representation of the \a x parameter.
+///
+/// This function swizzles and scales components of the \a x parameter. Use 
this
+/// function to compensate for the lack of UBYTE4 support in some hardware.
+
+constexpr vector D3DCOLORtoUBYTE4(vector V) {
+  return __detail::d3d_color_to_ubyte4(V);
+}
+
 
//===--===//
 // rcp builtins
 
//===--===//
diff --git a/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl 
b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
new file mode 100644
index 00..6e48800dae6698
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/D3DCOLORtoUBYTE4.hlsl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK
+
+// CHECK-LABEL: D3DCOLORtoUBYTE4
+int4 test_D3DCOLORtoUBYTE4 ( float4 p1 ) {
+  // CHECK: %[[SCALED:.*]] = fmul <4 x float> %{{.*}}, splat (float 
0x406FE010)
+  // CHECK: %[[CONVERTED:.*]] = fptoui <4 x float> %[[SCALED]] to <4 x i32>
+  // CHECK: %[[SHUFFLED:.*]] = shufflevector <4 x i32> %{{.*}}, <4 x i32> 
poison, <4 x i32> 
+  // CHECK: ret <4 x i32> %[[SHUFFLED]]
+  return D3DCOLORtoUBYTE4 ( p1 );
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
new file mode 100644
index 00..fb41c212bd0be3
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+int4 test_too_few_arg() {
+  return D3DCOLORtoUBYTE4();
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but no arguments were provided}}
+}
+
+int4 test_too_many_arg(float4 v) {
+  return D3DCOLORtoUBYTE4(v, v);
+  // expected-error@-1 {{no matching function for call to 'D3DCOLORtoUBYTE4'}}
+  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires single argument 'V', but 2 arguments were provided}}
+}

>From 49e5ddf3942da0d8634da22e35f66f0b675f0744 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Thu, 9 Jan 2025 17:30:45 +
Subject: [PATCH 2/5] Add additional sema tests for D3DCOLORtoUBYTE4 for
 invalid arg types

---
 .../BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl| 16 
 1 file changed, 16 insertions(+)

di

[clang] [HLSL] Implement D3DCOLORtoUBYTE4 intrinsic (PR #122202)

2025-01-09 Thread Deric Cheung via cfe-commits


@@ -33,6 +33,14 @@ constexpr enable_if_t bit_cast(T 
F) {
   return __builtin_bit_cast(U, F);
 }
 
+constexpr vector d3d_color_to_ubyte4(vector V) {
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  // 
https://stackoverflow.com/questions/52103720/why-does-d3dcolortoubyte4-multiplies-components-by-255-001953f
+  return V.zyxw * 255.001953f;

Icohedron wrote:

This implementation of `D3DCOLORtoUBYTE4` scales the vector by `255.001953`. 
This matches the way it was done in 
[DXC](https://github.com/microsoft/DirectXShaderCompiler/blob/070d0d5a2beacef9eeb51037a9b04665716fd6f3/lib/HLSL/HLOperationLower.cpp#L666C1-L697C2).
However, it differs from the [SPIRV custom 
implementation](https://github.com/microsoft/DirectXShaderCompiler/blob/070d0d5a2beacef9eeb51037a9b04665716fd6f3/tools/clang/lib/SPIRV/SpirvEmitter.cpp#L11647C1-L11663C2)
 which scales the vector by `255.002`.


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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-15 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,195 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK
+
+// CHECK-LABEL: define noundef nofpclass(nan inf) half 
@_Z17test_reflect_halfDhDh(
+// CHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef 
nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[I]], 0xH4000
+// CHECK-NEXT:[[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[N]], [[N]]
+// CHECK-NEXT:[[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP0]], [[MUL_I]]
+// CHECK-NEXT:[[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 
[[I]], [[MUL2_I]]
+// CHECK-NEXT:ret half [[SUB_I]]
+//
+// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half 
@_Z17test_reflect_halfDhDh(
+// SPVCHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef 
nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// SPVCHECK-NEXT:  [[ENTRY:.*:]]
+// SPVCHECK-NEXT:[[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[I]], 0xH4000
+// SPVCHECK-NEXT:[[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[N]], [[N]]
+// SPVCHECK-NEXT:[[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP0]], [[MUL_I]]
+// SPVCHECK-NEXT:[[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 
[[I]], [[MUL2_I]]
+// SPVCHECK-NEXT:ret half [[SUB_I]]
+//
+half test_reflect_half(half I, half N) {
+return reflect(I, N);
+}
+
+// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x half> 
@_Z18test_reflect_half2Dv2_DhS_(
+// CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[I:%.*]], <2 x half> 
noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp 
afn half @llvm.dx.fdot.v2f16(<2 x half> [[I]], <2 x half> [[N]])
+// CHECK-NEXT:[[TMP0:%.*]] = extractelement <2 x half> [[I]], i64 0
+// CHECK-NEXT:[[TMP1:%.*]] = extractelement <2 x half> [[N]], i64 0
+// CHECK-NEXT:[[TMP2:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP1]], 0xH4000

Icohedron wrote:

Yea that's another issue I spotted and am troubleshooting right now

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-15 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,33 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s

Icohedron wrote:

Changing the triple to `-mtriple=spirv32-unknown-unknown` does indeed cause the 
test to fail at instruction selection

```

FAIL: LLVM :: CodeGen/SPIRV/hlsl-intrinsics/reflect.ll (282 of 582)
 TEST 'LLVM :: CodeGen/SPIRV/hlsl-intrinsics/reflect.ll' 
FAILED 
Exit Code: 2

Command Output (stderr):
--
RUN: at line 1: /workspace/feature-reflect/build/bin/llc -O0 
-mtriple=spirv32-unknown-unknown 
/workspace/feature-reflect/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll 
-o - | /workspace/feature-reflect/build/bin/FileCheck 
/workspace/feature-reflect/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
+ /workspace/feature-reflect/build/bin/FileCheck 
/workspace/feature-reflect/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll
+ /workspace/feature-reflect/build/bin/llc -O0 -mtriple=spirv32-unknown-unknown 
/workspace/feature-reflect/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll 
-o -
LLVM ERROR: cannot select: %6:id(<2 x s64>) = G_INTRINSIC 
intrinsic(@llvm.spv.reflect), %0:vfid(<2 x s64>), %1:vfid(<2 x s64>) (in 
function: reflect_half4)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and 
include the crash backtrace.
Stack dump:
0.  Program arguments: /workspace/feature-reflect/build/bin/llc -O0 
-mtriple=spirv32-unknown-unknown 
/workspace/feature-reflect/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll 
-o -
1.  Running pass 'Function Pass Manager' on module 
'/workspace/feature-reflect/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll'.
2.  Running pass 'InstructionSelect' on function '@reflect_half4'
 #0 0x5a7a8f13318f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
/workspace/feature-reflect/llvm/lib/Support/Unix/Signals.inc:804:3
 #1 0x5a7a8f130a5f llvm::sys::RunSignalHandlers() 
/workspace/feature-reflect/llvm/lib/Support/Signals.cpp:105:20
 #2 0x5a7a8f130db6 SignalHandler(int) 
/workspace/feature-reflect/llvm/lib/Support/Unix/Signals.inc:417:1
 #3 0x71ee82242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x71ee822969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #5 0x71ee82242476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #6 0x71ee822287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #7 0x5a7a8f08b463 (/workspace/feature-reflect/build/bin/llc+0x3631463)
 #8 0x5a7a8f664b32 reportGISelDiagnostic(llvm::DiagnosticSeverity, 
llvm::MachineFunction&, llvm::TargetPassConfig const&, 
llvm::MachineOptimizationRemarkEmitter&, 
llvm::MachineOptimizationRemarkMissed&) 
/workspace/feature-reflect/llvm/lib/CodeGen/GlobalISel/Utils.cpp:248:23
 #9 0x5a7a8f666a55 
llvm::DiagnosticInfoOptimizationBase::~DiagnosticInfoOptimizationBase() 
/workspace/feature-reflect/llvm/include/llvm/IR/DiagnosticInfo.h:486:7
#10 0x5a7a8f666a55 
llvm::DiagnosticInfoMIROptimization::~DiagnosticInfoMIROptimization() 
/workspace/feature-reflect/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h:31:7
#11 0x5a7a8f666a55 
llvm::MachineOptimizationRemarkMissed::~MachineOptimizationRemarkMissed() 
/workspace/feature-reflect/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h:85:7
#12 0x5a7a8f666a55 llvm::reportGISelFailure(llvm::MachineFunction&, 
llvm::TargetPassConfig const&, llvm::MachineOptimizationRemarkEmitter&, char 
const*, llvm::StringRef, llvm::MachineInstr const&) 
/workspace/feature-reflect/llvm/lib/CodeGen/GlobalISel/Utils.cpp:277:1
#13 0x5a7a8f5ce077 
llvm::SmallVectorTemplateCommon, void>::begin() 
/workspace/feature-reflect/llvm/include/llvm/ADT/SmallVector.h:267:45
#14 0x5a7a8f5ce077 
llvm::SmallVectorTemplateCommon, void>::end() 
/workspace/feature-reflect/llvm/include/llvm/ADT/SmallVector.h:269:32
#15 0x5a7a8f5ce077 llvm::SmallVector, 8u>::~SmallVector() 
/workspace/feature-reflect/llvm/include/llvm/ADT/SmallVector.h:1202:24
#16 0x5a7a8f5ce077 llvm::po_iterator, false, 
llvm::GraphTraits>::~po_iterator() 
/workspace/feature-reflect/llvm/include/llvm/ADT/PostOrderIterator.h:97:7
#17 0x5a7a8f5ce077 
llvm::InstructionSelect::selectMachineFunction(llvm::MachineFunction&) 
/workspace/feature-reflect/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp:225:5
#18 0x5a7a8f5cf70c operator() 
/workspace/feature-reflect/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp:145:59
#19 0x5a7a8f5cf70c ~scope_exit 
/workspace/feature-reflect/llvm/include/llvm/ADT/ScopeExit.h:46:19
#20 0x5a7a8f5cf70c 
llvm::InstructionSelect::runOnMachineFunction(llvm::MachineFunction&) 
/workspace/feature-reflect/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp:157:1
#21 0x5a7a8f5cf70c 
llvm::InstructionSelect::runOnMachineFunction(llvm::MachineFunction&) 
/workspace/feature-reflect/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp:134:6
#22 0x5a7a8dfbf72a 
llvm::MachineFunction

[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-15 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-15 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,195 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK
+
+// CHECK-LABEL: define noundef nofpclass(nan inf) half 
@_Z17test_reflect_halfDhDh(
+// CHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef 
nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[I]], 0xH4000
+// CHECK-NEXT:[[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[N]], [[N]]
+// CHECK-NEXT:[[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP0]], [[MUL_I]]
+// CHECK-NEXT:[[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 
[[I]], [[MUL2_I]]
+// CHECK-NEXT:ret half [[SUB_I]]
+//
+// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half 
@_Z17test_reflect_halfDhDh(
+// SPVCHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef 
nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// SPVCHECK-NEXT:  [[ENTRY:.*:]]
+// SPVCHECK-NEXT:[[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[I]], 0xH4000
+// SPVCHECK-NEXT:[[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[N]], [[N]]
+// SPVCHECK-NEXT:[[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP0]], [[MUL_I]]
+// SPVCHECK-NEXT:[[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 
[[I]], [[MUL2_I]]
+// SPVCHECK-NEXT:ret half [[SUB_I]]
+//
+half test_reflect_half(half I, half N) {
+return reflect(I, N);
+}
+
+// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x half> 
@_Z18test_reflect_half2Dv2_DhS_(
+// CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[I:%.*]], <2 x half> 
noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp 
afn half @llvm.dx.fdot.v2f16(<2 x half> [[I]], <2 x half> [[N]])
+// CHECK-NEXT:[[TMP0:%.*]] = extractelement <2 x half> [[I]], i64 0
+// CHECK-NEXT:[[TMP1:%.*]] = extractelement <2 x half> [[N]], i64 0
+// CHECK-NEXT:[[TMP2:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP1]], 0xH4000
+// CHECK-NEXT:[[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP2]], [[HLSL_DOT_I]]
+// CHECK-NEXT:[[CAST_VTRUNC_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn 
half [[TMP0]], [[TMP3]]
+// CHECK-NEXT:[[SPLAT_SPLATINSERT:%.*]] = insertelement <2 x half> poison, 
half [[CAST_VTRUNC_I]], i64 0
+// CHECK-NEXT:[[SPLAT_SPLAT:%.*]] = shufflevector <2 x half> 
[[SPLAT_SPLATINSERT]], <2 x half> poison, <2 x i32> zeroinitializer
+// CHECK-NEXT:ret <2 x half> [[SPLAT_SPLAT]]
+//
+// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <2 x half> 
@_Z18test_reflect_half2Dv2_DhS_(
+// SPVCHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[I:%.*]], <2 x half> 
noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// SPVCHECK-NEXT:  [[ENTRY:.*:]]
+// SPVCHECK-NEXT:[[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz 
arcp afn <2 x half> @llvm.spv.reflect.v2f16(<2 x half> [[I]], <2 x half> [[N]])
+// SPVCHECK-NEXT:[[SPLAT_SPLAT:%.*]] = shufflevector <2 x half> 
[[SPV_REFLECT_I]], <2 x half> poison, <2 x i32> zeroinitializer

Icohedron wrote:

I am unsure where the vector splat is coming from.

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-15 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,195 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -fnative-half-type \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK
+
+// CHECK-LABEL: define noundef nofpclass(nan inf) half 
@_Z17test_reflect_halfDhDh(
+// CHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef 
nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[I]], 0xH4000
+// CHECK-NEXT:[[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[N]], [[N]]
+// CHECK-NEXT:[[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP0]], [[MUL_I]]
+// CHECK-NEXT:[[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 
[[I]], [[MUL2_I]]
+// CHECK-NEXT:ret half [[SUB_I]]
+//
+// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half 
@_Z17test_reflect_halfDhDh(
+// SPVCHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef 
nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// SPVCHECK-NEXT:  [[ENTRY:.*:]]
+// SPVCHECK-NEXT:[[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[I]], 0xH4000
+// SPVCHECK-NEXT:[[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[N]], [[N]]
+// SPVCHECK-NEXT:[[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP0]], [[MUL_I]]
+// SPVCHECK-NEXT:[[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 
[[I]], [[MUL2_I]]
+// SPVCHECK-NEXT:ret half [[SUB_I]]
+//
+half test_reflect_half(half I, half N) {
+return reflect(I, N);
+}
+
+// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x half> 
@_Z18test_reflect_half2Dv2_DhS_(
+// CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[I:%.*]], <2 x half> 
noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp 
afn half @llvm.dx.fdot.v2f16(<2 x half> [[I]], <2 x half> [[N]])
+// CHECK-NEXT:[[TMP0:%.*]] = extractelement <2 x half> [[I]], i64 0
+// CHECK-NEXT:[[TMP1:%.*]] = extractelement <2 x half> [[N]], i64 0
+// CHECK-NEXT:[[TMP2:%.*]] = fmul reassoc nnan ninf nsz arcp afn half 
[[TMP1]], 0xH4000

Icohedron wrote:

It seems like all the math operations except for the dot product are being 
performed on only the first elements of each input vector.

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


[clang] [llvm] [HLSL] Implement the `reflect` HLSL function (PR #122992)

2025-01-16 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/127137

>From 4fae5642c6e8e305cdc687b4968ba5eabaa44b50 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/4] Add the AddUint64 HLSL builtin function

- Defines the AddUint64 HLSL builtin function
- Implements the UAddc DXIL op to lower AddUint64 to DXIL
---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 47 
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 41 +++
 llvm/lib/Target/DirectX/DXIL.td   | 13 
 llvm/lib/Target/DirectX/DXILOpBuilder.cpp | 14 
 llvm/lib/Target/DirectX/DXILOpBuilder.h   |  3 +
 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 22 --
 llvm/test/CodeGen/DirectX/UAddc.ll| 40 +++
 llvm/test/CodeGen/DirectX/UAddc_errors.ll | 30 
 13 files changed, 348 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/UAddc.ll
 create mode 100644 llvm/test/CodeGen/DirectX/UAddc_errors.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 29939242596ba..2433427a89429 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2fce5e88ba8a0..e78339ee924ff 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10655,6 +10655,8 @@ def err_second_argument_to_cwsc_not_pointer : Error<
 
 def err_vector_incorrect_num_elements : Error<
   "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+def err_invalid_even_odd_vector_element_count : Error<
+  "invalid element count of %0 in vector %select{initialization|operand}4 
(expected an %select{even|odd}3 element count in the range of %1 and %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..5322b38458b26 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19445,6 +19445,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry

[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/127098

>From 5b093ca42fdc24f89bfccac25e6f2e17155432f6 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Wed, 12 Feb 2025 21:24:00 +
Subject: [PATCH 1/4] Implement the 'and' HLSL function

---
 clang/include/clang/Basic/Builtins.td|  6 +++
 clang/lib/CodeGen/CGBuiltin.cpp  |  5 +++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 16 +++
 clang/lib/Sema/SemaHLSL.cpp  | 11 +
 clang/test/CodeGenHLSL/builtins/and.hlsl | 45 
 clang/test/SemaHLSL/BuiltIns/and-errors.hlsl | 27 
 6 files changed, 110 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/and.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/and-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 29939242596ba..de758d88f8f92 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4765,6 +4765,12 @@ def HLSLAll : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "bool(...)";
 }
 
+def HLSLAnd : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_and"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLAny : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_any"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..82527cb5e1f7a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19463,6 +19463,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 CGM.getHLSLRuntime().getAllIntrinsic(), ArrayRef{Op0}, 
nullptr,
 "hlsl.all");
   }
+  case Builtin::BI__builtin_hlsl_and: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+return Builder.CreateAnd(Op0, Op1, "hlsl.and");
+  }
   case Builtin::BI__builtin_hlsl_any: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 return Builder.CreateIntrinsic(
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d1f5fdff8b600..7016b45d1c641 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -249,6 +249,22 @@ bool all(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_all)
 bool all(double4);
 
+//===--===//
+// and builtins
+//===--===//
+
+// \fn bool and(bool x, bool y)
+// \brief Logically ands two boolean vectors elementwise and produces a bool 
vector output.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool and(bool x, bool y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool2 and(bool2 x, bool2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool3 and(bool3 x, bool3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool4 and(bool4 x, bool4 y);
+
 
//===--===//
 // any builtins
 
//===--===//
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 4abd870ad6aaa..7297fb3a9e4d0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2245,6 +2245,17 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 break;
   }
+  case Builtin::BI__builtin_hlsl_and: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+ExprResult A = TheCall->getArg(0);
+QualType ArgTyA = A.get()->getType();
+// return type is the same as the input type
+TheCall->setType(ArgTyA);
+break;
+  }
   case Builtin::BI__builtin_hlsl_all:
   case Builtin::BI__builtin_hlsl_any: {
 if (SemaRef.checkArgCount(TheCall, 1))
diff --git a/clang/test/CodeGenHLSL/builtins/and.hlsl 
b/clang/test/CodeGenHLSL/builtins/and.hlsl
new file mode 100644
index 0..60295f192f5cc
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/and.hlsl
@@ -0,0 +1,45 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s
+
+// CHECK-LABEL: define noundef i1 @_Z15test_and_scalarbb(
+// CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) local_unnamed_addr 
#[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[HLSL_AND:%.*]] = and i1 [[X]], [[Y]]
+// CHECK-NEXT:ret i1 [[HLSL_AND]]
+//
+bool test_and_scalar(bool x, bool y) {
+  return and(x, y);
+}
+
+// CHECK-LABEL: define noundef <2 x i1> @_Z14test_and_bool2Dv2_bS_(
+// CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.

[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2079,6 +2079,14 @@ static bool CheckFloatingOrIntRepresentation(Sema *S, 
CallExpr *TheCall) {
 checkAllSignedTypes);
 }
 
+static bool CheckBoolRepresentation(Sema *S, CallExpr *TheCall) {
+  auto checkAllBoolTypes = [](clang::QualType PassedType) -> bool {
+return !PassedType->hasIntegerRepresentation();

Icohedron wrote:

`clang::QualType` does not have a `hasBooleanRepresentation();` function. 
I assume `hasIntegerRepresentation()` should work just fine.

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2229,6 +2241,41 @@ static bool CheckResourceHandle(
 // returning an ExprError
 bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) 
{
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+if (CheckUnsignedIntRepresentations(&SemaRef, TheCall))
+  return true;
+
+// CheckVectorElementCallArgs(...) guarantees both args are the same type.
+assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() &&
+   "Both args must be of the same type");
+
+// ensure both args are vectors
+auto *VTy = TheCall->getArg(0)->getType()->getAs();
+if (!VTy) {
+  SemaRef.Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector)
+  << "AddUint64" << /*all*/ 1;
+  return true;
+}
+
+// ensure both args have 2 elements, or both args have 4 elements
+int NumElementsArg = VTy->getNumElements();
+if (NumElementsArg != 2 && NumElementsArg != 4) {
+  SemaRef.Diag(TheCall->getBeginLoc(),
+   diag::err_invalid_even_odd_vector_element_count)
+  << NumElementsArg << 2 << 4 << /*even*/ 0 << /*operand*/ 1;
+  return true;
+}
+

Icohedron wrote:

Nevermind. I found a way thanks to @bob80905 
```c++
// ensure arg integers are 32-bits
CharUnits CharSize = 
SemaRef.getASTContext().getTypeSizeInChars(VTy->getElementType());
if (CharSize.getQuantity() != 4) {
  SemaRef.Diag(...);
  return true;
}
```

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2245,6 +2245,17 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 break;
   }
+  case Builtin::BI__builtin_hlsl_and: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+ExprResult A = TheCall->getArg(0);

Icohedron wrote:

I think it's just difference in wording. I'm pretty sure we are talking about 
the same thing? If you pass a non-bool type into `__builtin_hlsl_and` then it 
will be implicitly converted to a bool. Hence "any type that can be implicitly 
cast to a bool (vector) are allowed to be passed" into it.

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -O1 -verify
+
+bool test_too_few_arg(bool a) {
+  return __builtin_hlsl_and(a);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
1}}
+}
+
+bool test_too_many_arg(bool a) {
+  return __builtin_hlsl_and(a, a, a);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+bool2 test_mismatched_args(bool2 a, bool3 b) {
+  return __builtin_hlsl_and(a, b);
+  // expected-error@-1 {{all arguments to '__builtin_hlsl_and' must have the 
same type}}
+}
+
+struct S {
+  bool a;
+};
+
+bool test_invalid_type_conversion(S s) {
+  return __builtin_hlsl_and(s, s);

Icohedron wrote:

Actually this is a good catch. The error message is worded strangely-- it 
implies that `__builtin_hlsl_and` is trying to return a struct of type `S` and 
is failing because `S` can't be converted to a bool.

I will fix this by adding a check to SemaHLSL that the argument type has a bool 
representation, and emitting a better error message.

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -O1 -verify
+
+bool test_too_few_arg(bool a) {
+  return __builtin_hlsl_and(a);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
1}}
+}
+
+bool test_too_many_arg(bool a) {
+  return __builtin_hlsl_and(a, a, a);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+bool2 test_mismatched_args(bool2 a, bool3 b) {
+  return __builtin_hlsl_and(a, b);
+  // expected-error@-1 {{all arguments to '__builtin_hlsl_and' must have the 
same type}}
+}
+
+struct S {
+  bool a;
+};
+
+bool test_invalid_type_conversion(S s) {
+  return __builtin_hlsl_and(s, s);

Icohedron wrote:

Though I thought there would be something to catch errors like this when the 
argument type doesn't match any of the ones declared in `hlsl_intrinsics.h`

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -O1 -verify
+
+bool test_too_few_arg(bool a) {
+  return __builtin_hlsl_and(a);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
1}}
+}
+
+bool test_too_many_arg(bool a) {
+  return __builtin_hlsl_and(a, a, a);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+}
+
+bool2 test_mismatched_args(bool2 a, bool3 b) {
+  return __builtin_hlsl_and(a, b);
+  // expected-error@-1 {{all arguments to '__builtin_hlsl_and' must have the 
same type}}
+}
+
+struct S {
+  bool a;
+};
+
+bool test_invalid_type_conversion(S s) {
+  return __builtin_hlsl_and(s, s);

Icohedron wrote:

Actually, there is something like that, but it seems `__builtin_hlsl_and` is 
triggering something else.
The `D3DCOLORtoUBYTE` function doesn't have any SemaHLSL and [yet has a similar 
test which emits a more accurate error 
message](https://github.com/llvm/llvm-project/blob/main/clang/test/SemaHLSL/BuiltIns/D3DCOLORtoUBYTE4-errors.hlsl#L28).
 Perhaps this is just because `D3DCOLORtoUBYTE` is a header-only implementation?

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2229,6 +2241,41 @@ static bool CheckResourceHandle(
 // returning an ExprError
 bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) 
{
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+if (CheckUnsignedIntRepresentations(&SemaRef, TheCall))
+  return true;
+
+// CheckVectorElementCallArgs(...) guarantees both args are the same type.
+assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() &&
+   "Both args must be of the same type");
+
+// ensure both args are vectors
+auto *VTy = TheCall->getArg(0)->getType()->getAs();
+if (!VTy) {
+  SemaRef.Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector)
+  << "AddUint64" << /*all*/ 1;
+  return true;
+}
+
+// ensure both args have 2 elements, or both args have 4 elements
+int NumElementsArg = VTy->getNumElements();
+if (NumElementsArg != 2 && NumElementsArg != 4) {
+  SemaRef.Diag(TheCall->getBeginLoc(),
+   diag::err_invalid_even_odd_vector_element_count)
+  << NumElementsArg << 2 << 4 << /*even*/ 0 << /*operand*/ 1;
+  return true;
+}
+

Icohedron wrote:

uint2: `AddUint64( A:{low, high}, B:{low, high} )` and the result is one pair 
of 32-bit integers (low, high)

uint4: `AddUint64( A:{low0, high0, low1, high1}, B:{low0, high0, low1, high1} 
)` is equivalent to
```
AddUint64( A:{low0, high0}, B{low0, high0} )
AddUint64( A:{low1, high1}, B{low1, high1} )
```
so the result would be two pairs of 32-bit integers, (low0, high0) and (low1, 
high1), stored as a uint4: (low0, high0, low1, high1)


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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/127098

>From 5b093ca42fdc24f89bfccac25e6f2e17155432f6 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Wed, 12 Feb 2025 21:24:00 +
Subject: [PATCH 1/4] Implement the 'and' HLSL function

---
 clang/include/clang/Basic/Builtins.td|  6 +++
 clang/lib/CodeGen/CGBuiltin.cpp  |  5 +++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h | 16 +++
 clang/lib/Sema/SemaHLSL.cpp  | 11 +
 clang/test/CodeGenHLSL/builtins/and.hlsl | 45 
 clang/test/SemaHLSL/BuiltIns/and-errors.hlsl | 27 
 6 files changed, 110 insertions(+)
 create mode 100644 clang/test/CodeGenHLSL/builtins/and.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/and-errors.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 29939242596ba..de758d88f8f92 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4765,6 +4765,12 @@ def HLSLAll : LangBuiltin<"HLSL_LANG"> {
   let Prototype = "bool(...)";
 }
 
+def HLSLAnd : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_and"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLAny : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_any"];
   let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..82527cb5e1f7a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19463,6 +19463,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 CGM.getHLSLRuntime().getAllIntrinsic(), ArrayRef{Op0}, 
nullptr,
 "hlsl.all");
   }
+  case Builtin::BI__builtin_hlsl_and: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+return Builder.CreateAnd(Op0, Op1, "hlsl.and");
+  }
   case Builtin::BI__builtin_hlsl_any: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 return Builder.CreateIntrinsic(
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index d1f5fdff8b600..7016b45d1c641 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -249,6 +249,22 @@ bool all(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_all)
 bool all(double4);
 
+//===--===//
+// and builtins
+//===--===//
+
+// \fn bool and(bool x, bool y)
+// \brief Logically ands two boolean vectors elementwise and produces a bool 
vector output.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool and(bool x, bool y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool2 and(bool2 x, bool2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool3 and(bool3 x, bool3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool4 and(bool4 x, bool4 y);
+
 
//===--===//
 // any builtins
 
//===--===//
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 4abd870ad6aaa..7297fb3a9e4d0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2245,6 +2245,17 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 break;
   }
+  case Builtin::BI__builtin_hlsl_and: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+ExprResult A = TheCall->getArg(0);
+QualType ArgTyA = A.get()->getType();
+// return type is the same as the input type
+TheCall->setType(ArgTyA);
+break;
+  }
   case Builtin::BI__builtin_hlsl_all:
   case Builtin::BI__builtin_hlsl_any: {
 if (SemaRef.checkArgCount(TheCall, 1))
diff --git a/clang/test/CodeGenHLSL/builtins/and.hlsl 
b/clang/test/CodeGenHLSL/builtins/and.hlsl
new file mode 100644
index 0..60295f192f5cc
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/and.hlsl
@@ -0,0 +1,45 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -O1 -o - | FileCheck %s
+
+// CHECK-LABEL: define noundef i1 @_Z15test_and_scalarbb(
+// CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) local_unnamed_addr 
#[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[HLSL_AND:%.*]] = and i1 [[X]], [[Y]]
+// CHECK-NEXT:ret i1 [[HLSL_AND]]
+//
+bool test_and_scalar(bool x, bool y) {
+  return and(x, y);
+}
+
+// CHECK-LABEL: define noundef <2 x i1> @_Z14test_and_bool2Dv2_bS_(
+// CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.

[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2245,6 +2245,17 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 break;
   }
+  case Builtin::BI__builtin_hlsl_and: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+ExprResult A = TheCall->getArg(0);

Icohedron wrote:

Currently, any type that can be implicitly cast to a bool (vector) are allowed 
to be passed to the `and` HLSL builtin function. Should that be disallowed?
Or is the check you mention just something to reinforce / make more clear in 
SemaHLSL.cpp that the `and` builtin operates only with bools?

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -10655,6 +10655,8 @@ def err_second_argument_to_cwsc_not_pointer : Error<
 
 def err_vector_incorrect_num_elements : Error<
   "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+def err_invalid_even_odd_vector_element_count : Error<
+  "invalid element count of %0 in vector %select{initialization|operand}4 
(expected an %select{even|odd}3 element count in the range of %1 and %2)">;

Icohedron wrote:

"a vector whose total size is a multiple of 64-bits" could also mean 
`uint16_t4` ;)
But with a check for 32-bits in the integer arguments as a separate error 
message, it would be sufficient.

Or perhaps, do you think the AddUint64 function should be generalized to accept 
any vector of unsigned integers whose total size is a multiple of 64-bits? Like 
`uint16_t4`, or potentially `uint32_t` vectors longer than 4 in the future?

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2229,6 +2241,41 @@ static bool CheckResourceHandle(
 // returning an ExprError
 bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) 
{
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+if (CheckUnsignedIntRepresentations(&SemaRef, TheCall))
+  return true;
+
+// CheckVectorElementCallArgs(...) guarantees both args are the same type.
+assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() &&
+   "Both args must be of the same type");
+
+// ensure both args are vectors
+auto *VTy = TheCall->getArg(0)->getType()->getAs();
+if (!VTy) {
+  SemaRef.Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector)
+  << "AddUint64" << /*all*/ 1;
+  return true;
+}
+
+// ensure both args have 2 elements, or both args have 4 elements
+int NumElementsArg = VTy->getNumElements();
+if (NumElementsArg != 2 && NumElementsArg != 4) {
+  SemaRef.Diag(TheCall->getBeginLoc(),
+   diag::err_invalid_even_odd_vector_element_count)
+  << NumElementsArg << 2 << 4 << /*even*/ 0 << /*operand*/ 1;
+  return true;
+}
+

Icohedron wrote:

Indeed, a `uint16_t2` does slip by without diagnostics.

@inbelic did suggest to check that the input integers are 32-bits, but neither 
of us were able to figure out how to access integer bit count from a 
`clang::QualType`. Perhaps you would know how it could be done?

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


[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits

https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/127137

>From 4fae5642c6e8e305cdc687b4968ba5eabaa44b50 Mon Sep 17 00:00:00 2001
From: Icohedron 
Date: Mon, 27 Jan 2025 11:18:09 -0800
Subject: [PATCH 1/3] Add the AddUint64 HLSL builtin function

- Defines the AddUint64 HLSL builtin function
- Implements the UAddc DXIL op to lower AddUint64 to DXIL
---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/CodeGen/CGBuiltin.cpp   | 45 
 clang/lib/Headers/hlsl/hlsl_intrinsics.h  | 21 ++
 clang/lib/Sema/SemaHLSL.cpp   | 47 
 .../test/CodeGenHLSL/builtins/AddUint64.hlsl  | 71 +++
 .../SemaHLSL/BuiltIns/AddUint64-errors.hlsl   | 41 +++
 llvm/lib/Target/DirectX/DXIL.td   | 13 
 llvm/lib/Target/DirectX/DXILOpBuilder.cpp | 14 
 llvm/lib/Target/DirectX/DXILOpBuilder.h   |  3 +
 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 22 --
 llvm/test/CodeGen/DirectX/UAddc.ll| 40 +++
 llvm/test/CodeGen/DirectX/UAddc_errors.ll | 30 
 13 files changed, 348 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/AddUint64.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl
 create mode 100644 llvm/test/CodeGen/DirectX/UAddc.ll
 create mode 100644 llvm/test/CodeGen/DirectX/UAddc_errors.ll

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 29939242596ba..2433427a89429 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
 }
 
 // HLSL
+def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_adduint64"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "void(...)";
+}
+
 def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getpointer"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2fce5e88ba8a0..e78339ee924ff 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10655,6 +10655,8 @@ def err_second_argument_to_cwsc_not_pointer : Error<
 
 def err_vector_incorrect_num_elements : Error<
   "%select{too many|too few}0 elements in vector 
%select{initialization|operand}3 (expected %1 elements, have %2)">;
+def err_invalid_even_odd_vector_element_count : Error<
+  "invalid element count of %0 in vector %select{initialization|operand}4 
(expected an %select{even|odd}3 element count in the range of %1 and %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
 def err_invalid_neon_type_code : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..5322b38458b26 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19445,6 +19445,51 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
 return nullptr;
 
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+Value *OpA = EmitScalarExpr(E->getArg(0));
+Value *OpB = EmitScalarExpr(E->getArg(1));
+assert(E->getArg(0)->getType()->hasIntegerRepresentation() &&
+   E->getArg(1)->getType()->hasIntegerRepresentation() &&
+   "AddUint64 operands must have an integer representation");
+assert(((E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 2 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 2) ||
+(E->getArg(0)->getType()->castAs()->getNumElements() ==
+ 4 &&
+ E->getArg(1)->getType()->castAs()->getNumElements() ==
+ 4)) &&
+   "input vectors must have 2 or 4 elements each");
+
+llvm::Value *Result = PoisonValue::get(OpA->getType());
+uint64_t NumElements =
+E->getArg(0)->getType()->castAs()->getNumElements();
+for (uint64_t i = 0; i < NumElements / 2; ++i) {
+
+  // Obtain low and high words of inputs A and B
+  llvm::Value *LowA = Builder.CreateExtractElement(OpA, 2 * i + 0);
+  llvm::Value *HighA = Builder.CreateExtractElement(OpA, 2 * i + 1);
+  llvm::Value *LowB = Builder.CreateExtractElement(OpB, 2 * i + 0);
+  llvm::Value *HighB = Builder.CreateExtractElement(OpB, 2 * i + 1);
+
+  // Use an uadd_with_overflow to compute the sum of low words and obtain a
+  // carry value
+  llvm::Value *Carry;
+  llvm::Value *LowSum = EmitOverflowIntrinsic(
+  *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
+  llvm::Value *ZExtCarry = Builder.CreateZExt(Carry, HighA->getType());
+
+  // Sum the high words and the carry

[clang] [llvm] [HLSL] [DXIL] Implement the AddUint64 HLSL function and the UAddc DXIL op (PR #127137)

2025-02-14 Thread Deric Cheung via cfe-commits


@@ -2229,6 +2241,41 @@ static bool CheckResourceHandle(
 // returning an ExprError
 bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) 
{
   switch (BuiltinID) {
+  case Builtin::BI__builtin_hlsl_adduint64: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+if (CheckUnsignedIntRepresentations(&SemaRef, TheCall))
+  return true;
+
+// CheckVectorElementCallArgs(...) guarantees both args are the same type.
+assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() &&
+   "Both args must be of the same type");
+
+// ensure both args are vectors
+auto *VTy = TheCall->getArg(0)->getType()->getAs();
+if (!VTy) {
+  SemaRef.Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector)
+  << "AddUint64" << /*all*/ 1;
+  return true;
+}
+
+// ensure both args have 2 elements, or both args have 4 elements
+int NumElementsArg = VTy->getNumElements();
+if (NumElementsArg != 2 && NumElementsArg != 4) {
+  SemaRef.Diag(TheCall->getBeginLoc(),
+   diag::err_invalid_even_odd_vector_element_count)
+  << NumElementsArg << 2 << 4 << /*even*/ 0 << /*operand*/ 1;
+  return true;
+}
+

Icohedron wrote:

The 4-element vector size version of AddUint64 is the same as the 2-element 
vector size version of AddUint64 performed twice. 
AddUint64 returns a uint2 when its args are uint2, and AddUint64 returns a 
uint4 when its args are uint4.

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-14 Thread Deric Cheung via cfe-commits

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-15 Thread Deric Cheung via cfe-commits


@@ -2245,6 +2245,36 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
 
 break;
   }
+  case Builtin::BI__builtin_hlsl_and: {
+if (SemaRef.checkArgCount(TheCall, 2))
+  return true;
+if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+  return true;
+
+// CheckVectorElementCallArgs(...) guarantees both args are the same type.
+assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() &&
+   "Both args must be of the same type");
+
+// check that the arguments are bools or, if vectors,
+// vectors of bools
+QualType ArgTy = TheCall->getArg(0)->getType();
+if (const auto *VecTy = ArgTy->getAs()) {
+  ArgTy = VecTy->getElementType();
+}
+if (!getASTContext().hasSameUnqualifiedType(ArgTy,

Icohedron wrote:

I did try that. I had defined the following function:
```c++
static bool CheckBoolRepresentation(Sema *S, CallExpr *TheCall) {
  auto checkAllBoolTypes = [](clang::QualType PassedType) -> bool {
return !PassedType->isBooleanType();
  };
  return CheckAllArgTypesAreCorrect(S, TheCall, S->Context.BoolTy,
checkAllBoolTypes);
}
```
and when I tried to use it, I got a strange errors when running the test
```
 TEST 'Clang :: CodeGenHLSL/builtins/and.hlsl' FAILED 
***
*
Exit Code: 2

Command Output (stderr):
--
 TEST 'Clang :: CodeGenHLSL/builtins/and.hlsl' FAILED 
***
*
Exit Code: 2

Command Output (stderr):
--
RUN: at line 2: /workspace/feature-and/build/bin/clang -cc1 -internal-isystem 
/workspace/feature-and/build/lib/clang/21/include -nostdsysteminc 
-finclude-default-header -tripledxil-pc-shadermodel6.3-library 
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl-emit-llvm 
-O1 -o - | /workspace/feature-and/build/bin/FileCheck 
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl
+ /workspace/feature-and/build/bin/clang -cc1 -internal-isystem 
/workspace/feature-and/build/lib/clang/21/include -nostdsysteminc 
-finclude-default-header -triple dxil-pc-shadermodel6.3-library 
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl -emit-llvm -O1 
-o -
+ /workspace/feature-and/build/bin/FileCheck 
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl:23:14: error: 
passing 'bool2' (aka 'vector') to parameter of incompatible type 
'__attribute__((__vector_size__(2 * sizeof(bool bool' (vector of 2 'bool' 
values)
   23 |   return and(x, y);
  |  ^
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl:33:14: error: 
passing 'bool3' (aka 'vector') to parameter of incompatible type 
'__attribute__((__vector_size__(3 * sizeof(bool bool' (vector of 3 'bool' 
values)
   33 |   return and(x, y);
  |  ^
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl:43:14: error: 
passing 'bool4' (aka 'vector') to parameter of incompatible type 
'__attribute__((__vector_size__(4 * sizeof(bool bool' (vector of 4 'bool' 
values)
   43 |   return and(x, y);
  |  ^
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl:55:14: error: 
passing 'vector' (vector of 4 'bool' values) to parameter of 
incompatible type '__attribute__((__vector_size__(4 * sizeof(bool bool' 
(vector of 4 'bool' values)
   55 |   return and(x, y);
  |  ^
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl:67:14: error: 
passing 'vector' (vector of 4 'bool' values) to parameter of 
incompatible type '__attribute__((__vector_size__(4 * sizeof(bool bool' 
(vector of 4 'bool' values)
   67 |   return and(x, y);
  |  ^
5 errors generated.
FileCheck error: '' is empty.
FileCheck command line:  /workspace/feature-and/build/bin/FileCheck 
/workspace/feature-and/clang/test/CodeGenHLSL/builtins/and.hlsl

--
```

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


[clang] [HLSL] Implement the 'and' HLSL function (PR #127098)

2025-02-15 Thread Deric Cheung via cfe-commits

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


  1   2   >