[clang] [llvm] [HLSL][DXIL][SPIRV] Intrinsic unification PR (PR #87171)
Farzon Lotfi via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 1 19:26:57 PDT 2024
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/87171
>From 47518b4172cef216f1cc84e54b65e979b4c679c2 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Thu, 28 Mar 2024 21:05:36 -0400
Subject: [PATCH 1/2] [HLSL][DXIL][SPIRV] Intrinsic unification PR
---
clang/include/clang/Basic/Builtins.td | 6 +
clang/lib/CodeGen/CGBuiltin.cpp | 19 ++
clang/lib/Headers/hlsl/hlsl_intrinsics.h | 112 +++++++
clang/lib/Sema/SemaChecking.cpp | 1 +
clang/test/CodeGenHLSL/builtins/all.hlsl | 277 ++++++++++++++++++
llvm/include/llvm/IR/Intrinsics.td | 12 +
llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 +-
llvm/include/llvm/IR/IntrinsicsSPIRV.td | 3 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 19 ++
.../test/CodeGen/SPIRV/hlsl-intrinsics/all.ll | 95 ++++++
10 files changed, 545 insertions(+), 3 deletions(-)
create mode 100644 clang/test/CodeGenHLSL/builtins/all.hlsl
create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index f421223ff087de..d6ceb450bd106b 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4587,6 +4587,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
}
// HLSL
+def HLSLAll : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_elementwise_all"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "bool(...)";
+}
+
def HLSLAny : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_any"];
let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index bb007231c0b783..add7ec1fa0eb45 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -51,6 +51,7 @@
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsS390.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/IR/IntrinsicsVE.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
@@ -18176,12 +18177,30 @@ Intrinsic::ID getDotProductIntrinsic(QualType QT, int elementCount) {
return Intrinsic::dx_udot;
}
+Intrinsic::ID getAllIntrinsic(const llvm::Triple::ArchType Arch) {
+ switch (Arch) {
+ case llvm::Triple::dxil:
+ return Intrinsic::dx_all;
+ case llvm::Triple::spirv:
+ return Intrinsic::spv_all;
+ default:
+ llvm_unreachable("Input semantic not supported by target");
+ }
+}
+
Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
if (!getLangOpts().HLSL)
return nullptr;
switch (BuiltinID) {
+ case Builtin::BI__builtin_hlsl_elementwise_all: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ return Builder.CreateIntrinsic(
+ /*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()),
+ getAllIntrinsic(CGM.getTarget().getTriple().getArch()),
+ ArrayRef<Value *>{Op0}, nullptr, "hlsl.all");
+ }
case Builtin::BI__builtin_hlsl_elementwise_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 9fb6204f90c9a8..06409c6fc77417 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -100,6 +100,118 @@ double3 abs(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
double4 abs(double4);
+//===----------------------------------------------------------------------===//
+// all builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn bool all(T x)
+/// \brief Returns True if all components of the \a x parameter are non-zero;
+/// otherwise, false. \param x The input value.
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t2);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t3);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t4);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t2);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t3);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t4);
+#endif
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half2);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half3);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool4);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint64_t4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(double);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(double2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(double3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(double4);
+
//===----------------------------------------------------------------------===//
// any builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 11401b6f56c0ea..9c646e10406469 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5562,6 +5562,7 @@ void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall,
// returning an ExprError
bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
switch (BuiltinID) {
+ case Builtin::BI__builtin_hlsl_elementwise_all:
case Builtin::BI__builtin_hlsl_elementwise_any: {
if (checkArgCount(*this, TheCall, 1))
return true;
diff --git a/clang/test/CodeGenHLSL/builtins/all.hlsl b/clang/test/CodeGenHLSL/builtins/all.hlsl
new file mode 100644
index 00000000000000..b48daa287480ff
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/all.hlsl
@@ -0,0 +1,277 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,SPIR_NO_HALF,SPIR_CHECK
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,NATIVE_HALF,DXIL_NATIVE_HALF,DXIL_CHECK
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_NO_HALF,DXIL_CHECK
+
+#ifdef __HLSL_ENABLE_16_BIT
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_int16_t(int16_t p0) { return all(p0); }
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_int16_t2(int16_t2 p0) { return all(p0); }
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v3i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v3i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_int16_t3(int16_t3 p0) { return all(p0); }
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v4i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v4i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_int16_t4(int16_t4 p0) { return all(p0); }
+
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_uint16_t(uint16_t p0) { return all(p0); }
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_uint16_t2(uint16_t2 p0) { return all(p0); }
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v3i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v3i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_uint16_t3(uint16_t3 p0) { return all(p0); }
+// DXIL_NATIVE_HALF: define noundef i1 @
+// SPIR_NATIVE_HALF: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v4i16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v4i16
+// NATIVE_HALF: ret i1 %hlsl.all
+bool test_all_uint16_t4(uint16_t4 p0) { return all(p0); }
+#endif // __HLSL_ENABLE_16_BIT
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.f16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.f16
+// DXIL_NO_HALF: %hlsl.all = call i1 @llvm.dx.all.f32
+// SPIR_NO_HALF: %hlsl.all = call i1 @llvm.spv.all.f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_half(half p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2f16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2f16
+// DXIL_NO_HALF: %hlsl.all = call i1 @llvm.dx.all.v2f32
+// SPIR_NO_HALF: %hlsl.all = call i1 @llvm.spv.all.v2f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_half2(half2 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v3f16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v3f16
+// DXIL_NO_HALF: %hlsl.all = call i1 @llvm.dx.all.v3f32
+// SPIR_NO_HALF: %hlsl.all = call i1 @llvm.spv.all.v3f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_half3(half3 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v4f16
+// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v4f16
+// DXIL_NO_HALF: %hlsl.all = call i1 @llvm.dx.all.v4f32
+// SPIR_NO_HALF: %hlsl.all = call i1 @llvm.spv.all.v4f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_half4(half4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.f32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_float(float p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2f32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_float2(float2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3f32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_float3(float3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4f32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4f32
+// CHECK: ret i1 %hlsl.all
+bool test_all_float4(float4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.f64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.f64
+// CHECK: ret i1 %hlsl.all
+bool test_all_double(double p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2f64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2f64
+// CHECK: ret i1 %hlsl.all
+bool test_all_double2(double2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3f64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3f64
+// CHECK: ret i1 %hlsl.all
+bool test_all_double3(double3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4f64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4f64
+// CHECK: ret i1 %hlsl.all
+bool test_all_double4(double4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_int(int p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_int2(int2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_int3(int3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_int4(int4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint(uint p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint2(uint2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint3(uint3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4i32
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4i32
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint4(uint4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_int64_t(int64_t p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_int64_t2(int64_t2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_int64_t3(int64_t3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_int64_t4(int64_t4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint64_t(uint64_t p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint64_t2(uint64_t2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint64_t3(uint64_t3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4i64
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4i64
+// CHECK: ret i1 %hlsl.all
+bool test_all_uint64_t4(uint64_t4 p0) { return all(p0); }
+
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.i1
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.i1
+// CHECK: ret i1 %hlsl.all
+bool test_all_bool(bool p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v2i1
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v2i1
+// CHECK: ret i1 %hlsl.all
+bool test_all_bool2(bool2 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v3i1
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v3i1
+// CHECK: ret i1 %hlsl.all
+bool test_all_bool3(bool3 p0) { return all(p0); }
+// DXIL_CHECK: define noundef i1 @
+// SPIR_CHECK: define spir_func noundef i1 @
+// DXIL_CHECK: %hlsl.all = call i1 @llvm.dx.all.v4i1
+// SPIR_CHECK: %hlsl.all = call i1 @llvm.spv.all.v4i1
+// CHECK: ret i1 %hlsl.all
+bool test_all_bool4(bool4 p0) { return all(p0); }
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index c04f4c52692158..1163bd6c8fbaba 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -684,6 +684,18 @@ class DefaultAttrsIntrinsic<list<LLVMType> ret_types,
intr_properties, name,
sd_properties, /*disable_default_attributes*/ 0> {}
+// HLSL Intrinsic Classes
+class HLSLThreadId
+ : Intrinsic</*ret_types*/ [llvm_i32_ty],
+ /*param_types*/[llvm_i32_ty],
+ /*intr_properties*/ [IntrNoMem, IntrWillReturn],
+ /*name*/ ""> {}
+class HLSLAll : Intrinsic</*ret_types*/ [llvm_i1_ty],
+ /*param_types*/[llvm_any_ty],
+ /*intr_properties*/ [IntrNoMem, IntrWillReturn],
+ /*name*/ ""> {}
+
+
/// ClangBuiltin - If this intrinsic exactly corresponds to a Clang builtin, this
/// specifies the name of the builtin. This provides automatic CBE and CFE
/// support.
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index a871fac46b9fd5..c67102a14387f4 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -11,8 +11,7 @@
//===----------------------------------------------------------------------===//
let TargetPrefix = "dx" in {
-
-def int_dx_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
+def int_dx_thread_id : HLSLThreadId;
def int_dx_group_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
def int_dx_thread_id_in_group : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrWillReturn]>;
@@ -20,6 +19,7 @@ def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMe
def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
+def int_dx_all : HLSLAll;
def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
def int_dx_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
def int_dx_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 0eb09b1699aff4..f987d7928ab23f 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -53,7 +53,8 @@ let TargetPrefix = "spv" in {
ImmArg<ArgIndex<0>>]>;
// The following intrinsic(s) are mirrored from IntrinsicsDirectX.td for HLSL support.
- def int_spv_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
+ def int_spv_thread_id : HLSLThreadId;
+ def int_spv_all : HLSLAll;
def int_spv_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index f4525e713c987f..bf71f0c0ff3df6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -144,6 +144,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
bool selectAddrSpaceCast(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
+ bool selectAll(Register ResVReg, const SPIRVType *ResType,
+ MachineInstr &I) const;
+
bool selectBitreverse(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
@@ -1155,6 +1158,20 @@ static unsigned getBoolCmpOpcode(unsigned PredNum) {
}
}
+bool SPIRVInstructionSelector::selectAll(Register ResVReg,
+ const SPIRVType *ResType,
+ MachineInstr &I) const {
+ assert(I.getNumOperands() == 3);
+ assert(I.getOperand(2).isReg());
+
+ MachineBasicBlock &BB = *I.getParent();
+ return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpAll))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .constrainAllUses(TII, TRI, RBI);
+}
+
bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
@@ -1785,6 +1802,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
break;
case Intrinsic::spv_thread_id:
return selectSpvThreadId(ResVReg, ResType, I);
+ case Intrinsic::spv_all:
+ return selectAll(ResVReg, ResType, I);
case Intrinsic::spv_lifetime_start:
case Intrinsic::spv_lifetime_end: {
unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll
new file mode 100644
index 00000000000000..c904ac08699355
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll
@@ -0,0 +1,95 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; Note: The validator is wrong it wants the return to be a bool vector when it is bool scalar return
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; Make sure spirv operation function calls for all are generated.
+
+; CHECK: OpMemoryModel Logical GLSL450
+
+define noundef i1 @all_bool(i1 noundef %a) {
+entry:
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.i1(i1 %a)
+ ret i1 %hlsl.all
+}
+
+define noundef i1 @all_int64_t(i64 noundef %p0) {
+entry:
+ %p0.addr = alloca i64, align 8
+ store i64 %p0, ptr %p0.addr, align 8
+ %0 = load i64, ptr %p0.addr, align 8
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.i64(i64 %0)
+ ret i1 %hlsl.all
+}
+
+
+define noundef i1 @all_int(i32 noundef %p0) {
+entry:
+ %p0.addr = alloca i32, align 4
+ store i32 %p0, ptr %p0.addr, align 4
+ %0 = load i32, ptr %p0.addr, align 4
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.i32(i32 %0)
+ ret i1 %hlsl.all
+}
+
+
+define noundef i1 @all_int16_t(i16 noundef %p0) {
+entry:
+ %p0.addr = alloca i16, align 2
+ store i16 %p0, ptr %p0.addr, align 2
+ %0 = load i16, ptr %p0.addr, align 2
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.i16(i16 %0)
+ ret i1 %hlsl.all
+}
+
+define noundef i1 @all_double(double noundef %p0) {
+entry:
+ %p0.addr = alloca double, align 8
+ store double %p0, ptr %p0.addr, align 8
+ %0 = load double, ptr %p0.addr, align 8
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.f64(double %0)
+ ret i1 %hlsl.all
+}
+
+
+define noundef i1 @all_float(float noundef %p0) {
+entry:
+ %p0.addr = alloca float, align 4
+ store float %p0, ptr %p0.addr, align 4
+ %0 = load float, ptr %p0.addr, align 4
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.f32(float %0)
+ ret i1 %hlsl.all
+}
+
+
+define noundef i1 @all_half(half noundef %p0) {
+entry:
+ %p0.addr = alloca half, align 2
+ store half %p0, ptr %p0.addr, align 2
+ %0 = load half, ptr %p0.addr, align 2
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.f16(half %0)
+ ret i1 %hlsl.all
+}
+
+
+define noundef i1 @all_bool4(<4 x i1> noundef %p0) {
+entry:
+ ; CHECK: %[[#]] = OpAll %[[#]] %[[#]]
+ %hlsl.all = call i1 @llvm.spv.all.v4i1(<4 x i1> %p0)
+ ret i1 %hlsl.all
+}
+
+declare i1 @llvm.spv.all.v4i1(<4 x i1>)
+declare i1 @llvm.spv.all.i1(i1)
+declare i1 @llvm.spv.all.i16(i16)
+declare i1 @llvm.spv.all.i32(i32)
+declare i1 @llvm.spv.all.i64(i64)
+declare i1 @llvm.spv.all.f16(half)
+declare i1 @llvm.spv.all.f32(float)
+declare i1 @llvm.spv.all.f64(double)
>From 8913b11cd17a10d64b0c334dd2ef2e6e528abd98 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Mon, 1 Apr 2024 19:57:34 -0400
Subject: [PATCH 2/2] add a macro for switch statement, remove type classes
---
clang/lib/CodeGen/CGBuiltin.cpp | 16 ++-------
clang/lib/CodeGen/CGHLSLRuntime.cpp | 18 +++-------
clang/lib/CodeGen/CGHLSLUtils.h | 44 +++++++++++++++++++++++
llvm/include/llvm/IR/Intrinsics.td | 12 -------
llvm/include/llvm/IR/IntrinsicsDirectX.td | 7 ++--
llvm/include/llvm/IR/IntrinsicsSPIRV.td | 4 +--
6 files changed, 57 insertions(+), 44 deletions(-)
create mode 100644 clang/lib/CodeGen/CGHLSLUtils.h
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index add7ec1fa0eb45..eec25d59c6a7dc 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -13,6 +13,7 @@
#include "ABIInfo.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
+#include "CGHLSLUtils.h"
#include "CGObjCRuntime.h"
#include "CGOpenCLRuntime.h"
#include "CGRecordLayout.h"
@@ -51,7 +52,6 @@
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsS390.h"
-#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/IR/IntrinsicsVE.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
@@ -18177,17 +18177,6 @@ Intrinsic::ID getDotProductIntrinsic(QualType QT, int elementCount) {
return Intrinsic::dx_udot;
}
-Intrinsic::ID getAllIntrinsic(const llvm::Triple::ArchType Arch) {
- switch (Arch) {
- case llvm::Triple::dxil:
- return Intrinsic::dx_all;
- case llvm::Triple::spirv:
- return Intrinsic::spv_all;
- default:
- llvm_unreachable("Input semantic not supported by target");
- }
-}
-
Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
if (!getLangOpts().HLSL)
@@ -18198,7 +18187,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *Op0 = EmitScalarExpr(E->getArg(0));
return Builder.CreateIntrinsic(
/*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()),
- getAllIntrinsic(CGM.getTarget().getTriple().getArch()),
+ CGHLSLUtils::get_hlsl_all_intrinsic(
+ CGM.getTarget().getTriple().getArch()),
ArrayRef<Value *>{Op0}, nullptr, "hlsl.all");
}
case Builtin::BI__builtin_hlsl_elementwise_any: {
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 794d93358b0a4c..c772049dbe3acc 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -14,11 +14,10 @@
#include "CGHLSLRuntime.h"
#include "CGDebugInfo.h"
+#include "CGHLSLUtils.h"
#include "CodeGenModule.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/IR/IntrinsicsDirectX.h"
-#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/FormatVariadic.h"
@@ -343,18 +342,9 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
return B.CreateCall(FunctionCallee(DxGroupIndex));
}
if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) {
- llvm::Function *ThreadIDIntrinsic;
- switch (CGM.getTarget().getTriple().getArch()) {
- case llvm::Triple::dxil:
- ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_thread_id);
- break;
- case llvm::Triple::spirv:
- ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::spv_thread_id);
- break;
- default:
- llvm_unreachable("Input semantic not supported by target");
- break;
- }
+ llvm::Function *ThreadIDIntrinsic =
+ CGM.getIntrinsic(CGHLSLUtils::get_hlsl_thread_id_intrinsic(
+ CGM.getTarget().getTriple().getArch()));
return buildVectorInput(B, ThreadIDIntrinsic, Ty);
}
assert(false && "Unhandled parameter attribute");
diff --git a/clang/lib/CodeGen/CGHLSLUtils.h b/clang/lib/CodeGen/CGHLSLUtils.h
new file mode 100644
index 00000000000000..ca29835105aa87
--- /dev/null
+++ b/clang/lib/CodeGen/CGHLSLUtils.h
@@ -0,0 +1,44 @@
+
+//===----- CGHLSLUtils.h - Utility functions for HLSL CodeGen ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This File Provides utility function for HLSL code generation.
+// It is used to abstract away implementation details of backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLUTILS_H
+#define LLVM_CLANG_LIB_CODEGEN_CGHLSLUTILS_H
+
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+
+// Define the function generator macro
+#define GENERATE_HLSL_INTRINSIC_FUNCTION(name) \
+ static llvm::Intrinsic::ID get_hlsl_##name##_intrinsic( \
+ const llvm::Triple::ArchType Arch) { \
+ switch (Arch) { \
+ case llvm::Triple::dxil: \
+ return llvm::Intrinsic::dx_##name; \
+ case llvm::Triple::spirv: \
+ return llvm::Intrinsic::spv_##name; \
+ default: \
+ llvm_unreachable("Input semantic not supported by target"); \
+ } \
+ }
+
+class CGHLSLUtils {
+public:
+ GENERATE_HLSL_INTRINSIC_FUNCTION(all)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(thread_id)
+private:
+ CGHLSLUtils() = delete;
+};
+
+#endif
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 1163bd6c8fbaba..c04f4c52692158 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -684,18 +684,6 @@ class DefaultAttrsIntrinsic<list<LLVMType> ret_types,
intr_properties, name,
sd_properties, /*disable_default_attributes*/ 0> {}
-// HLSL Intrinsic Classes
-class HLSLThreadId
- : Intrinsic</*ret_types*/ [llvm_i32_ty],
- /*param_types*/[llvm_i32_ty],
- /*intr_properties*/ [IntrNoMem, IntrWillReturn],
- /*name*/ ""> {}
-class HLSLAll : Intrinsic</*ret_types*/ [llvm_i1_ty],
- /*param_types*/[llvm_any_ty],
- /*intr_properties*/ [IntrNoMem, IntrWillReturn],
- /*name*/ ""> {}
-
-
/// ClangBuiltin - If this intrinsic exactly corresponds to a Clang builtin, this
/// specifies the name of the builtin. This provides automatic CBE and CFE
/// support.
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index c67102a14387f4..a7f212da2f5b63 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -11,7 +11,8 @@
//===----------------------------------------------------------------------===//
let TargetPrefix = "dx" in {
-def int_dx_thread_id : HLSLThreadId;
+
+def int_dx_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
def int_dx_group_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
def int_dx_thread_id_in_group : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrWillReturn]>;
@@ -19,8 +20,8 @@ def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMe
def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
-def int_dx_all : HLSLAll;
-def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
+def int_dx_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
+def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
def int_dx_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
def int_dx_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index f987d7928ab23f..f843383f0b00ed 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -53,8 +53,8 @@ let TargetPrefix = "spv" in {
ImmArg<ArgIndex<0>>]>;
// The following intrinsic(s) are mirrored from IntrinsicsDirectX.td for HLSL support.
- def int_spv_thread_id : HLSLThreadId;
- def int_spv_all : HLSLAll;
+ def int_spv_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>;
def int_spv_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
+ def int_spv_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
}
More information about the cfe-commits
mailing list