-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends #87171
Conversation
d051ac5
to
8913b11
Compare
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-hlsl Author: Farzon Lotfi (farzonl) ChangesStart of #83882
Decided to implement a new intrinsic instead of edit an existing one to formalize the design without editing a bunch of test cases. Patch is 29.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87171.diff 11 Files Affected:
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..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"
@@ -18182,6 +18183,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
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()),
+ CGHLSLUtils::get_hlsl_all_intrinsic(
+ 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/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/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 no...
[truncated]
|
@llvm/pr-subscribers-clang Author: Farzon Lotfi (farzonl) ChangesStart of #83882
Decided to implement a new intrinsic instead of edit an existing one to formalize the design without editing a bunch of test cases. Patch is 29.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87171.diff 11 Files Affected:
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..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"
@@ -18182,6 +18183,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
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()),
+ CGHLSLUtils::get_hlsl_all_intrinsic(
+ 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/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/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 no...
[truncated]
|
8913b11
to
e59edde
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
dc24777
to
f50c949
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
abeacf6
to
bcdffdf
Compare
…c CodeGenModule is incomplete in the header\CGHLSLRuntime.h
and make GENERATE_HLSL_INTRINSIC_FUNCTION take a function name
e6e59f4
to
5b15811
Compare
…ype isn't defined yet.
5b15811
to
998f8ca
Compare
1bd7855
to
4d0ebe8
Compare
The |
So lets look at an example to see why we want an intrinsic: bool foo(float4 a) {
return all(a);
} In DXIL you would be correct it is just a few IR Operations. %5 = fcmp fast une float %1, 0.000000e+00
%6 = fcmp fast une float %2, 0.000000e+00
%7 = fcmp fast une float %3, 0.000000e+00
%8 = fcmp fast une float %4, 0.000000e+00
%9 = and i1 %5, %6
%10 = and i1 %9, %7
%11 = and i1 %10, %8
%12 = zext i1 %11 to i32 But In SPIRV hlsl's all intrinsic maps to an All opcode %10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%19 = OpFOrdNotEqual %v4bool %18 %10
%20 = OpAll %bool %19
%21 = OpSelect %uint %20 %uint_1 %uint_0 |
Start of #83882
Builtins.td
- add thehlsl
all
elementwise builtin.CGBuiltin.cpp
- Show a use case for CGHLSLUtils via anall
intrinsic codegen.CGHLSLRuntime.cpp
- movethread_id
to use CGHLSLUtils.CGHLSLRuntime.h
- Create a macro to help pick the right intrinsic for the backend.hlsl_intrinsics.h
- Add theall
api.SemaChecking.cpp
- Addall
builtin type checkingIntrinsicsDirectX.td
- Add theall
dx
intrinsicIntrinsicsSPIRV.td
- Add theall
spv
intrinsicWork still needed:
SPIRVInstructionSelector.cpp
- Add an implementation ofOpAll
forspv_all
intrinsic