https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/87034
**** DO NOT MERGE **** This is part of a proposal for how to unify spir-v and DirectX intrinsics. The issue tracking this work is: #83882 >From 8f7fb8ece073c251f78a2133b42d8baccb89c7f3 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <farzonlo...@microsoft.com> Date: Thu, 28 Mar 2024 21:05:36 -0400 Subject: [PATCH] [HLSL][DXIL][SPIRV] Intrinsic unification PR --- clang/include/clang/Basic/Builtins.td | 6 + clang/lib/CodeGen/CGBuiltin.cpp | 7 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 5 +- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 112 +++++++++ clang/lib/Sema/SemaChecking.cpp | 1 + clang/test/CodeGenHLSL/builtins/all.hlsl | 233 ++++++++++++++++++ .../semantics/DispatchThreadID.hlsl | 13 +- llvm/include/llvm/IR/CMakeLists.txt | 1 + llvm/include/llvm/IR/Intrinsics.td | 1 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 - llvm/include/llvm/IR/IntrinsicsHLSL.td | 17 ++ llvm/include/llvm/IR/IntrinsicsSPIRV.td | 1 - llvm/lib/IR/Function.cpp | 1 + llvm/lib/Target/DirectX/DXIL.td | 2 +- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 1 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 36 ++- llvm/test/CodeGen/DirectX/comput_ids.ll | 4 +- .../hlsl-intrinsics/SV_DispatchThreadID.ll | 8 +- .../test/CodeGen/SPIRV/hlsl-intrinsics/all.ll | 95 +++++++ .../secondary/llvm/include/llvm/IR/BUILD.gn | 5 + 20 files changed, 522 insertions(+), 28 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/all.hlsl create mode 100644 llvm/include/llvm/IR/IntrinsicsHLSL.td 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 287e763bad82dd..0a6d6b91c51e6f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -45,6 +45,7 @@ #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" #include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/IntrinsicsHLSL.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -18192,6 +18193,12 @@ 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()), + Intrinsic::hlsl_all, 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..da5424e77fcdf0 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -18,6 +18,7 @@ #include "clang/AST/Decl.h" #include "clang/Basic/TargetOptions.h" #include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/IntrinsicsHLSL.h" #include "llvm/IR/IntrinsicsSPIRV.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -346,10 +347,8 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B, 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); + ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::hlsl_thread_id); break; default: llvm_unreachable("Input semantic not supported by target"); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index a34e72402c0e64..762823de523aaa 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 a1ce867248a49b..35f81a359b0161 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5563,6 +5563,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..54df5f6caa130f --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/all.hlsl @@ -0,0 +1,233 @@ +// 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,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,NO_HALF,DXIL_CHECK + +#ifdef __HLSL_ENABLE_16_BIT +// DXIL_NATIVE_HALF: define noundef i1 @ +// SPIR_NATIVE_HALF: define spir_func noundef i1 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.all.f16 +// NO_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.all.v2f16 +// NO_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.all.v3f16 +// NO_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// NATIVE_HALF: %hlsl.all = call i1 @llvm.hlsl.all.v4f16 +// NO_HALF: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.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 @ +// CHECK: %hlsl.all = call i1 @llvm.hlsl.all.v4i1 +// CHECK: ret i1 %hlsl.all +bool test_all_bool4(bool4 p0) { return all(p0); } diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl b/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl index 3efc36baa35b1a..8318588dc1556c 100644 --- a/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl +++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl @@ -1,22 +1,19 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s -// Make sure SV_DispatchThreadID translated into dx.thread.id. +// Make sure SV_DispatchThreadID translated into hlsl.thread.id. // CHECK: define void @foo() -// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.dx.thread.id(i32 0) -// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.spv.thread.id(i32 0) +// CHECK: %[[#ID:]] = call i32 @llvm.hlsl.thread.id(i32 0) // CHECK: call void @{{.*}}foo{{.*}}(i32 %[[#ID]]) [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_DispatchThreadID) {} // CHECK: define void @bar() -// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.dx.thread.id(i32 0) -// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.spv.thread.id(i32 0) +// CHECK: %[[#ID_X:]] = call i32 @llvm.hlsl.thread.id(i32 0) // CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0 -// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.dx.thread.id(i32 1) -// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.spv.thread.id(i32 1) +// CHECK: %[[#ID_Y:]] = call i32 @llvm.hlsl.thread.id(i32 1) // CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1 // CHECK-DXIL: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]]) [shader("compute")] diff --git a/llvm/include/llvm/IR/CMakeLists.txt b/llvm/include/llvm/IR/CMakeLists.txt index 468d663796ed43..c896d93c55a399 100644 --- a/llvm/include/llvm/IR/CMakeLists.txt +++ b/llvm/include/llvm/IR/CMakeLists.txt @@ -10,6 +10,7 @@ tablegen(LLVM IntrinsicsARM.h -gen-intrinsic-enums -intrinsic-prefix=arm) tablegen(LLVM IntrinsicsBPF.h -gen-intrinsic-enums -intrinsic-prefix=bpf) tablegen(LLVM IntrinsicsDirectX.h -gen-intrinsic-enums -intrinsic-prefix=dx) tablegen(LLVM IntrinsicsHexagon.h -gen-intrinsic-enums -intrinsic-prefix=hexagon) +tablegen(LLVM IntrinsicsHLSL.h -gen-intrinsic-enums -intrinsic-prefix=hlsl) tablegen(LLVM IntrinsicsLoongArch.h -gen-intrinsic-enums -intrinsic-prefix=loongarch) tablegen(LLVM IntrinsicsMips.h -gen-intrinsic-enums -intrinsic-prefix=mips) tablegen(LLVM IntrinsicsNVPTX.h -gen-intrinsic-enums -intrinsic-prefix=nvvm) diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 764902426f0b82..3381baceccc217 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -2655,6 +2655,7 @@ include "llvm/IR/IntrinsicsRISCV.td" include "llvm/IR/IntrinsicsSPIRV.td" include "llvm/IR/IntrinsicsVE.td" include "llvm/IR/IntrinsicsDirectX.td" +include "llvm/IR/IntrinsicsHLSL.td" include "llvm/IR/IntrinsicsLoongArch.td" #endif // TEST_INTRINSICS_SUPPRESS_DEFS diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index a871fac46b9fd5..9bdf823cd253ce 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -12,7 +12,6 @@ let TargetPrefix = "dx" in { -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]>; diff --git a/llvm/include/llvm/IR/IntrinsicsHLSL.td b/llvm/include/llvm/IR/IntrinsicsHLSL.td new file mode 100644 index 00000000000000..bbf666aac159a2 --- /dev/null +++ b/llvm/include/llvm/IR/IntrinsicsHLSL.td @@ -0,0 +1,17 @@ +//===- IntrinsicsDirectX.td - Defines DirectX intrinsics ---*- tablegen -*-===// +// +// 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 defines all of the DirectX-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "hlsl" in { + def int_hlsl_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>; + + def int_hlsl_thread_id : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrWillReturn]>; +} diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index 0eb09b1699aff4..308d6b3125beb7 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -53,7 +53,6 @@ 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_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">, Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>; } diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index eb126f182eadcb..c85689051d1f39 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" #include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/IntrinsicsHLSL.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsLoongArch.h" #include "llvm/IR/IntrinsicsMips.h" diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index c5d7ee76275f86..482e111b1226fd 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -325,7 +325,7 @@ let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 8)) in def Dot4 : DXILOpMapping<56, dot4, int_dx_dot4, "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 3">; -def ThreadId : DXILOpMapping<93, threadId, int_dx_thread_id, +def ThreadId : DXILOpMapping<93, threadId, int_hlsl_thread_id, "Reads the thread ID">; def GroupId : DXILOpMapping<94, groupId, int_dx_group_id, "Reads the group ID (SV_GroupID)">; diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index f09e322f88e1fd..5f39b3dd2d45f7 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/IntrinsicsHLSL.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index f4525e713c987f..83491886634be9 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -28,6 +28,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/IntrinsicsHLSL.h" #include "llvm/IR/IntrinsicsSPIRV.h" #include "llvm/Support/Debug.h" @@ -144,6 +145,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; @@ -220,8 +224,8 @@ class SPIRVInstructionSelector : public InstructionSelector { bool selectLog10(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const; - bool selectSpvThreadId(Register ResVReg, const SPIRVType *ResType, - MachineInstr &I) const; + bool selectHLSLThreadId(Register ResVReg, const SPIRVType *ResType, + MachineInstr &I) const; bool selectUnmergeValues(MachineInstr &I) const; @@ -1155,6 +1159,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 { @@ -1783,8 +1801,10 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, .addUse(I.getOperand(2).getReg()) .addUse(I.getOperand(3).getReg()); break; - case Intrinsic::spv_thread_id: - return selectSpvThreadId(ResVReg, ResType, I); + case Intrinsic::hlsl_thread_id: + return selectHLSLThreadId(ResVReg, ResType, I); + case Intrinsic::hlsl_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 @@ -2052,10 +2072,10 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg, return Result; } -bool SPIRVInstructionSelector::selectSpvThreadId(Register ResVReg, - const SPIRVType *ResType, - MachineInstr &I) const { - // DX intrinsic: @llvm.dx.thread.id(i32) +bool SPIRVInstructionSelector::selectHLSLThreadId(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + // DX intrinsic: @llvm.hlsl.thread.id(i32) // ID Name Description // 93 ThreadId reads the thread ID diff --git a/llvm/test/CodeGen/DirectX/comput_ids.ll b/llvm/test/CodeGen/DirectX/comput_ids.ll index 553994094d71e5..d9e79a2682b73e 100644 --- a/llvm/test/CodeGen/DirectX/comput_ids.ll +++ b/llvm/test/CodeGen/DirectX/comput_ids.ll @@ -10,7 +10,7 @@ target triple = "dxil-pc-shadermodel6.7-library" define i32 @test_thread_id(i32 %a) #0 { entry: ; CHECK:call i32 @dx.op.threadId.i32(i32 93, i32 %{{.*}}) - %0 = call i32 @llvm.dx.thread.id(i32 %a) + %0 = call i32 @llvm.hlsl.thread.id(i32 %a) ret i32 %0 } @@ -42,7 +42,7 @@ entry: } ; Function Attrs: nounwind readnone willreturn -declare i32 @llvm.dx.thread.id(i32) #1 +declare i32 @llvm.hlsl.thread.id(i32) #1 declare i32 @llvm.dx.group.id(i32) #1 declare i32 @llvm.dx.flattened.thread.id.in.group() #1 declare i32 @llvm.dx.thread.id.in.group(i32) #1 diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/SV_DispatchThreadID.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/SV_DispatchThreadID.ll index e93271b703f7b2..18f4bf7bbb2069 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/SV_DispatchThreadID.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/SV_DispatchThreadID.ll @@ -38,21 +38,21 @@ entry: ; CHECK: %[[#load:]] = OpLoad %[[#v3int]] %[[#GlobalInvocationId]] ; CHECK: %[[#load0:]] = OpCompositeExtract %[[#int]] %[[#load]] 0 - %0 = call i32 @llvm.spv.thread.id(i32 0) + %0 = call i32 @llvm.hlsl.thread.id(i32 0) ; CHECK: %[[#tempvar:]] = OpCompositeInsert %[[#v3int]] %[[#load0]] %[[#tempvar]] 0 %1 = insertelement <3 x i32> poison, i32 %0, i64 0 ; CHECK: %[[#load:]] = OpLoad %[[#v3int]] %[[#GlobalInvocationId]] ; CHECK: %[[#load1:]] = OpCompositeExtract %[[#int]] %[[#load]] 1 - %2 = call i32 @llvm.spv.thread.id(i32 1) + %2 = call i32 @llvm.hlsl.thread.id(i32 1) ; CHECK: %[[#tempvar:]] = OpCompositeInsert %[[#v3int]] %[[#load1]] %[[#tempvar]] 1 %3 = insertelement <3 x i32> %1, i32 %2, i64 1 ; CHECK: %[[#load:]] = OpLoad %[[#v3int]] %[[#GlobalInvocationId]] ; CHECK: %[[#load2:]] = OpCompositeExtract %[[#int]] %[[#load]] 2 - %4 = call i32 @llvm.spv.thread.id(i32 2) + %4 = call i32 @llvm.hlsl.thread.id(i32 2) ; CHECK: %[[#tempvar:]] = OpCompositeInsert %[[#v3int]] %[[#load2]] %[[#tempvar]] 2 %5 = insertelement <3 x i32> %3, i32 %4, i64 2 @@ -62,7 +62,7 @@ entry: } ; Function Attrs: nounwind willreturn memory(none) -declare i32 @llvm.spv.thread.id(i32) #2 +declare i32 @llvm.hlsl.thread.id(i32) #2 attributes #0 = { noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } attributes #1 = { norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } 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..aae4ad0f677337 --- /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.hlsl.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.hlsl.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.hlsl.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.hlsl.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.hlsl.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.hlsl.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.hlsl.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.hlsl.all.v4i1(<4 x i1> %p0) + ret i1 %hlsl.all +} + +declare i1 @llvm.hlsl.all.v4i1(<4 x i1>) +declare i1 @llvm.hlsl.all.i1(i1) +declare i1 @llvm.hlsl.all.i16(i16) +declare i1 @llvm.hlsl.all.i32(i32) +declare i1 @llvm.hlsl.all.i64(i64) +declare i1 @llvm.hlsl.all.f16(half) +declare i1 @llvm.hlsl.all.f32(float) +declare i1 @llvm.hlsl.all.f64(double) diff --git a/llvm/utils/gn/secondary/llvm/include/llvm/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/include/llvm/IR/BUILD.gn index 87e58608617aea..f54fbf60942ab7 100644 --- a/llvm/utils/gn/secondary/llvm/include/llvm/IR/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/include/llvm/IR/BUILD.gn @@ -57,6 +57,10 @@ gen_arch_intrinsics("IntrinsicsHexagon") { intrinsic_prefix = "hexagon" } +gen_arch_intrinsics("IntrinsicsHLSL") { + intrinsic_prefix = "hlsl" +} + gen_arch_intrinsics("IntrinsicsLoongArch") { intrinsic_prefix = "loongarch" } @@ -125,6 +129,7 @@ group("public_tablegen") { ":IntrinsicsBPF", ":IntrinsicsDirectX", ":IntrinsicsHexagon", + ":IntrinsicsHLSL", ":IntrinsicsLoongArch", ":IntrinsicsMips", ":IntrinsicsNVPTX", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits