diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 3dbecc57c2..79cfe362e3 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -4029,6 +4029,10 @@ bool SPIRVToLLVM::transVectorComputeMetadata(SPIRVFunction *BF) { if (BF->hasDecorate(DecorationVectorComputeCallableFunctionINTEL)) F->addFnAttr(kVCMetadata::VCCallable); + auto SEVAttr = Attribute::get(*Context, kVCMetadata::VCSingleElementVector); + if (BF->hasDecorate(DecorationSingleElementVectorINTEL)) + F->addAttribute(AttributeList::ReturnIndex, SEVAttr); + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) { auto ArgNo = I->getArgNo(); @@ -4039,6 +4043,8 @@ bool SPIRVToLLVM::transVectorComputeMetadata(SPIRVFunction *BF) { std::to_string(Kind)); F->addAttribute(ArgNo + 1, Attr); } + if (BA->hasDecorate(DecorationSingleElementVectorINTEL)) + F->addAttribute(ArgNo + 1, SEVAttr); } // Do not add float control if there is no any diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index a8ef89debd..f907d38daf 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -621,6 +621,15 @@ void LLVMToSPIRV::transVectorComputeMetadata(Function *F) { BF->addDecorate(DecorationVectorComputeCallableFunctionINTEL); } + if (Attrs.hasAttribute(AttributeList::ReturnIndex, + kVCMetadata::VCSingleElementVector)) { + auto *RT = BF->getType(); + assert(RT->isTypeBool() || RT->isTypeFloat() || RT->isTypeInt() || + RT->isTypePointer() && + "This decoration is valid only for Scalar or Pointer types"); + BF->addDecorate(DecorationSingleElementVectorINTEL); + } + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) { auto ArgNo = I->getArgNo(); @@ -632,6 +641,13 @@ void LLVMToSPIRV::transVectorComputeMetadata(Function *F) { .getAsInteger(0, Kind); BA->addDecorate(DecorationFuncParamIOKind, Kind); } + if (Attrs.hasAttribute(ArgNo + 1, kVCMetadata::VCSingleElementVector)) { + auto *AT = BA->getType(); + assert(AT->isTypeBool() || AT->isTypeFloat() || AT->isTypeInt() || + AT->isTypePointer() && + "This decoration is valid only for Scalar or Pointer types"); + BA->addDecorate(DecorationSingleElementVectorINTEL); + } } if (!isKernel(F) && BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_float_controls2) && diff --git a/lib/SPIRV/VectorComputeUtil.h b/lib/SPIRV/VectorComputeUtil.h index fcf082d802..464af785fc 100755 --- a/lib/SPIRV/VectorComputeUtil.h +++ b/lib/SPIRV/VectorComputeUtil.h @@ -109,6 +109,7 @@ const static char VCVolatile[] = "VCVolatile"; const static char VCByteOffset[] = "VCByteOffset"; const static char VCSIMTCall[] = "VCSIMTCall"; const static char VCCallable[] = "VCCallable"; +const static char VCSingleElementVector[] = "VCSingleElementVector"; } // namespace kVCMetadata namespace kVCType { diff --git a/lib/SPIRV/libSPIRV/SPIRVEnum.h b/lib/SPIRV/libSPIRV/SPIRVEnum.h index 49c6e1a0d1..ff3ec2ea8b 100644 --- a/lib/SPIRV/libSPIRV/SPIRVEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVEnum.h @@ -410,6 +410,8 @@ template <> inline void SPIRVMap::init() { {CapabilityFunctionFloatControlINTEL}); ADD_VEC_INIT(DecorationFunctionFloatingPointModeINTEL, {CapabilityFunctionFloatControlINTEL}); + ADD_VEC_INIT(DecorationSingleElementVectorINTEL, + {CapabilityVectorComputeINTEL}); ADD_VEC_INIT(DecorationVectorComputeCallableFunctionINTEL, {CapabilityVectorComputeINTEL}); } diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index d9b294577f..5559423378 100644 --- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -161,6 +161,7 @@ template <> inline void SPIRVMap::init() { add(DecorationIOPipeStorageINTEL, "IOPipeStorageINTEL"); add(DecorationFunctionFloatingPointModeINTEL, "FunctionFloatingPointModeINTEL"); + add(DecorationSingleElementVectorINTEL, "SingleElementVectorINTEL"); add(DecorationVectorComputeCallableFunctionINTEL, "VectorComputeCallableFunctionINTEL"); add(DecorationMax, "Max"); diff --git a/lib/SPIRV/libSPIRV/spirv.hpp b/lib/SPIRV/libSPIRV/spirv.hpp index 980ce89e81..e0a3fd056a 100644 --- a/lib/SPIRV/libSPIRV/spirv.hpp +++ b/lib/SPIRV/libSPIRV/spirv.hpp @@ -522,6 +522,7 @@ enum Decoration { DecorationBufferLocationINTEL = 5921, DecorationIOPipeStorageINTEL = 5944, DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, DecorationVectorComputeCallableFunctionINTEL = 6087, DecorationMax = 0x7fffffff, }; diff --git a/test/transcoding/SPV_INTEL_vector_compute/decoration_single_element_vector.ll b/test/transcoding/SPV_INTEL_vector_compute/decoration_single_element_vector.ll new file mode 100755 index 0000000000..75e67872e3 --- /dev/null +++ b/test/transcoding/SPV_INTEL_vector_compute/decoration_single_element_vector.ll @@ -0,0 +1,50 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-allow-unknown-intrinsics +; RUN: llvm-spirv %t.spv -o %t.spt --to-text +; RUN: llvm-spirv -r %t.spv -o %t.bc +; RUN: llvm-dis %t.bc -o %t.ll +; RUN: FileCheck %s --input-file %t.spt -check-prefix=SPV +; RUN: FileCheck %s --input-file %t.ll -check-prefix=LLVM + +; ModuleID = 'linear_genx.cpp' +source_filename = "linear_genx.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir64" + + + +; SPV-DAG: Name [[def:[0-9]+]] "_Z24__cm_intrinsic_impl_sdivu2CMvb1_cS_" +; SPV-DAG: Name [[a:[0-9]+]] "a" +; SPV-DAG: Name [[b:[0-9]+]] "b" +; SPV-DAG: Decorate [[def]] SingleElementVectorINTEL +; SPV-DAG: Decorate [[a]] SingleElementVectorINTEL +; SPV-DAG: Decorate [[b]] SingleElementVectorINTEL + +; LLVM-DAG: "VCSingleElementVector" i8 @_Z24__cm_intrinsic_impl_sdivu2CMvb1_cS_(i8 "VCSingleElementVector" %a, i8 "VCSingleElementVector" %b) +; LLVM-DAG: i8 @some.unknown.intrinsic(i8 "VCSingleElementVector", i8) +; Function Attrs: noinline norecurse nounwind readnone +define dso_local "VCSingleElementVector" i8 @_Z24__cm_intrinsic_impl_sdivu2CMvb1_cS_(i8 "VCSingleElementVector" %a, i8 "VCSingleElementVector" %b) local_unnamed_addr #1 { +entry: + %conv.i.i = sitofp i8 %a to float + %conv1.i.i = sitofp i8 %b to float + %div.i.i = fdiv float 1.000000e+00, %conv1.i.i + %mul.i.i = fmul float %conv.i.i, 0x3FF0000100000000 + %mul2.i.i = fmul float %mul.i.i, %div.i.i + %conv3.i.i = fptosi float %mul2.i.i to i32 + %conv3.i = trunc i32 %conv3.i.i to i8 + ret i8 %conv3.i +} + + +; Function Attrs: noinline nounwind +define dso_local dllexport spir_kernel void @linear(i8 %ibuf, i8 %obuf) local_unnamed_addr #1 { +entry: + %0 = call i8 @_Z24__cm_intrinsic_impl_sdivu2CMvb1_cS_(i8 %ibuf, i8 %obuf) + %1 = tail call i8 @some.unknown.intrinsic(i8 %ibuf, i8 %obuf) + ret void +} + +; Function Attrs: nounwind readnone +declare i8 @some.unknown.intrinsic(i8 "VCSingleElementVector", i8) #1 + +attributes #1 = { noinline norecurse nounwind readnone "VCFunction"}