From b0732c51fd3a9a13cb1e5edad9ba8fb94f227127 Mon Sep 17 00:00:00 2001 From: Nikita Kornev Date: Wed, 16 Mar 2022 12:31:28 +0300 Subject: [PATCH] [Backport] Support cl_bf16_conversions --- lib/SPIRV/OCLToSPIRV.cpp | 120 ++++++++++++++ lib/SPIRV/OCLUtil.h | 20 +++ lib/SPIRV/SPIRVToOCL.cpp | 31 ++++ lib/SPIRV/SPIRVToOCL.h | 7 + ...tAsBFloat16Float_inval_scalar_signature.ll | 23 +++ ...onvertAsBFloat16Float_inval_vec_elem_ty.ll | 23 +++ .../ConvertAsBFloat16Float_inval_vec_size.ll | 23 +++ ...BFloat16AsUshort_inval_scalar_signature.ll | 23 +++ ...nvertBFloat16AsUshort_inval_vec_elem_ty.ll | 23 +++ .../ConvertBFloat16AsUshort_inval_vec_size.ll | 23 +++ .../cl_bfloat16_conversions_extension.ll | 151 ++++++++++++++++++ .../convert_bfloat16_generic.ll | 2 +- 12 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_scalar_signature.ll create mode 100644 test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_elem_ty.ll create mode 100644 test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_size.ll create mode 100644 test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_scalar_signature.ll create mode 100644 test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_elem_ty.ll create mode 100644 test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_size.ll create mode 100644 test/transcoding/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension.ll diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp index 788fac62d1..37f80acbca 100644 --- a/lib/SPIRV/OCLToSPIRV.cpp +++ b/lib/SPIRV/OCLToSPIRV.cpp @@ -263,6 +263,11 @@ class OCLToSPIRVBase : public InstVisitor { void visitCallLdexp(CallInst *CI, StringRef MangledName, StringRef DemangledName); + /// For cl_intel_convert_bfloat16_as_ushort + void visitCallConvertBFloat16AsUshort(CallInst *CI, StringRef DemangledName); + /// For cl_intel_convert_as_bfloat16_float + void visitCallConvertAsBFloat16Float(CallInst *CI, StringRef DemangledName); + void setOCLTypeToSPIRV(OCLTypeToSPIRVBase *OCLTypeToSPIRV) { OCLTypeToSPIRVPtr = OCLTypeToSPIRV; } @@ -574,6 +579,24 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) { visitCallLdexp(&CI, MangledName, DemangledName); return; } + if (DemangledName == kOCLBuiltinName::ConvertBFloat16AsUShort || + DemangledName == kOCLBuiltinName::ConvertBFloat162AsUShort2 || + DemangledName == kOCLBuiltinName::ConvertBFloat163AsUShort3 || + DemangledName == kOCLBuiltinName::ConvertBFloat164AsUShort4 || + DemangledName == kOCLBuiltinName::ConvertBFloat168AsUShort8 || + DemangledName == kOCLBuiltinName::ConvertBFloat1616AsUShort16) { + visitCallConvertBFloat16AsUshort(&CI, DemangledName); + return; + } + if (DemangledName == kOCLBuiltinName::ConvertAsBFloat16Float || + DemangledName == kOCLBuiltinName::ConvertAsBFloat162Float2 || + DemangledName == kOCLBuiltinName::ConvertAsBFloat163Float3 || + DemangledName == kOCLBuiltinName::ConvertAsBFloat164Float4 || + DemangledName == kOCLBuiltinName::ConvertAsBFloat168Float8 || + DemangledName == kOCLBuiltinName::ConvertAsBFloat1616Float16) { + visitCallConvertAsBFloat16Float(&CI, DemangledName); + return; + } visitCallBuiltinSimple(&CI, MangledName, DemangledName); } @@ -1916,6 +1939,103 @@ void OCLToSPIRVBase::visitCallLdexp(CallInst *CI, StringRef MangledName, visitCallBuiltinSimple(CI, MangledName, DemangledName); } +void OCLToSPIRVBase::visitCallConvertBFloat16AsUshort(CallInst *CI, + StringRef DemangledName) { + Type *RetTy = CI->getType(); + Type *ArgTy = CI->getOperand(0)->getType(); + if (DemangledName == kOCLBuiltinName::ConvertBFloat16AsUShort) { + if (!RetTy->isIntegerTy(16U) || !ArgTy->isFloatTy()) + report_fatal_error( + "OpConvertBFloat16AsUShort must be of i16 and take float"); + } else { + FixedVectorType *RetTyVec = cast(RetTy); + FixedVectorType *ArgTyVec = cast(ArgTy); + if (!RetTyVec || !RetTyVec->getElementType()->isIntegerTy(16U) || + !ArgTyVec || !ArgTyVec->getElementType()->isFloatTy()) + report_fatal_error("OpConvertBFloat16NAsUShortN must be of and " + "take "); + unsigned RetTyVecSize = RetTyVec->getNumElements(); + unsigned ArgTyVecSize = ArgTyVec->getNumElements(); + if (DemangledName == kOCLBuiltinName::ConvertBFloat162AsUShort2) { + if (RetTyVecSize != 2 || ArgTyVecSize != 2) + report_fatal_error("ConvertBFloat162AsUShort2 must be of <2 x i16> and " + "take <2 x float>"); + } else if (DemangledName == kOCLBuiltinName::ConvertBFloat163AsUShort3) { + if (RetTyVecSize != 3 || ArgTyVecSize != 3) + report_fatal_error("ConvertBFloat163AsUShort3 must be of <3 x i16> and " + "take <3 x float>"); + } else if (DemangledName == kOCLBuiltinName::ConvertBFloat164AsUShort4) { + if (RetTyVecSize != 4 || ArgTyVecSize != 4) + report_fatal_error("ConvertBFloat164AsUShort4 must be of <4 x i16> and " + "take <4 x float>"); + } else if (DemangledName == kOCLBuiltinName::ConvertBFloat168AsUShort8) { + if (RetTyVecSize != 8 || ArgTyVecSize != 8) + report_fatal_error("ConvertBFloat168AsUShort8 must be of <8 x i16> and " + "take <8 x float>"); + } else if (DemangledName == kOCLBuiltinName::ConvertBFloat1616AsUShort16) { + if (RetTyVecSize != 16 || ArgTyVecSize != 16) + report_fatal_error("ConvertBFloat1616AsUShort16 must be of <16 x i16> " + "and take <16 x float>"); + } + } + + AttributeList Attrs = CI->getCalledFunction()->getAttributes(); + mutateCallInstSPIRV( + M, CI, + [=](CallInst *, std::vector &Args) { + return getSPIRVFuncName(internal::OpConvertFToBF16INTEL); + }, + &Attrs); +} + +void OCLToSPIRVBase::visitCallConvertAsBFloat16Float(CallInst *CI, + StringRef DemangledName) { + Type *RetTy = CI->getType(); + Type *ArgTy = CI->getOperand(0)->getType(); + if (DemangledName == kOCLBuiltinName::ConvertAsBFloat16Float) { + if (!RetTy->isFloatTy() || !ArgTy->isIntegerTy(16U)) + report_fatal_error( + "OpConvertAsBFloat16Float must be of float and take i16"); + } else { + FixedVectorType *RetTyVec = cast(RetTy); + FixedVectorType *ArgTyVec = cast(ArgTy); + if (!RetTyVec || !RetTyVec->getElementType()->isFloatTy() || !ArgTyVec || + !ArgTyVec->getElementType()->isIntegerTy(16U)) + report_fatal_error("OpConvertAsBFloat16NFloatN must be of " + "and take "); + unsigned RetTyVecSize = RetTyVec->getNumElements(); + unsigned ArgTyVecSize = ArgTyVec->getNumElements(); + if (DemangledName == kOCLBuiltinName::ConvertAsBFloat162Float2) { + if (RetTyVecSize != 2 || ArgTyVecSize != 2) + report_fatal_error("ConvertAsBFloat162Float2 must be of <2 x float> " + "and take <2 x i16>"); + } else if (DemangledName == kOCLBuiltinName::ConvertAsBFloat163Float3) { + if (RetTyVecSize != 3 || ArgTyVecSize != 3) + report_fatal_error("ConvertAsBFloat163Float3 must be of <3 x float> " + "and take <3 x i16>"); + } else if (DemangledName == kOCLBuiltinName::ConvertAsBFloat164Float4) { + if (RetTyVecSize != 4 || ArgTyVecSize != 4) + report_fatal_error("ConvertAsBFloat164Float4 must be of <4 x float> " + "and take <4 x i16>"); + } else if (DemangledName == kOCLBuiltinName::ConvertAsBFloat168Float8) { + if (RetTyVecSize != 8 || ArgTyVecSize != 8) + report_fatal_error("ConvertAsBFloat168Float8 must be of <8 x float> " + "and take <8 x i16>"); + } else if (DemangledName == kOCLBuiltinName::ConvertAsBFloat1616Float16) { + if (RetTyVecSize != 16 || ArgTyVecSize != 16) + report_fatal_error("ConvertAsBFloat1616Float16 must be of <16 x float> " + "and take <16 x i16>"); + } + } + + AttributeList Attrs = CI->getCalledFunction()->getAttributes(); + mutateCallInstSPIRV( + M, CI, + [=](CallInst *, std::vector &Args) { + return getSPIRVFuncName(internal::OpConvertBF16ToFINTEL); + }, + &Attrs); +} } // namespace SPIRV INITIALIZE_PASS_BEGIN(OCLToSPIRVLegacy, "ocl-to-spv", diff --git a/lib/SPIRV/OCLUtil.h b/lib/SPIRV/OCLUtil.h index 1d9e4f9385..dcb61b003b 100644 --- a/lib/SPIRV/OCLUtil.h +++ b/lib/SPIRV/OCLUtil.h @@ -305,6 +305,26 @@ const static char SubgroupBlockWriteINTELPrefix[] = const static char SubgroupImageMediaBlockINTELPrefix[] = "intel_sub_group_media_block"; const static char LDEXP[] = "ldexp"; +#define _SPIRV_OP(x) \ + const static char ConvertBFloat16##x##AsUShort##x[] = \ + "intel_convert_bfloat16" #x "_as_ushort" #x; +_SPIRV_OP() +_SPIRV_OP(2) +_SPIRV_OP(3) +_SPIRV_OP(4) +_SPIRV_OP(8) +_SPIRV_OP(16) +#undef _SPIRV_OP +#define _SPIRV_OP(x) \ + const static char ConvertAsBFloat16##x##Float##x[] = \ + "intel_convert_as_bfloat16" #x "_float" #x; +_SPIRV_OP() +_SPIRV_OP(2) +_SPIRV_OP(3) +_SPIRV_OP(4) +_SPIRV_OP(8) +_SPIRV_OP(16) +#undef _SPIRV_OP } // namespace kOCLBuiltinName /// Offset for OpenCL image channel order enumeration values. diff --git a/lib/SPIRV/SPIRVToOCL.cpp b/lib/SPIRV/SPIRVToOCL.cpp index 806cc98ae1..26ac5e3fb8 100644 --- a/lib/SPIRV/SPIRVToOCL.cpp +++ b/lib/SPIRV/SPIRVToOCL.cpp @@ -194,6 +194,11 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) { visitCallSPIRVRelational(&CI, OC); return; } + if (OC == internal::OpConvertFToBF16INTEL || + OC == internal::OpConvertBF16ToFINTEL) { + visitCallSPIRVBFloat16Conversions(&CI, OC); + return; + } if (OCLSPIRVBuiltinMap::rfind(OC)) visitCallSPIRVBuiltin(&CI, OC); } @@ -970,6 +975,32 @@ void SPIRVToOCLBase::visitCallSPIRVGenericPtrMemSemantics(CallInst *CI) { &Attrs); } +void SPIRVToOCLBase::visitCallSPIRVBFloat16Conversions(CallInst *CI, Op OC) { + AttributeList Attrs = CI->getCalledFunction()->getAttributes(); + mutateCallInstOCL( + M, CI, + [=](CallInst *, std::vector &Args) { + Type *ArgTy = CI->getOperand(0)->getType(); + std::string N = + ArgTy->isVectorTy() + ? std::to_string(cast(ArgTy)->getNumElements()) + : ""; + std::string Name; + switch (static_cast(OC)) { + case internal::OpConvertFToBF16INTEL: + Name = "intel_convert_bfloat16" + N + "_as_ushort" + N; + break; + case internal::OpConvertBF16ToFINTEL: + Name = "intel_convert_as_bfloat16" + N + "_float" + N; + break; + default: + break; // do nothing + } + return Name; + }, + &Attrs); +} + void SPIRVToOCLBase::visitCallSPIRVBuiltin(CallInst *CI, Op OC) { AttributeList Attrs = CI->getCalledFunction()->getAttributes(); mutateCallInstOCL( diff --git a/lib/SPIRV/SPIRVToOCL.h b/lib/SPIRV/SPIRVToOCL.h index 380459faa9..62b49e91ee 100644 --- a/lib/SPIRV/SPIRVToOCL.h +++ b/lib/SPIRV/SPIRVToOCL.h @@ -161,6 +161,13 @@ class SPIRVToOCLBase : public InstVisitor { /// %1 = shl i31 %0, 8 void visitCallSPIRVGenericPtrMemSemantics(CallInst *CI); + /// Transform __spirv_ConvertFToBF16INTELDv(N)_f to: + /// intel_convert_bfloat16(N)_as_ushort(N)Dv(N)_f; + /// and transform __spirv_ConvertBF16ToFINTELDv(N)_s to: + /// intel_convert_as_bfloat16(N)_float(N)Dv(N)_t; + /// where N is vector size + void visitCallSPIRVBFloat16Conversions(CallInst *CI, Op OC); + /// Transform __spirv_* builtins to OCL 2.0 builtins. /// No change with arguments. void visitCallSPIRVBuiltin(CallInst *CI, Op OC); diff --git a/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_scalar_signature.ll b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_scalar_signature.ll new file mode 100644 index 0000000000..33908268da --- /dev/null +++ b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_scalar_signature.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not --crash llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +; CHECK-ERROR: OpConvertAsBFloat16Float must be of float and take i16 + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func double @_Z31intel_convert_as_bfloat16_floatt(i32 zeroext 0) + ret void +} + +; Function Attrs: convergent +declare spir_func double @_Z31intel_convert_as_bfloat16_floatt(i32 zeroext) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_elem_ty.ll b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_elem_ty.ll new file mode 100644 index 0000000000..d69c354d16 --- /dev/null +++ b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_elem_ty.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not --crash llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +; CHECK-ERROR: OpConvertAsBFloat16NFloatN must be of and take + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func <2 x double> @_Z33intel_convert_as_bfloat162_float2Dv2_t(<2 x i32> zeroinitializer) + ret void +} + +; ; Function Attrs: convergent +declare spir_func <2 x double> @_Z33intel_convert_as_bfloat162_float2Dv2_t(<2 x i32>) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_size.ll b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_size.ll new file mode 100644 index 0000000000..f8c1c146b3 --- /dev/null +++ b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertAsBFloat16Float_inval_vec_size.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not --crash llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +; CHECK-ERROR: ConvertAsBFloat162Float2 must be of <2 x float> and take <2 x i16> + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func <8 x float> @_Z33intel_convert_as_bfloat162_float2Dv2_t(<4 x i16> zeroinitializer) + ret void +} + +; Function Attrs: convergent +declare spir_func <8 x float> @_Z33intel_convert_as_bfloat162_float2Dv2_t(<4 x i16>) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_scalar_signature.ll b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_scalar_signature.ll new file mode 100644 index 0000000000..586dce1b5e --- /dev/null +++ b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_scalar_signature.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not --crash llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +; CHECK-ERROR: OpConvertBFloat16AsUShort must be of i16 and take float + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func zeroext i16 @_Z32intel_convert_bfloat16_as_ushortf(double 0.000000e+00) + ret void +} + +; Function Attrs: convergent +declare spir_func zeroext i16 @_Z32intel_convert_bfloat16_as_ushortf(double) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_elem_ty.ll b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_elem_ty.ll new file mode 100644 index 0000000000..ac4f2388cd --- /dev/null +++ b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_elem_ty.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not --crash llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +; CHECK-ERROR: OpConvertBFloat16NAsUShortN must be of and take + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func <2 x i32> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<2 x double> zeroinitializer) + ret void +} + +; Function Attrs: convergent +declare spir_func <2 x i32> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<2 x double>) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_size.ll b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_size.ll new file mode 100644 index 0000000000..7c3e71fd4f --- /dev/null +++ b/test/negative/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension/ConvertBFloat16AsUshort_inval_vec_size.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not --crash llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +; CHECK-ERROR: ConvertBFloat162AsUShort2 must be of <2 x i16> and take <2 x float> + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func <8 x i16> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<4 x float> zeroinitializer) + ret void +} + +; Function Attrs: convergent +declare spir_func <8 x i16> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<4 x float>) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/transcoding/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension.ll b/test/transcoding/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension.ll new file mode 100644 index 0000000000..11b869a9ba --- /dev/null +++ b/test/transcoding/SPV_INTEL_bfloat16_conversion/cl_bfloat16_conversions_extension.ll @@ -0,0 +1,151 @@ +; RUN: llvm-as %s -o %t.bc + +; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-WO-EXT + +; RUN: llvm-spirv -s %t.bc -o %t.regularized.bc +; RUN: llvm-dis %t.regularized.bc -o %t.regularized.ll +; RUN: FileCheck < %t.regularized.ll %s --check-prefix=CHECK-REGULARIZED + +; RUN: llvm-spirv --spirv-text %t.bc -o %t.spt --spirv-ext=+SPV_INTEL_bfloat16_conversion +; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV + +; RUN: llvm-spirv -to-binary %t.spt -o %t.spv + +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc --spirv-target-env=CL2.0 +; RUN: llvm-dis %t.rev.bc -o %t.rev.ll +; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM-CL20 + +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc --spirv-target-env=SPV-IR +; RUN: llvm-dis %t.rev.bc -o %t.rev.ll +; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM-SPV + +; CHECK-WO-EXT: RequiresExtension: Feature requires the following SPIR-V extension: +; CHECK-WO-EXT-NEXT: SPV_INTEL_bfloat16_conversion + +; CHECK-REGULARIZED: call spir_func zeroext i16 @_Z27__spirv_ConvertFToBF16INTELf(float 0.000000e+00) +; CHECK-REGULARIZED: call spir_func <2 x i16> @_Z27__spirv_ConvertFToBF16INTELDv2_f(<2 x float> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <3 x i16> @_Z27__spirv_ConvertFToBF16INTELDv3_f(<3 x float> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <4 x i16> @_Z27__spirv_ConvertFToBF16INTELDv4_f(<4 x float> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <8 x i16> @_Z27__spirv_ConvertFToBF16INTELDv8_f(<8 x float> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <16 x i16> @_Z27__spirv_ConvertFToBF16INTELDv16_f(<16 x float> zeroinitializer) +; CHECK-REGULARIZED: call spir_func float @_Z27__spirv_ConvertBF16ToFINTELs(i16 zeroext 0) +; CHECK-REGULARIZED: call spir_func <2 x float> @_Z27__spirv_ConvertBF16ToFINTELDv2_s(<2 x i16> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <3 x float> @_Z27__spirv_ConvertBF16ToFINTELDv3_s(<3 x i16> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <4 x float> @_Z27__spirv_ConvertBF16ToFINTELDv4_s(<4 x i16> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <8 x float> @_Z27__spirv_ConvertBF16ToFINTELDv8_s(<8 x i16> zeroinitializer) +; CHECK-REGULARIZED: call spir_func <16 x float> @_Z27__spirv_ConvertBF16ToFINTELDv16_s(<16 x i16> zeroinitializer) + +; CHECK-SPIRV: TypeInt [[#Int16Ty:]] 16 0 +; CHECK-SPIRV: TypeFloat [[#FloatTy:]] 32 +; CHECK-SPIRV: TypeVector [[#VecFloat2:]] [[#FloatTy]] 2 +; CHECK-SPIRV: TypeVector [[#VecInt162:]] [[#Int16Ty]] 2 +; CHECK-SPIRV: TypeVector [[#VecFloat3:]] [[#FloatTy]] 3 +; CHECK-SPIRV: TypeVector [[#VecInt163:]] [[#Int16Ty]] 3 +; CHECK-SPIRV: TypeVector [[#VecFloat4:]] [[#FloatTy]] 4 +; CHECK-SPIRV: TypeVector [[#VecInt164:]] [[#Int16Ty]] 4 +; CHECK-SPIRV: TypeVector [[#VecFloat8:]] [[#FloatTy]] 8 +; CHECK-SPIRV: TypeVector [[#VecInt168:]] [[#Int16Ty]] 8 +; CHECK-SPIRV: TypeVector [[#VecFloat16:]] [[#FloatTy]] 16 +; CHECK-SPIRV: TypeVector [[#VecInt1616:]] [[#Int16Ty]] 16 + +; CHECK-SPIRV: ConvertFToBF16INTEL [[#Int16Ty]] +; CHECK-SPIRV: ConvertFToBF16INTEL [[#VecInt162]] +; CHECK-SPIRV: ConvertFToBF16INTEL [[#VecInt163]] +; CHECK-SPIRV: ConvertFToBF16INTEL [[#VecInt164]] +; CHECK-SPIRV: ConvertFToBF16INTEL [[#VecInt168]] +; CHECK-SPIRV: ConvertFToBF16INTEL [[#VecInt1616]] +; CHECK-SPIRV: ConvertBF16ToFINTEL [[#FloatTy]] +; CHECK-SPIRV: ConvertBF16ToFINTEL [[#VecFloat2]] +; CHECK-SPIRV: ConvertBF16ToFINTEL [[#VecFloat3]] +; CHECK-SPIRV: ConvertBF16ToFINTEL [[#VecFloat4]] +; CHECK-SPIRV: ConvertBF16ToFINTEL [[#VecFloat8]] +; CHECK-SPIRV: ConvertBF16ToFINTEL [[#VecFloat16]] + +; CHECK-LLVM-SPV: call spir_func i16 @_Z27__spirv_ConvertFToBF16INTELf(float 0.000000e+00) +; CHECK-LLVM-SPV: call spir_func <2 x i16> @_Z27__spirv_ConvertFToBF16INTELDv2_f(<2 x float> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <3 x i16> @_Z27__spirv_ConvertFToBF16INTELDv3_f(<3 x float> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <4 x i16> @_Z27__spirv_ConvertFToBF16INTELDv4_f(<4 x float> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <8 x i16> @_Z27__spirv_ConvertFToBF16INTELDv8_f(<8 x float> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <16 x i16> @_Z27__spirv_ConvertFToBF16INTELDv16_f(<16 x float> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func float @_Z27__spirv_ConvertBF16ToFINTELs(i16 0) +; CHECK-LLVM-SPV: call spir_func <2 x float> @_Z27__spirv_ConvertBF16ToFINTELDv2_s(<2 x i16> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <3 x float> @_Z27__spirv_ConvertBF16ToFINTELDv3_s(<3 x i16> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <4 x float> @_Z27__spirv_ConvertBF16ToFINTELDv4_s(<4 x i16> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <8 x float> @_Z27__spirv_ConvertBF16ToFINTELDv8_s(<8 x i16> zeroinitializer) +; CHECK-LLVM-SPV: call spir_func <16 x float> @_Z27__spirv_ConvertBF16ToFINTELDv16_s(<16 x i16> zeroinitializer) + +; CHECK-LLVM-CL20: call spir_func i16 @_Z32intel_convert_bfloat16_as_ushortf(float 0.000000e+00) +; CHECK-LLVM-CL20: call spir_func <2 x i16> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<2 x float> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <3 x i16> @_Z34intel_convert_bfloat163_as_ushort3Dv3_f(<3 x float> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <4 x i16> @_Z34intel_convert_bfloat164_as_ushort4Dv4_f(<4 x float> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <8 x i16> @_Z34intel_convert_bfloat168_as_ushort8Dv8_f(<8 x float> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <16 x i16> @_Z36intel_convert_bfloat1616_as_ushort16Dv16_f(<16 x float> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func float @_Z31intel_convert_as_bfloat16_floats(i16 0) +; CHECK-LLVM-CL20: call spir_func <2 x float> @_Z33intel_convert_as_bfloat162_float2Dv2_s(<2 x i16> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <3 x float> @_Z33intel_convert_as_bfloat163_float3Dv3_s(<3 x i16> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <4 x float> @_Z33intel_convert_as_bfloat164_float4Dv4_s(<4 x i16> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <8 x float> @_Z33intel_convert_as_bfloat168_float8Dv8_s(<8 x i16> zeroinitializer) +; CHECK-LLVM-CL20: call spir_func <16 x float> @_Z35intel_convert_as_bfloat1616_float16Dv16_s(<16 x i16> zeroinitializer) + +; ModuleID = 'kernel.cl' +source_filename = "kernel.cl" +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define dso_local spir_kernel void @f() { +entry: + %call = call spir_func zeroext i16 @_Z32intel_convert_bfloat16_as_ushortf(float 0.000000e+00) + %call1 = call spir_func <2 x i16> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<2 x float> zeroinitializer) + %call2 = call spir_func <3 x i16> @_Z34intel_convert_bfloat163_as_ushort3Dv3_f(<3 x float> zeroinitializer) + %call3 = call spir_func <4 x i16> @_Z34intel_convert_bfloat164_as_ushort4Dv4_f(<4 x float> zeroinitializer) + %call4 = call spir_func <8 x i16> @_Z34intel_convert_bfloat168_as_ushort8Dv8_f(<8 x float> zeroinitializer) + %call5 = call spir_func <16 x i16> @_Z36intel_convert_bfloat1616_as_ushort16Dv16_f(<16 x float> zeroinitializer) + %call6 = call spir_func float @_Z31intel_convert_as_bfloat16_floatt(i16 zeroext 0) + %call7 = call spir_func <2 x float> @_Z33intel_convert_as_bfloat162_float2Dv2_t(<2 x i16> zeroinitializer) + %call8 = call spir_func <3 x float> @_Z33intel_convert_as_bfloat163_float3Dv3_t(<3 x i16> zeroinitializer) + %call9 = call spir_func <4 x float> @_Z33intel_convert_as_bfloat164_float4Dv4_t(<4 x i16> zeroinitializer) + %call10 = call spir_func <8 x float> @_Z33intel_convert_as_bfloat168_float8Dv8_t(<8 x i16> zeroinitializer) + %call11 = call spir_func <16 x float> @_Z35intel_convert_as_bfloat1616_float16Dv16_t(<16 x i16> zeroinitializer) + ret void +} + +; Function Attrs: convergent +declare spir_func zeroext i16 @_Z32intel_convert_bfloat16_as_ushortf(float) + +; Function Attrs: convergent +declare spir_func <2 x i16> @_Z34intel_convert_bfloat162_as_ushort2Dv2_f(<2 x float>) + +; Function Attrs: convergent +declare spir_func <3 x i16> @_Z34intel_convert_bfloat163_as_ushort3Dv3_f(<3 x float>) + +; Function Attrs: convergent +declare spir_func <4 x i16> @_Z34intel_convert_bfloat164_as_ushort4Dv4_f(<4 x float>) + +; Function Attrs: convergent +declare spir_func <8 x i16> @_Z34intel_convert_bfloat168_as_ushort8Dv8_f(<8 x float>) + +; Function Attrs: convergent +declare spir_func <16 x i16> @_Z36intel_convert_bfloat1616_as_ushort16Dv16_f(<16 x float>) + +; Function Attrs: convergent +declare spir_func float @_Z31intel_convert_as_bfloat16_floatt(i16 zeroext) + +; Function Attrs: convergent +declare spir_func <2 x float> @_Z33intel_convert_as_bfloat162_float2Dv2_t(<2 x i16>) + +; Function Attrs: convergent +declare spir_func <3 x float> @_Z33intel_convert_as_bfloat163_float3Dv3_t(<3 x i16>) + +; Function Attrs: convergent +declare spir_func <4 x float> @_Z33intel_convert_as_bfloat164_float4Dv4_t(<4 x i16>) + +; Function Attrs: convergent +declare spir_func <8 x float> @_Z33intel_convert_as_bfloat168_float8Dv8_t(<8 x i16>) + +; Function Attrs: convergent +declare spir_func <16 x float> @_Z35intel_convert_as_bfloat1616_float16Dv16_t(<16 x i16>) + +!opencl.ocl.version = !{!0} + +!0 = !{i32 2, i32 0} diff --git a/test/transcoding/SPV_INTEL_bfloat16_conversion/convert_bfloat16_generic.ll b/test/transcoding/SPV_INTEL_bfloat16_conversion/convert_bfloat16_generic.ll index 2974e562ec..a9542a867f 100644 --- a/test/transcoding/SPV_INTEL_bfloat16_conversion/convert_bfloat16_generic.ll +++ b/test/transcoding/SPV_INTEL_bfloat16_conversion/convert_bfloat16_generic.ll @@ -2,7 +2,7 @@ ; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_bfloat16_conversion ; RUN: llvm-spirv %t.spv -o %t.spt --to-text ; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV -; RUN: llvm-spirv %t.spv -o %t.rev.bc -r +; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=SPV-IR ; RUN: llvm-dis %t.rev.bc -o %t.rev.ll ; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM