From cbb70aa95f08206db9a1e4f628b42c77a6abd7b1 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezzubikov Date: Wed, 20 May 2020 01:16:22 +0300 Subject: [PATCH 1/6] Improve constant expressions lowering for function pointers. Extend constexprs lowering support to lower constant vector of pure function pointers w/o any transformations inside. --- llvm-spirv/lib/SPIRV/SPIRVLowerConstExpr.cpp | 27 +++++++----- llvm-spirv/lib/SPIRV/SPIRVWriter.cpp | 17 ++++++-- llvm-spirv/test/constexpr_vector.ll | 13 ++++-- .../vector_elem.ll | 42 +++++++++++++++++++ 4 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 llvm-spirv/test/transcoding/SPV_INTEL_function_pointers/vector_elem.ll diff --git a/llvm-spirv/lib/SPIRV/SPIRVLowerConstExpr.cpp b/llvm-spirv/lib/SPIRV/SPIRVLowerConstExpr.cpp index d15345d665171..205d313515671 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVLowerConstExpr.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVLowerConstExpr.cpp @@ -113,7 +113,6 @@ bool SPIRVLowerConstExpr::runOnModule(Module &Module) { void SPIRVLowerConstExpr::visit(Module *M) { for (auto &I : M->functions()) { - std::map CMap; std::list WorkList; for (auto &BI : I) { for (auto &II : BI) { @@ -124,7 +123,10 @@ void SPIRVLowerConstExpr::visit(Module *M) { while (!WorkList.empty()) { auto II = WorkList.front(); - auto LowerOp = [&II, &FBegin, &I](ConstantExpr *CE) { + auto LowerOp = [&II, &FBegin, &I](Value *V) -> Value * { + if (isa(V)) + return V; + auto *CE = cast(V); SPIRVDBG(dbgs() << "[lowerConstantExpressions] " << *CE;) auto ReplInst = CE->getAsInstruction(); auto InsPoint = II->getParent() == &*FBegin ? II : &FBegin->back(); @@ -149,25 +151,30 @@ void SPIRVLowerConstExpr::visit(Module *M) { for (unsigned OI = 0, OE = II->getNumOperands(); OI != OE; ++OI) { auto Op = II->getOperand(OI); auto *Vec = dyn_cast(Op); - if (Vec && std::all_of(Vec->op_begin(), Vec->op_end(), - [](Value *V) { return isa(V); })) { + if (Vec && std::all_of(Vec->op_begin(), Vec->op_end(), [](Value *V) { + return isa(V) || isa(V); + })) { // Expand a vector of constexprs and construct it back with series of // insertelement instructions - std::list ReplList; - std::transform( - Vec->op_begin(), Vec->op_end(), std::back_inserter(ReplList), - [LowerOp](Value *V) { return LowerOp(cast(V)); }); + std::list OpList; + std::transform(Vec->op_begin(), Vec->op_end(), + std::back_inserter(OpList), + [LowerOp](Value *V) { return LowerOp(V); }); Value *Repl = nullptr; unsigned Idx = 0; - for (auto V : ReplList) + std::list ReplList; + for (auto V : OpList) { + if (auto *Inst = dyn_cast(V)) + ReplList.push_back(Inst); Repl = InsertElementInst::Create( (Repl ? Repl : UndefValue::get(Vec->getType())), V, ConstantInt::get(Type::getInt32Ty(M->getContext()), Idx++), "", II); + } II->replaceUsesOfWith(Op, Repl); WorkList.splice(WorkList.begin(), ReplList); } else if (auto CE = dyn_cast(Op)) - WorkList.push_front(LowerOp(CE)); + WorkList.push_front(cast(LowerOp(CE))); } } } diff --git a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp index b19a11665e740..f85c53166536e 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp @@ -1302,13 +1302,22 @@ SPIRVValue *LLVMToSPIRV::transValueWithoutDecoration(Value *V, if (auto Ins = dyn_cast(V)) { auto Index = Ins->getOperand(2); - if (auto Const = dyn_cast(Index)) + if (auto Const = dyn_cast(Index)) { + SPIRVValue *InsVal = nullptr; + if (auto *F = dyn_cast(Ins->getOperand(1))) { + if (!BM->checkExtension(ExtensionID::SPV_INTEL_function_pointers, + SPIRVEC_FunctionPointers, toString(V))) + return nullptr; + InsVal = BM->addFunctionPointerINTELInst( + transType(F->getType()), + static_cast(transValue(F, BB)), BB); + } else + InsVal = transValue(Ins->getOperand(1), BB); return mapValue(V, BM->addCompositeInsertInst( - transValue(Ins->getOperand(1), BB), - transValue(Ins->getOperand(0), BB), + InsVal, transValue(Ins->getOperand(0), BB), std::vector(1, Const->getZExtValue()), BB)); - else + } else return mapValue( V, BM->addVectorInsertDynamicInst(transValue(Ins->getOperand(0), BB), transValue(Ins->getOperand(1), BB), diff --git a/llvm-spirv/test/constexpr_vector.ll b/llvm-spirv/test/constexpr_vector.ll index 72f0ba9600891..a3c1170177e0d 100644 --- a/llvm-spirv/test/constexpr_vector.ll +++ b/llvm-spirv/test/constexpr_vector.ll @@ -1,8 +1,7 @@ ; RUN: llvm-as < %s | llvm-spirv -s | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM ; CHECK-LLVM: define dllexport void @vadd() { -; CHECK-LLVM-NEXT: entry: -; CHECK-LLVM-NEXT: %Funcs = alloca <16 x i8>, align 16 +; CHECK-LLVM: %Funcs = alloca <16 x i8>, align 16 ; CHECK-LLVM-NEXT: %0 = ptrtoint i32 (i32)* @_Z2f1u2CMvb32_j to i64 ; CHECK-LLVM-NEXT: %1 = bitcast i64 %0 to <8 x i8> ; CHECK-LLVM-NEXT: %2 = extractelement <8 x i8> %1, i32 0 @@ -40,8 +39,12 @@ ; CHECK-LLVM-NEXT: %34 = insertelement <16 x i8> %33, i8 %18, i32 14 ; CHECK-LLVM-NEXT: %35 = insertelement <16 x i8> %34, i8 %19, i32 15 ; CHECK-LLVM-NEXT: store <16 x i8> %35, <16 x i8>* %Funcs, align 16 -; CHECK-LLVM-NEXT: ret void -; CHECK-LLVM-NEXT: } +; CHECK-LLVM: %Funcs1 = alloca <2 x i64>, align 16 +; CHECK-LLVM-NEXT: %36 = ptrtoint i32 (i32)* @_Z2f1u2CMvb32_j to i64 +; CHECK-LLVM-NEXT: %37 = ptrtoint i32 (i32)* @_Z2f2u2CMvb32_j to i64 +; CHECK-LLVM-NEXT: %38 = insertelement <2 x i64> undef, i64 %36, i32 0 +; CHECK-LLVM-NEXT: %39 = insertelement <2 x i64> %38, i64 %37, i32 1 +; CHECK-LLVM-NEXT: store <2 x i64> %39, <2 x i64>* %Funcs1, align 16 ; RUN: llvm-as < %s | llvm-spirv -spirv-text --spirv-ext=+SPV_INTEL_function_pointers | FileCheck %s --check-prefix=CHECK-SPIRV @@ -115,5 +118,7 @@ define dllexport void @vadd() { entry: %Funcs = alloca <16 x i8>, align 16 store <16 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 0), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 1), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 2), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 3), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 4), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 5), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 6), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f1u2CMvb32_j to i64) to <8 x i8>), i32 7), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 0), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 1), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 2), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 3), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 4), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 5), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 6), i8 extractelement (<8 x i8> bitcast (i64 ptrtoint (i32 (i32)* @_Z2f2u2CMvb32_j to i64) to <8 x i8>), i32 7)>, <16 x i8>* %Funcs, align 16 + %Funcs1 = alloca <2 x i64>, align 16 + store <2 x i64> , <2 x i64>* %Funcs1, align 16 ret void } diff --git a/llvm-spirv/test/transcoding/SPV_INTEL_function_pointers/vector_elem.ll b/llvm-spirv/test/transcoding/SPV_INTEL_function_pointers/vector_elem.ll new file mode 100644 index 0000000000000..f9d9d60e19328 --- /dev/null +++ b/llvm-spirv/test/transcoding/SPV_INTEL_function_pointers/vector_elem.ll @@ -0,0 +1,42 @@ +; RUN: llvm-as < %s | llvm-spirv -spirv-text --spirv-ext=+SPV_INTEL_function_pointers | FileCheck %s --check-prefix=CHECK-SPIRV + +; CHECK-SPIRV-DAG: 6 Name [[F1:[0-9+]]] "_Z2f1u2CMvb32_j" +; CHECK-SPIRV-DAG: 6 Name [[F2:[0-9+]]] "_Z2f2u2CMvb32_j" +; CHECK-SPIRV-DAG: 4 Name [[Funcs:[0-9]+]] "Funcs" + +; CHECK-SPIRV: 4 TypeInt [[TypeInt32:[0-9]+]] 32 0 +; CHECK-SPIRV: 4 TypeFunction [[TypeFunc:[0-9]+]] [[TypeInt32]] [[TypeInt32]] +; CHECK-SPIRV: 4 TypePointer [[TypePtr:[0-9]+]] {{[0-9]+}} [[TypeFunc]] +; CHECK-SPIRV: 4 TypeVector [[TypeVec:[0-9]+]] [[TypePtr]] [[TypeInt32]] +; CHECK-SPIRV: 3 Undef [[TypeVec]] [[TypeUndef:[0-9]+]] + +; CHECK-SPIRV: 4 FunctionPointerINTEL [[TypePtr]] [[F1Ptr:[0-9]+]] [[F1]] +; CHECK-SPIRV: 6 CompositeInsert [[TypeVec]] [[NewVec0:[0-9]+]] [[F1Ptr]] [[TypeUndef]] 0 +; CHECK-SPIRV: 4 FunctionPointerINTEL [[TypePtr]] [[F2Ptr:[0-9]+]] [[F2]] +; CHECK-SPIRV: 6 CompositeInsert [[TypeVec]] [[NewVec1:[0-9]+]] [[F2Ptr]] [[NewVec0]] 1 +; CHECK-SPIRV: 5 Store [[Funcs]] [[NewVec1]] [[TypeInt32]] {{[0-9+]}} + + +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" +target triple = "spir-unknown-unknown" + +; Function Attrs: noinline norecurse nounwind readnone +define internal i32 @_Z2f1u2CMvb32_j(i32 %x) { +entry: + ret i32 %x +} +; Function Attrs: noinline norecurse nounwind readnone +define internal i32 @_Z2f2u2CMvb32_j(i32 %x) { +entry: + ret i32 %x +} + +; Function Attrs: noinline nounwind +define dllexport void @vadd() { +entry: + %Funcs = alloca <2 x i32 (i32)*>, align 16 + %0 = insertelement <2 x i32 (i32)*> undef, i32 (i32)* @_Z2f1u2CMvb32_j, i32 0 + %1 = insertelement <2 x i32 (i32)*> %0, i32 (i32)* @_Z2f2u2CMvb32_j, i32 1 + store <2 x i32 (i32)*> %1, <2 x i32 (i32)*>* %Funcs, align 16 + ret void +} From bb676bff14982b91e52c7ba57d94211f6604af9b Mon Sep 17 00:00:00 2001 From: nrudenko Date: Wed, 29 Apr 2020 16:52:44 +0300 Subject: [PATCH 2/6] Add infrastructure for SPV_INTEL_float_controls2 extension Extension is published at https://github.com/intel/llvm/pull/1611 --- llvm-spirv/include/LLVMSPIRVExtensions.inc | 1 + llvm-spirv/lib/SPIRV/SPIRVWriter.cpp | 12 +++ llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp | 4 + llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h | 19 ++++- llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h | 8 ++ .../lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h | 6 ++ .../lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 6 ++ llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp | 6 ++ .../test/exec_mode_float_control_intel.ll | 80 +++++++++++++++++++ 9 files changed, 138 insertions(+), 4 deletions(-) create mode 100755 llvm-spirv/test/exec_mode_float_control_intel.ll diff --git a/llvm-spirv/include/LLVMSPIRVExtensions.inc b/llvm-spirv/include/LLVMSPIRVExtensions.inc index a0cbcd97aa57f..da45e25d2953e 100644 --- a/llvm-spirv/include/LLVMSPIRVExtensions.inc +++ b/llvm-spirv/include/LLVMSPIRVExtensions.inc @@ -19,3 +19,4 @@ EXT(SPV_INTEL_io_pipes) EXT(SPV_INTEL_inline_assembly) EXT(SPV_INTEL_arbitrary_precision_integers) EXT(SPV_INTEL_optimization_hints) +EXT(SPV_INTEL_float_controls2) diff --git a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp index f85c53166536e..54d5db0ce9532 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp @@ -2541,6 +2541,18 @@ bool LLVMToSPIRV::transExecutionMode() { BF->addExecutionMode(BM->add(new SPIRVExecutionMode( BF, static_cast(EMode), TargetWidth))); } break; + case spv::ExecutionModeRoundingModeRTPINTEL: + case spv::ExecutionModeRoundingModeRTNINTEL: + case spv::ExecutionModeFloatingPointModeALTINTEL: + case spv::ExecutionModeFloatingPointModeIEEEINTEL: { + if (!BM->isAllowedToUseExtension( + ExtensionID::SPV_INTEL_float_controls2)) + break; + unsigned TargetWidth; + N.get(TargetWidth); + BF->addExecutionMode(BM->add(new SPIRVExecutionMode( + BF, static_cast(EMode), TargetWidth))); + } break; default: llvm_unreachable("invalid execution mode"); } diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp index d5609726be143..9015ff869617e 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp @@ -487,6 +487,10 @@ void SPIRVExecutionMode::decode(std::istream &I) { case ExecutionModeSignedZeroInfNanPreserve: case ExecutionModeRoundingModeRTE: case ExecutionModeRoundingModeRTZ: + case ExecutionModeRoundingModeRTPINTEL: + case ExecutionModeRoundingModeRTNINTEL: + case ExecutionModeFloatingPointModeALTINTEL: + case ExecutionModeFloatingPointModeIEEEINTEL: case ExecutionModeSubgroupSize: case ExecutionModeMaxWorkDimINTEL: case ExecutionModeNumSIMDWorkitemsINTEL: diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h index a734f10379290..0f1f976313414 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h @@ -674,7 +674,7 @@ class SPIRVComponentExecutionModes { public: void addExecutionMode(SPIRVExecutionMode *ExecMode) { // There should not be more than 1 execution mode kind except the ones - // mentioned in SPV_KHR_float_controls. + // mentioned in SPV_KHR_float_controls and SPV_INTEL_float_controls2. #ifndef NDEBUG auto IsDenorm = [](auto EMK) { return EMK == ExecutionModeDenormPreserve || @@ -682,13 +682,20 @@ class SPIRVComponentExecutionModes { }; auto IsRoundingMode = [](auto EMK) { return EMK == ExecutionModeRoundingModeRTE || - EMK == ExecutionModeRoundingModeRTZ; + EMK == ExecutionModeRoundingModeRTZ || + EMK == ExecutionModeRoundingModeRTPINTEL || + EMK == ExecutionModeRoundingModeRTNINTEL; + }; + auto IsFPMode = [](auto EMK) { + return EMK == ExecutionModeFloatingPointModeALTINTEL || + EMK == ExecutionModeFloatingPointModeIEEEINTEL; }; auto IsOtherFP = [](auto EMK) { return EMK == ExecutionModeSignedZeroInfNanPreserve; }; auto IsFloatControl = [&](auto EMK) { - return IsDenorm(EMK) || IsRoundingMode(EMK) || IsOtherFP(EMK); + return IsDenorm(EMK) || IsRoundingMode(EMK) || IsFPMode(EMK) || + IsOtherFP(EMK); }; auto IsCompatible = [&](SPIRVExecutionMode *EM0, SPIRVExecutionMode *EM1) { if (EM0->getTargetId() != EM1->getTargetId()) @@ -702,7 +709,8 @@ class SPIRVComponentExecutionModes { if (TW0 != TW1) return true; return !(IsDenorm(EMK0) && IsDenorm(EMK1)) && - !(IsRoundingMode(EMK0) && IsRoundingMode(EMK1)); + !(IsRoundingMode(EMK0) && IsRoundingMode(EMK1)) && + !(IsFPMode(EMK0) && IsFPMode(EMK1)); }; for (auto I = ExecModes.begin(); I != ExecModes.end(); ++I) { assert(IsCompatible(ExecMode, (*I).second) && @@ -814,6 +822,9 @@ class SPIRVCapability : public SPIRVEntryNoId { case CapabilityRoundingModeRTE: case CapabilityRoundingModeRTZ: return getSet(ExtensionID::SPV_KHR_float_controls); + case CapabilityRoundToInfinityINTEL: + case CapabilityFloatingPointModeINTEL: + return getSet(ExtensionID::SPV_INTEL_float_controls2); default: return SPIRVExtSet(); } diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h index 6d24877a0230c..53a79e561450a 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h @@ -244,6 +244,14 @@ template <> inline void SPIRVMap::init() { {CapabilitySignedZeroInfNanPreserve}); ADD_VEC_INIT(ExecutionModeRoundingModeRTE, {CapabilityRoundingModeRTE}); ADD_VEC_INIT(ExecutionModeRoundingModeRTZ, {CapabilityRoundingModeRTZ}); + ADD_VEC_INIT(ExecutionModeRoundingModeRTPINTEL, + {CapabilityRoundToInfinityINTEL}); + ADD_VEC_INIT(ExecutionModeRoundingModeRTNINTEL, + {CapabilityRoundToInfinityINTEL}); + ADD_VEC_INIT(ExecutionModeFloatingPointModeALTINTEL, + {CapabilityFloatingPointModeINTEL}); + ADD_VEC_INIT(ExecutionModeFloatingPointModeIEEEINTEL, + {CapabilityFloatingPointModeINTEL}); } template <> inline void SPIRVMap::init() { diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h index 3db6bb9f8a59f..1180a0daeefac 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h @@ -149,6 +149,10 @@ inline bool isValid(spv::ExecutionMode V) { case ExecutionModeSignedZeroInfNanPreserve: case ExecutionModeRoundingModeRTE: case ExecutionModeRoundingModeRTZ: + case ExecutionModeRoundingModeRTPINTEL: + case ExecutionModeRoundingModeRTNINTEL: + case ExecutionModeFloatingPointModeALTINTEL: + case ExecutionModeFloatingPointModeIEEEINTEL: return true; default: return false; @@ -586,6 +590,8 @@ inline bool isValid(spv::Capability V) { case CapabilitySignedZeroInfNanPreserve: case CapabilityRoundingModeRTE: case CapabilityRoundingModeRTZ: + case CapabilityRoundToInfinityINTEL: + case CapabilityFloatingPointModeINTEL: case CapabilityFPGAMemoryAttributesINTEL: case CapabilityArbitraryPrecisionIntegersINTEL: case CapabilityFPGALoopControlsINTEL: diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index 0a62838dff765..4c8c3da301de1 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -128,6 +128,10 @@ template <> inline void SPIRVMap::init() { add(ExecutionModeSignedZeroInfNanPreserve, "SignedZeroInfNanPreserve"); add(ExecutionModeRoundingModeRTE, "RoundingModeRTE"); add(ExecutionModeRoundingModeRTZ, "RoundingModeRTZ"); + add(ExecutionModeRoundingModeRTPINTEL, "RoundingModeRTPINTEL"); + add(ExecutionModeRoundingModeRTNINTEL, "RoundingModeRTNINTEL"); + add(ExecutionModeFloatingPointModeALTINTEL, "FloatingPointModeALTINTEL"); + add(ExecutionModeFloatingPointModeIEEEINTEL, "FloatingPointModeIEEEINTEL"); } SPIRV_DEF_NAMEMAP(ExecutionMode, SPIRVExecutionModeNameMap) @@ -507,6 +511,8 @@ template <> inline void SPIRVMap::init() { add(CapabilitySubgroupImageMediaBlockIOINTEL, "SubgroupImageMediaBlockIOINTEL"); add(CapabilityAsmINTEL, "AsmINTEL"); + add(CapabilityRoundToInfinityINTEL, "RoundToInfinityINTEL"); + add(CapabilityFloatingPointModeINTEL, "FloatingPointModeINTEL"); add(CapabilitySubgroupAvcMotionEstimationINTEL, "SubgroupAvcMotionEstimationINTEL"); add(CapabilitySubgroupAvcMotionEstimationIntraINTEL, diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp b/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp index cb4cacb7c0c61..760295ccf31bf 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp +++ b/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp @@ -162,6 +162,10 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, ExecutionModeMaxWorkgroupSizeINTEL = 5893, ExecutionModeMaxWorkDimINTEL = 5894, ExecutionModeNoGlobalOffsetINTEL = 5895, @@ -931,6 +935,8 @@ enum Capability { CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, CapabilityFPGAMemoryAttributesINTEL = 5824, CapabilityArbitraryPrecisionIntegersINTEL = 5844, CapabilityUnstructuredLoopControlsINTEL = 5886, diff --git a/llvm-spirv/test/exec_mode_float_control_intel.ll b/llvm-spirv/test/exec_mode_float_control_intel.ll new file mode 100755 index 0000000000000..bebbb38f0468b --- /dev/null +++ b/llvm-spirv/test/exec_mode_float_control_intel.ll @@ -0,0 +1,80 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_float_controls2 +; RUN: llvm-spirv %t.spv -o %t.spt --to-text +; RUN: FileCheck %s --input-file %t.spt -check-prefix=SPV + +; ModuleID = 'float_control.bc' +source_filename = "float_control.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_float_controls_0(i32 %ibuf, i32 %obuf) local_unnamed_addr { +entry: + ret void +} + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_float_controls_1(i32 %ibuf, i32 %obuf) local_unnamed_addr { +entry: + ret void +} + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_float_controls_2(i32 %ibuf, i32 %obuf) local_unnamed_addr { +entry: + ret void +} + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_float_controls_3(i32 %ibuf, i32 %obuf) local_unnamed_addr { +entry: + ret void +} + + +!llvm.module.flags = !{!12} +!llvm.ident = !{!13} +!spirv.EntryPoint = !{} +!spirv.ExecutionMode = !{!15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26} + +; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL0:[0-9]+]] "k_float_controls_0" +; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL1:[0-9]+]] "k_float_controls_1" +; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL2:[0-9]+]] "k_float_controls_2" +; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL3:[0-9]+]] "k_float_controls_3" +!0 = !{void (i32, i32)* @k_float_controls_0, !"k_float_controls_0", !1, i32 0, !2, !3, !4, i32 0, i32 0} +!1 = !{i32 2, i32 2} +!2 = !{i32 32, i32 36} +!3 = !{i32 0, i32 0} +!4 = !{!"", !""} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.1"} +!14 = !{i32 1, i32 0} + +; SPV-DAG: ExecutionMode [[KERNEL0]] 5620 64 +!15 = !{void (i32, i32)* @k_float_controls_0, i32 5620, i32 64} +; SPV-DAG: ExecutionMode [[KERNEL0]] 5620 32 +!16 = !{void (i32, i32)* @k_float_controls_0, i32 5620, i32 32} +; SPV-DAG: ExecutionMode [[KERNEL0]] 5620 16 +!17 = !{void (i32, i32)* @k_float_controls_0, i32 5620, i32 16} + +; SPV-DAG: ExecutionMode [[KERNEL1]] 5621 64 +!18 = !{void (i32, i32)* @k_float_controls_1, i32 5621, i32 64} +; SPV-DAG: ExecutionMode [[KERNEL1]] 5621 32 +!19 = !{void (i32, i32)* @k_float_controls_1, i32 5621, i32 32} +; SPV-DAG: ExecutionMode [[KERNEL1]] 5621 16 +!20 = !{void (i32, i32)* @k_float_controls_1, i32 5621, i32 16} + +; SPV-DAG: ExecutionMode [[KERNEL2]] 5622 64 +!21 = !{void (i32, i32)* @k_float_controls_2, i32 5622, i32 64} +; SPV-DAG: ExecutionMode [[KERNEL2]] 5622 32 +!22 = !{void (i32, i32)* @k_float_controls_2, i32 5622, i32 32} +; SPV-DAG: ExecutionMode [[KERNEL2]] 5622 16 +!23 = !{void (i32, i32)* @k_float_controls_2, i32 5622, i32 16} + +; SPV-DAG: ExecutionMode [[KERNEL3]] 5623 64 +!24 = !{void (i32, i32)* @k_float_controls_3, i32 5623, i32 64} +; SPV-DAG: ExecutionMode [[KERNEL3]] 5623 32 +!25 = !{void (i32, i32)* @k_float_controls_3, i32 5623, i32 32} +; SPV-DAG: ExecutionMode [[KERNEL3]] 5623 16 +!26 = !{void (i32, i32)* @k_float_controls_3, i32 5623, i32 16} From ba7d1748c9a9cd8125d698eb5c27e47e1ed62278 Mon Sep 17 00:00:00 2001 From: nrudenko Date: Fri, 21 Feb 2020 17:06:56 +0300 Subject: [PATCH 3/6] Add infrastructure for SPV_INTEL_vector_compute extension Extension is published at https://github.com/intel/llvm/pull/1612 Co-Authored-By: Aleksandr Bezzubikov Co-Authored-By: Aleksander Us Co-Authored-By: Alexey Sachkov Co-Authored-By: Alexey Sotkin Co-Authored-By: Anton Sidorenko Co-Authored-By: Gang Chen Co-Authored-By: Kai Chen Co-Authored-By: Konstantin Vladimirov Co-Authored-By: Wei Pan Change-Id: Ic8bd645316f054729b8571efd2b9800a38cb723c --- llvm-spirv/include/LLVMSPIRVExtensions.inc | 1 + llvm-spirv/lib/SPIRV/SPIRVWriter.cpp | 8 ++++++++ llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp | 1 + llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h | 6 +++++- llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h | 13 ++++++++++++- llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h | 8 ++++++++ llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 8 ++++++++ llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.h | 14 ++++++++++++-- llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp | 8 ++++++++ 9 files changed, 63 insertions(+), 4 deletions(-) diff --git a/llvm-spirv/include/LLVMSPIRVExtensions.inc b/llvm-spirv/include/LLVMSPIRVExtensions.inc index da45e25d2953e..a3660d4452a3c 100644 --- a/llvm-spirv/include/LLVMSPIRVExtensions.inc +++ b/llvm-spirv/include/LLVMSPIRVExtensions.inc @@ -20,3 +20,4 @@ EXT(SPV_INTEL_inline_assembly) EXT(SPV_INTEL_arbitrary_precision_integers) EXT(SPV_INTEL_optimization_hints) EXT(SPV_INTEL_float_controls2) +EXT(SPV_INTEL_vector_compute) diff --git a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp index 54d5db0ce9532..993c1be4d9cb9 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp @@ -2528,6 +2528,14 @@ bool LLVMToSPIRV::transExecutionMode() { BM->addCapability(CapabilityFPGAKernelAttributesINTEL); } } break; + case spv::ExecutionModeSharedLocalMemorySizeINTEL: { + if (!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) + break; + unsigned SLMSize; + N.get(SLMSize); + BF->addExecutionMode(new SPIRVExecutionMode( + BF, static_cast(EMode), SLMSize)); + } break; case spv::ExecutionModeDenormPreserve: case spv::ExecutionModeDenormFlushToZero: diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp index 9015ff869617e..a5f972d0ed65e 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.cpp @@ -491,6 +491,7 @@ void SPIRVExecutionMode::decode(std::istream &I) { case ExecutionModeRoundingModeRTNINTEL: case ExecutionModeFloatingPointModeALTINTEL: case ExecutionModeFloatingPointModeIEEEINTEL: + case ExecutionModeSharedLocalMemorySizeINTEL: case ExecutionModeSubgroupSize: case ExecutionModeMaxWorkDimINTEL: case ExecutionModeNumSIMDWorkitemsINTEL: diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h index 0f1f976313414..0a0dec6a0e137 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h @@ -503,7 +503,8 @@ class SPIRVEntryPoint : public SPIRVAnnotation { SPIRVEntryPoint(SPIRVModule *TheModule, SPIRVExecutionModelKind, SPIRVId TheId, const std::string &TheName, std::vector Variables); - SPIRVEntryPoint() : ExecModel(ExecutionModelKernel) {} + SPIRVEntryPoint() {} + _SPIRV_DCL_ENCDEC protected: SPIRVExecutionModelKind ExecModel; @@ -825,6 +826,9 @@ class SPIRVCapability : public SPIRVEntryNoId { case CapabilityRoundToInfinityINTEL: case CapabilityFloatingPointModeINTEL: return getSet(ExtensionID::SPV_INTEL_float_controls2); + case CapabilityVectorComputeINTEL: + case CapabilityVectorAnyINTEL: + return getSet(ExtensionID::SPV_INTEL_vector_compute); default: return SPIRVExtSet(); } diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h index 53a79e561450a..163242abd26f9 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEnum.h @@ -252,6 +252,8 @@ template <> inline void SPIRVMap::init() { {CapabilityFloatingPointModeINTEL}); ADD_VEC_INIT(ExecutionModeFloatingPointModeIEEEINTEL, {CapabilityFloatingPointModeINTEL}); + ADD_VEC_INIT(ExecutionModeSharedLocalMemorySizeINTEL, + {CapabilityVectorComputeINTEL}); } template <> inline void SPIRVMap::init() { @@ -263,7 +265,8 @@ template <> inline void SPIRVMap::init() { template <> inline void SPIRVMap::init() { ADD_VEC_INIT(StorageClassUniform, {CapabilityShader}); ADD_VEC_INIT(StorageClassOutput, {CapabilityShader}); - ADD_VEC_INIT(StorageClassPrivate, {CapabilityShader}); + ADD_VEC_INIT(StorageClassPrivate, + {CapabilityShader, CapabilityVectorComputeINTEL}); ADD_VEC_INIT(StorageClassGeneric, {CapabilityGenericPointer}); ADD_VEC_INIT(StorageClassPushConstant, {CapabilityShader}); ADD_VEC_INIT(StorageClassAtomicCounter, {CapabilityAtomicStorage}); @@ -384,6 +387,14 @@ template <> inline void SPIRVMap::init() { {CapabilityIndirectReferencesINTEL}); ADD_VEC_INIT(DecorationIOPipeStorageINTEL, {CapabilityIOPipeINTEL}); ADD_VEC_INIT(DecorationSideEffectsINTEL, {CapabilityAsmINTEL}); + ADD_VEC_INIT(DecorationVectorComputeFunctionINTEL, + {CapabilityVectorComputeINTEL}); + ADD_VEC_INIT(DecorationVectorComputeVariableINTEL, + {CapabilityVectorComputeINTEL}); + ADD_VEC_INIT(DecorationGlobalVariableOffsetINTEL, + {CapabilityVectorComputeINTEL}); + ADD_VEC_INIT(DecorationFuncParamIOKind, {CapabilityVectorComputeINTEL}); + ADD_VEC_INIT(DecorationStackCallINTEL, {CapabilityVectorComputeINTEL}); } template <> inline void SPIRVMap::init() { diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h index 1180a0daeefac..d8451aec91121 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h @@ -153,6 +153,7 @@ inline bool isValid(spv::ExecutionMode V) { case ExecutionModeRoundingModeRTNINTEL: case ExecutionModeFloatingPointModeALTINTEL: case ExecutionModeFloatingPointModeIEEEINTEL: + case ExecutionModeSharedLocalMemorySizeINTEL: return true; default: return false; @@ -421,6 +422,11 @@ inline bool isValid(spv::Decoration V) { case DecorationBankBitsINTEL: case DecorationForcePow2DepthINTEL: case DecorationReferencedIndirectlyINTEL: + case DecorationVectorComputeFunctionINTEL: + case DecorationStackCallINTEL: + case DecorationVectorComputeVariableINTEL: + case DecorationGlobalVariableOffsetINTEL: + case DecorationFuncParamIOKind: return true; default: return false; @@ -592,6 +598,8 @@ inline bool isValid(spv::Capability V) { case CapabilityRoundingModeRTZ: case CapabilityRoundToInfinityINTEL: case CapabilityFloatingPointModeINTEL: + case CapabilityVectorComputeINTEL: + case CapabilityVectorAnyINTEL: case CapabilityFPGAMemoryAttributesINTEL: case CapabilityArbitraryPrecisionIntegersINTEL: case CapabilityFPGALoopControlsINTEL: diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index 4c8c3da301de1..d9606705107e0 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -132,6 +132,7 @@ template <> inline void SPIRVMap::init() { add(ExecutionModeRoundingModeRTNINTEL, "RoundingModeRTNINTEL"); add(ExecutionModeFloatingPointModeALTINTEL, "FloatingPointModeALTINTEL"); add(ExecutionModeFloatingPointModeIEEEINTEL, "FloatingPointModeIEEEINTEL"); + add(ExecutionModeSharedLocalMemorySizeINTEL, "SharedLocalMemorySizeINTEL"); } SPIRV_DEF_NAMEMAP(ExecutionMode, SPIRVExecutionModeNameMap) @@ -360,6 +361,11 @@ template <> inline void SPIRVMap::init() { add(DecorationForcePow2DepthINTEL, "ForcePow2DepthINTEL"); add(DecorationReferencedIndirectlyINTEL, "ReferencedIndirectlyINTEL"); add(DecorationIOPipeStorageINTEL, "IOPipeStorageINTEL"); + add(DecorationVectorComputeFunctionINTEL, "VectorComputeFunctionINTEL"); + add(DecorationStackCallINTEL, "StackCallINTEL"); + add(DecorationVectorComputeVariableINTEL, "VectorComputeVariableINTEL"); + add(DecorationGlobalVariableOffsetINTEL, "GlobalVariableOffsetINTEL"); + add(DecorationFuncParamIOKind, "FuncParamIOKind"); } SPIRV_DEF_NAMEMAP(Decoration, SPIRVDecorationNameMap) @@ -511,6 +517,8 @@ template <> inline void SPIRVMap::init() { add(CapabilitySubgroupImageMediaBlockIOINTEL, "SubgroupImageMediaBlockIOINTEL"); add(CapabilityAsmINTEL, "AsmINTEL"); + add(CapabilityVectorComputeINTEL, "VectorComputeINTEL"); + add(CapabilityVectorAnyINTEL, "VectorAnyINTEL"); add(CapabilityRoundToInfinityINTEL, "RoundToInfinityINTEL"); add(CapabilityFloatingPointModeINTEL, "FloatingPointModeINTEL"); add(CapabilitySubgroupAvcMotionEstimationINTEL, diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.h b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.h index 1ce1d3058fcf6..80b890c983e09 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.h +++ b/llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.h @@ -307,6 +307,11 @@ class SPIRVTypeVector : public SPIRVType { // usage of 8-component or 16-component vectors. if (CompCount == 8 || CompCount == 16) V.push_back(CapabilityVector16); + + if (Module->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) + if (CompCount == 1 || (CompCount > 4 && CompCount < 8) || + (CompCount > 8 && CompCount < 16) || CompCount > 16) + V.push_back(CapabilityVectorAnyINTEL); return V; } @@ -319,8 +324,13 @@ class SPIRVTypeVector : public SPIRVType { void validate() const override { SPIRVEntry::validate(); CompType->validate(); - assert(CompCount == 2 || CompCount == 3 || CompCount == 4 || - CompCount == 8 || CompCount == 16); +#ifndef NDEBUG + if (!(Module->isAllowedToUseExtension( + ExtensionID::SPV_INTEL_vector_compute))) { + assert(CompCount == 2 || CompCount == 3 || CompCount == 4 || + CompCount == 8 || CompCount == 16); + } +#endif // !NDEBUG } private: diff --git a/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp b/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp index 760295ccf31bf..e2d38f47311dd 100644 --- a/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp +++ b/llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp @@ -162,6 +162,7 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, ExecutionModeRoundingModeRTPINTEL = 5620, ExecutionModeRoundingModeRTNINTEL = 5621, ExecutionModeFloatingPointModeALTINTEL = 5622, @@ -476,6 +477,11 @@ enum Decoration { DecorationAliasedPointerEXT = 5356, DecorationReferencedIndirectlyINTEL = 5602, DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKind = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, @@ -931,6 +937,8 @@ enum Capability { CapabilityFunctionPointersINTEL = 5603, CapabilityIndirectReferencesINTEL = 5604, CapabilityAsmINTEL = 5606, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, CapabilityOptimizationHintsINTEL = 5629, CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, From 8c1416fd7e66c0a499829a4f54734c437d426390 Mon Sep 17 00:00:00 2001 From: nrudenko Date: Fri, 21 Feb 2020 17:06:56 +0300 Subject: [PATCH 4/6] Implementation of SPV_INTEL_vector_compute extension Backend part Extension is published at https://github.com/intel/llvm/pull/1612 Co-Authored-By: Aleksandr Bezzubikov Co-Authored-By: Aleksander Us Co-Authored-By: Alexey Sachkov Co-Authored-By: Alexey Sotkin Co-Authored-By: Anton Sidorenko Co-Authored-By: Gang Chen Co-Authored-By: Kai Chen Co-Authored-By: Konstantin Vladimirov Co-Authored-By: Wei Pan Change-Id: Ic8bd645316f054729b8571efd2b9800a38cb723c --- llvm-spirv/lib/SPIRV/CMakeLists.txt | 1 + llvm-spirv/lib/SPIRV/SPIRVReader.cpp | 100 ++++++++++++++++- llvm-spirv/lib/SPIRV/SPIRVReader.h | 1 + llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp | 99 ++++++++++++++++ llvm-spirv/lib/SPIRV/VectorComputeUtil.h | 125 +++++++++++++++++++++ 5 files changed, 322 insertions(+), 4 deletions(-) create mode 100755 llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp create mode 100755 llvm-spirv/lib/SPIRV/VectorComputeUtil.h diff --git a/llvm-spirv/lib/SPIRV/CMakeLists.txt b/llvm-spirv/lib/SPIRV/CMakeLists.txt index b9abb7ce5ef30..92ba12ae58199 100644 --- a/llvm-spirv/lib/SPIRV/CMakeLists.txt +++ b/llvm-spirv/lib/SPIRV/CMakeLists.txt @@ -8,6 +8,7 @@ add_llvm_library(LLVMSPIRVLib OCL21ToSPIRV.cpp OCLTypeToSPIRV.cpp OCLUtil.cpp + VectorComputeUtil.cpp SPIRVLowerBool.cpp SPIRVLowerConstExpr.cpp SPIRVLowerMemmove.cpp diff --git a/llvm-spirv/lib/SPIRV/SPIRVReader.cpp b/llvm-spirv/lib/SPIRV/SPIRVReader.cpp index d0c8a8ea64b10..4bbb7fa80b193 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVReader.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVReader.cpp @@ -50,6 +50,7 @@ #include "SPIRVType.h" #include "SPIRVUtil.h" #include "SPIRVValue.h" +#include "VectorComputeUtil.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Analysis/LoopInfo.h" @@ -108,7 +109,7 @@ const static char *Restrict = "restrict"; const static char *Pipe = "pipe"; } // namespace kOCLTypeQualifierName -static bool isOpenCLKernel(SPIRVFunction *BF) { +static bool isKernel(SPIRVFunction *BF) { return BF->getModule()->isEntryPoint(ExecutionModelKernel, BF->getId()); } @@ -1530,7 +1531,17 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, assert(BB && "Invalid BB"); return mapValue(BV, new AllocaInst(Ty, 0, BV->getName(), BB)); } - auto AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(BS); + SPIRAddressSpace AddrSpace; + + bool IsVectorCompute = + BVar->hasDecorate(DecorationVectorComputeVariableINTEL); + if (IsVectorCompute) { + AddrSpace = VectorComputeUtil::getVCGlobalVarAddressSpace(BS); + if (!Initializer) + Initializer = UndefValue::get(Ty); + } else + AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(BS); + auto LVar = new GlobalVariable(*M, Ty, IsConst, LinkageTy, Initializer, BV->getName(), 0, GlobalVariable::NotThreadLocal, AddrSpace); @@ -1538,6 +1549,16 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, Ty->getArrayElementType()->isIntegerTy(8)) ? GlobalValue::UnnamedAddr::Global : GlobalValue::UnnamedAddr::None); + + if (IsVectorCompute) { + LVar->addAttribute(kVCMetadata::VCGlobalVariable); + SPIRVWord Offset; + if (BVar->hasDecorate(DecorationGlobalVariableOffsetINTEL, 0, &Offset)) + LVar->addAttribute(kVCMetadata::VCByteOffset, utostr(Offset)); + if (BVar->hasDecorate(DecorationVolatile)) + LVar->addAttribute(kVCMetadata::VCVolatile); + } + SPIRVBuiltinVariableKind BVKind; if (BVar->isBuiltin(&BVKind)) BuiltinGVMap[LVar] = BVKind; @@ -2404,7 +2425,7 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) { if (Loc != FuncMap.end()) return Loc->second; - auto IsKernel = BM->isEntryPoint(ExecutionModelKernel, BF->getId()); + auto IsKernel = isKernel(BF); auto Linkage = IsKernel ? GlobalValue::ExternalLinkage : transLinkageType(BF); FunctionType *FT = dyn_cast(transType(BF->getFunctionType())); Function *F = cast( @@ -3218,7 +3239,7 @@ bool SPIRVToLLVM::transFPContractMetadata() { bool ContractOff = false; for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) { SPIRVFunction *BF = BM->getFunction(I); - if (!isOpenCLKernel(BF)) + if (!isKernel(BF)) continue; if (BF->getExecutionMode(ExecutionModeContractionOff)) { ContractOff = true; @@ -3296,6 +3317,7 @@ bool SPIRVToLLVM::transMetadata() { assert(F && "Invalid translated function"); transOCLMetadata(BF); + transVectorComputeMetadata(BF); if (F->getCallingConv() != CallingConv::SPIR_KERNEL) continue; @@ -3436,6 +3458,76 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) { return true; } +bool SPIRVToLLVM::transVectorComputeMetadata(SPIRVFunction *BF) { + using namespace VectorComputeUtil; + Function *F = static_cast(getTranslatedValue(BF)); + assert(F && "Invalid translated function"); + + if (BF->hasDecorate(DecorationStackCallINTEL)) + F->addFnAttr(kVCMetadata::VCStackCall); + + bool IsVectorCompute = BF->hasDecorate(DecorationVectorComputeFunctionINTEL); + if (!IsVectorCompute) + return true; + F->addFnAttr(kVCMetadata::VCFunction); + + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; + ++I) { + auto ArgNo = I->getArgNo(); + SPIRVFunctionParameter *BA = BF->getArgument(ArgNo); + SPIRVWord Kind; + if (BA->hasDecorate(DecorationFuncParamIOKind, 0, &Kind)) { + Attribute Attr = Attribute::get(*Context, kVCMetadata::VCArgumentIOKind, + std::to_string(Kind)); + F->addAttribute(ArgNo + 1, Attr); + } + } + + // Do not add float control if there is no any + bool IsVCFloatControl = false; + unsigned FloatControl = 0; + // RoundMode and FloatMode are always same for all types in Cm + // While Denorm could be different for double, float and half + VCRoundModeExecModeMap::foreach ([&](VCRoundMode VCRM, ExecutionMode EM) { + if (BF->getExecutionMode(EM)) { + IsVCFloatControl = true; + FloatControl |= getVCFloatControl(VCRM); + } + }); + VCFloatModeExecModeMap::foreach ([&](VCFloatMode VCFM, ExecutionMode EM) { + if (BF->getExecutionMode(EM)) { + IsVCFloatControl = true; + FloatControl |= getVCFloatControl(VCFM); + } + }); + VCDenormModeExecModeMap::foreach ([&](VCDenormMode VCDM, ExecutionMode EM) { + auto ExecModes = BF->getExecutionModeRange(EM); + for (auto It = ExecModes.first; It != ExecModes.second; It++) { + IsVCFloatControl = true; + unsigned TargetWidth = (*It).second->getLiterals()[0]; + VCFloatType FloatType = VCFloatTypeSizeMap::rmap(TargetWidth); + FloatControl |= getVCFloatControl(VCDM, FloatType); + } + }); + if (IsVCFloatControl) { + Attribute Attr = Attribute::get(*Context, kVCMetadata::VCFloatControl, + std::to_string(FloatControl)); + F->addAttribute(AttributeList::FunctionIndex, Attr); + } + + if (auto EM = BF->getExecutionMode(ExecutionModeSharedLocalMemorySizeINTEL)) { + unsigned int SLMSize = EM->getLiterals()[0]; + Attribute Attr = Attribute::get(*Context, kVCMetadata::VCSLMSize, + std::to_string(SLMSize)); + F->addAttribute(AttributeList::FunctionIndex, Attr); + } + + if (F->getCallingConv() != CallingConv::SPIR_KERNEL) + return true; + + return true; +} + bool SPIRVToLLVM::transAlign(SPIRVValue *BV, Value *V) { if (auto AL = dyn_cast(V)) { SPIRVWord Align = 0; diff --git a/llvm-spirv/lib/SPIRV/SPIRVReader.h b/llvm-spirv/lib/SPIRV/SPIRVReader.h index 8c04eef7f5ee9..28571ab5ccca8 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVReader.h +++ b/llvm-spirv/lib/SPIRV/SPIRVReader.h @@ -104,6 +104,7 @@ class SPIRVToLLVM { bool transFPContractMetadata(); bool transMetadata(); bool transOCLMetadata(SPIRVFunction *BF); + bool transVectorComputeMetadata(SPIRVFunction *BF); Value *transAsmINTEL(SPIRVAsmINTEL *BA); CallInst *transAsmCallINTEL(SPIRVAsmCallINTEL *BI, Function *F, BasicBlock *BB); diff --git a/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp b/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp new file mode 100755 index 0000000000000..a4491c155ff28 --- /dev/null +++ b/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp @@ -0,0 +1,99 @@ +//=- VectorComputeUtil.cpp - vector compute utilities implemetation * C++ -*-=// +// +// The LLVM/SPIR-V Translator +// +// +// +//===----------------------------------------------------------------------===// +// +// This file implements translation of VC float control bits +// +//===----------------------------------------------------------------------===// + +#include "VectorComputeUtil.h" +#include "SPIRVInternal.h" +#include "llvm/IR/Metadata.h" +using namespace VectorComputeUtil; +using namespace SPIRV; + +enum VCFloatControl { + VC_RTE = 0, // Round to nearest or even + VC_RTP = 1 << 4, // Round towards +ve inf + VC_RTN = 2 << 4, // Round towards -ve inf + VC_RTZ = 3 << 4, // Round towards zero + + VC_DENORM_FTZ = 0, // Denorm mode flush to zero + VC_DENORM_D_ALLOW = 1 << 6, // Denorm mode double allow + VC_DENORM_F_ALLOW = 1 << 7, // Denorm mode float allow + VC_DENORM_HF_ALLOW = 1 << 10, // Denorm mode half allow + + VC_FLOAT_MODE_IEEE = 0, // Single precision float IEEE mode + VC_FLOAT_MODE_ALT = 1 // Single precision float ALT mode +}; + +enum VCFloatControlMask { + VC_ROUND_MASK = (VC_RTE | VC_RTP | VC_RTN | VC_RTZ), + VC_FLOAT_MASK = (VC_FLOAT_MODE_IEEE | VC_FLOAT_MODE_ALT) +}; + +typedef SPIRVMap VCRoundModeControlBitMap; +typedef SPIRVMap VCFloatModeControlBitMap; +typedef SPIRVMap VCFloatTypeDenormMaskMap; +template <> inline void SPIRVMap::init() { + add(RTE, VC_RTE); + add(RTP, VC_RTP); + add(RTN, VC_RTN); + add(RTZ, VC_RTZ); +} +template <> inline void SPIRVMap::init() { + add(IEEE, VC_FLOAT_MODE_IEEE); + add(ALT, VC_FLOAT_MODE_ALT); +} +template <> inline void SPIRVMap::init() { + add(Double, VC_DENORM_D_ALLOW); + add(Float, VC_DENORM_F_ALLOW); + add(Half, VC_DENORM_HF_ALLOW); +} + +namespace VectorComputeUtil { + +unsigned getVCFloatControl(VCRoundMode RoundMode) noexcept { + return VCRoundModeControlBitMap::map(RoundMode); +} +unsigned getVCFloatControl(VCFloatMode FloatMode) noexcept { + return VCFloatModeControlBitMap::map(FloatMode); +} +unsigned getVCFloatControl(VCDenormMode DenormMode, + VCFloatType FloatType) noexcept { + if (DenormMode == Preserve) + return VCFloatTypeDenormMaskMap::map(FloatType); + return VC_DENORM_FTZ; +} + +SPIRVStorageClassKind +getVCGlobalVarStorageClass(SPIRAddressSpace AddressSpace) noexcept { + switch (AddressSpace) { + case SPIRAS_Private: + return StorageClassPrivate; + case SPIRAS_Local: + return StorageClassWorkgroup; + default: + assert(false && "Unexpected address space"); + return StorageClassPrivate; + } +} + +SPIRAddressSpace +getVCGlobalVarAddressSpace(SPIRVStorageClassKind StorageClass) noexcept { + switch (StorageClass) { + case StorageClassPrivate: + return SPIRAS_Private; + case StorageClassWorkgroup: + return SPIRAS_Local; + default: + assert(false && "Unexpected storage class"); + return SPIRAS_Private; + } +} + +} // namespace VectorComputeUtil diff --git a/llvm-spirv/lib/SPIRV/VectorComputeUtil.h b/llvm-spirv/lib/SPIRV/VectorComputeUtil.h new file mode 100755 index 0000000000000..77ae02757a696 --- /dev/null +++ b/llvm-spirv/lib/SPIRV/VectorComputeUtil.h @@ -0,0 +1,125 @@ +//=- VectorComputeUtil.h - vector compute utilities declarations -*- C++ -*-=// +// +// The LLVM/SPIR-V Translator +// +// +// +//===----------------------------------------------------------------------===// +// +// This file declares translation of VectorComputeUtil float control bits, +// and VC kernel metadata +// +//===----------------------------------------------------------------------===// + +#ifndef SPIRV_VCUTIL_H +#define SPIRV_VCUTIL_H + +#include "SPIRVInternal.h" +#include "SPIRVUtil.h" +#include "spirv.hpp" +#include "llvm/IR/Module.h" + +namespace VectorComputeUtil { + +/////////////////////////////////////////////////////////////////////////////// +// +// Types +// +/////////////////////////////////////////////////////////////////////////////// + +enum VCRoundMode { + RTE, // Round to nearest or even + RTP, // Round towards +ve inf + RTN, // Round towards -ve inf + RTZ, // Round towards zero +}; +enum VCDenormMode { + FlushToZero, + Preserve, +}; +enum VCFloatMode { + IEEE, // Single precision float IEEE mode + ALT, // Single precision float ALT mode +}; +enum VCFloatType { + Double, + Float, + Half, +}; +unsigned getVCFloatControl(VCRoundMode RoundMode) noexcept; +unsigned getVCFloatControl(VCFloatMode FloatMode) noexcept; +unsigned getVCFloatControl(VCDenormMode DenormMode, + VCFloatType FloatType) noexcept; + +typedef SPIRV::SPIRVMap VCRoundModeExecModeMap; +typedef SPIRV::SPIRVMap VCFloatModeExecModeMap; +typedef SPIRV::SPIRVMap + VCDenormModeExecModeMap; +typedef SPIRV::SPIRVMap VCFloatTypeSizeMap; + +/////////////////////////////////////////////////////////////////////////////// +// +// Functions +// +/////////////////////////////////////////////////////////////////////////////// + +SPIRVStorageClassKind +getVCGlobalVarStorageClass(SPIRAddressSpace AddressSpace) noexcept; +SPIRAddressSpace +getVCGlobalVarAddressSpace(SPIRVStorageClassKind StorageClass) noexcept; + +} // namespace VectorComputeUtil + +/////////////////////////////////////////////////////////////////////////////// +// +// Constants +// +/////////////////////////////////////////////////////////////////////////////// + +namespace kVCMetadata { +const static char VCFunction[] = "VCFunction"; +const static char VCStackCall[] = "VCStackCall"; +const static char VCArgumentIOKind[] = "VCArgumentIOKind"; +const static char VCFloatControl[] = "VCFloatControl"; +const static char VCSLMSize[] = "VCSLMSize"; +const static char VCGlobalVariable[] = "VCGlobalVariable"; +const static char VCVolatile[] = "VCVolatile"; +const static char VCByteOffset[] = "VCByteOffset"; +} // namespace kVCMetadata + +/////////////////////////////////////////////////////////////////////////////// +// +// Map definitions +// +/////////////////////////////////////////////////////////////////////////////// + +namespace SPIRV { +template <> +inline void +SPIRVMap::init() { + add(VectorComputeUtil::RTE, spv::ExecutionModeRoundingModeRTE); + add(VectorComputeUtil::RTZ, spv::ExecutionModeRoundingModeRTZ); + add(VectorComputeUtil::RTP, spv::ExecutionModeRoundingModeRTPINTEL); + add(VectorComputeUtil::RTN, spv::ExecutionModeRoundingModeRTNINTEL); +} +template <> +inline void +SPIRVMap::init() { + add(VectorComputeUtil::FlushToZero, spv::ExecutionModeDenormFlushToZero); + add(VectorComputeUtil::Preserve, spv::ExecutionModeDenormPreserve); +} +template <> +inline void +SPIRVMap::init() { + add(VectorComputeUtil::IEEE, spv::ExecutionModeFloatingPointModeIEEEINTEL); + add(VectorComputeUtil::ALT, spv::ExecutionModeFloatingPointModeALTINTEL); +} +template <> +inline void SPIRVMap::init() { + add(VectorComputeUtil::Double, 64); + add(VectorComputeUtil::Float, 32); + add(VectorComputeUtil::Half, 16); +} +} // namespace SPIRV + +#endif // SPIRV_VCUTIL_H From 0bcd3d8fae5fde882ce04f5545bb10b621d31ff5 Mon Sep 17 00:00:00 2001 From: nrudenko Date: Fri, 21 Feb 2020 17:06:56 +0300 Subject: [PATCH 5/6] Implementation of SPV_INTEL_vector_compute extension Frontend part Extension is published at https://github.com/intel/llvm/pull/1612 Co-Authored-By: Aleksandr Bezzubikov Co-Authored-By: Aleksander Us Co-Authored-By: Alexey Sachkov Co-Authored-By: Alexey Sotkin Co-Authored-By: Anton Sidorenko Co-Authored-By: Gang Chen Co-Authored-By: Kai Chen Co-Authored-By: Konstantin Vladimirov Co-Authored-By: Wei Pan Change-Id: Ic8bd645316f054729b8571efd2b9800a38cb723c --- llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp | 53 ++++++++++++++ llvm-spirv/lib/SPIRV/SPIRVWriter.cpp | 76 ++++++++++++++++++--- llvm-spirv/lib/SPIRV/SPIRVWriter.h | 3 +- llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp | 17 +++++ llvm-spirv/lib/SPIRV/VectorComputeUtil.h | 6 ++ 5 files changed, 143 insertions(+), 12 deletions(-) diff --git a/llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp b/llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp index 5c491ba210a9f..66e0d16300995 100644 --- a/llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp +++ b/llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp @@ -42,6 +42,7 @@ #include "SPIRVInternal.h" #include "SPIRVMDBuilder.h" #include "SPIRVMDWalker.h" +#include "VectorComputeUtil.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/IRBuilder.h" @@ -69,6 +70,8 @@ class PreprocessMetadata : public ModulePass { bool runOnModule(Module &M) override; void visit(Module *M); void preprocessOCLMetadata(Module *M, SPIRVMDBuilder *B, SPIRVMDWalker *W); + void preprocessVectorComputeMetadata(Module *M, SPIRVMDBuilder *B, + SPIRVMDWalker *W); static char ID; @@ -100,6 +103,7 @@ void PreprocessMetadata::visit(Module *M) { SPIRVMDWalker W(*M); preprocessOCLMetadata(M, &B, &W); + preprocessVectorComputeMetadata(M, &B, &W); // Create metadata representing (empty so far) list // of OpExecutionMode instructions @@ -243,6 +247,55 @@ void PreprocessMetadata::preprocessOCLMetadata(Module *M, SPIRVMDBuilder *B, B->eraseNamedMD(kSPIR2MD::FPContract); } +void PreprocessMetadata::preprocessVectorComputeMetadata(Module *M, + SPIRVMDBuilder *B, + SPIRVMDWalker *W) { + using namespace VectorComputeUtil; + + auto EM = B->addNamedMD(kSPIRVMD::ExecutionMode); + + for (auto &F : *M) { + // Add VC float control execution modes + // RoundMode and FloatMode are always same for all types in VC + // While Denorm could be different for double, float and half + auto Attrs = F.getAttributes(); + if (Attrs.hasFnAttribute(kVCMetadata::VCFloatControl)) { + SPIRVWord Mode = 0; + Attrs + .getAttribute(AttributeList::FunctionIndex, + kVCMetadata::VCFloatControl) + .getValueAsString() + .getAsInteger(0, Mode); + spv::ExecutionMode ExecRoundMode = + VCRoundModeExecModeMap::map(getVCRoundMode(Mode)); + spv::ExecutionMode ExecFloatMode = + VCFloatModeExecModeMap::map(getVCFloatMode(Mode)); + VCFloatTypeSizeMap::foreach ( + [&](VCFloatType FloatType, unsigned TargetWidth) { + EM.addOp().add(&F).add(ExecRoundMode).add(TargetWidth).done(); + EM.addOp().add(&F).add(ExecFloatMode).add(TargetWidth).done(); + EM.addOp() + .add(&F) + .add(VCDenormModeExecModeMap::map( + getVCDenormPreserve(Mode, FloatType))) + .add(TargetWidth) + .done(); + }); + } + if (Attrs.hasFnAttribute(kVCMetadata::VCSLMSize)) { + SPIRVWord SLMSize = 0; + Attrs.getAttribute(AttributeList::FunctionIndex, kVCMetadata::VCSLMSize) + .getValueAsString() + .getAsInteger(0, SLMSize); + EM.addOp() + .add(&F) + .add(spv::ExecutionModeSharedLocalMemorySizeINTEL) + .add(SLMSize) + .done(); + } + } +} + } // namespace SPIRV INITIALIZE_PASS(PreprocessMetadata, "preprocess-metadata", diff --git a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp index 993c1be4d9cb9..06ca564e9cd84 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVWriter.cpp @@ -53,6 +53,7 @@ #include "SPIRVType.h" #include "SPIRVUtil.h" #include "SPIRVValue.h" +#include "VectorComputeUtil.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringSwitch.h" @@ -144,7 +145,7 @@ SPIRVValue *LLVMToSPIRV::getTranslatedValue(const Value *V) const { return nullptr; } -bool LLVMToSPIRV::oclIsKernel(Function *F) { +bool LLVMToSPIRV::isKernel(Function *F) { if (F->getCallingConv() == CallingConv::SPIR_KERNEL) return true; return false; @@ -514,11 +515,12 @@ SPIRVFunction *LLVMToSPIRV::transFunctionDecl(Function *F) { BF->setFunctionControlMask(transFunctionControlMask(F)); if (F->hasName()) BM->setName(BF, F->getName().str()); - if (oclIsKernel(F)) + if (isKernel(F)) BM->addEntryPoint(ExecutionModelKernel, BF->getId()); else if (F->getLinkage() != GlobalValue::InternalLinkage) BF->setLinkageType(transLinkageType(F)); auto Attrs = F->getAttributes(); + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) { auto ArgNo = I->getArgNo(); @@ -548,15 +550,46 @@ SPIRVFunction *LLVMToSPIRV::transFunctionDecl(Function *F) { if (Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::SExt)) BF->addDecorate(DecorationFuncParamAttr, FunctionParameterAttributeSext); if (Attrs.hasFnAttribute("referenced-indirectly")) { - assert(!oclIsKernel(F) && + assert(!isKernel(F) && "kernel function was marked as referenced-indirectly"); BF->addDecorate(DecorationReferencedIndirectlyINTEL); } + + if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) + transVectorComputeMetadata(F); + SPIRVDBG(dbgs() << "[transFunction] " << *F << " => "; spvdbgs() << *BF << '\n';) return BF; } +void LLVMToSPIRV::transVectorComputeMetadata(Function *F) { + if (!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) + return; + auto BF = static_cast(getTranslatedValue(F)); + auto Attrs = F->getAttributes(); + + if (Attrs.hasFnAttribute(kVCMetadata::VCStackCall)) + BF->addDecorate(DecorationStackCallINTEL); + if (Attrs.hasFnAttribute(kVCMetadata::VCFunction)) + BF->addDecorate(DecorationVectorComputeFunctionINTEL); + else + return; + + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; + ++I) { + auto ArgNo = I->getArgNo(); + SPIRVFunctionParameter *BA = BF->getArgument(ArgNo); + if (Attrs.hasAttribute(ArgNo + 1, kVCMetadata::VCArgumentIOKind)) { + SPIRVWord Kind; + Attrs.getAttribute(ArgNo + 1, kVCMetadata::VCArgumentIOKind) + .getValueAsString() + .getAsInteger(0, Kind); + BA->addDecorate(DecorationFuncParamIOKind, Kind); + } + } +} + SPIRVValue *LLVMToSPIRV::transConstant(Value *V) { if (auto CPNull = dyn_cast(V)) return BM->addNullConstant( @@ -1000,12 +1033,34 @@ SPIRVValue *LLVMToSPIRV::transValueWithoutDecoration(Value *V, BVarInit = transValue(Init, nullptr); } - auto BVar = static_cast(BM->addVariable( - transType(Ty), GV->isConstant(), transLinkageType(GV), BVarInit, - GV->getName().str(), - SPIRSPIRVAddrSpaceMap::map( - static_cast(Ty->getAddressSpace())), - nullptr)); + SPIRVStorageClassKind StorageClass; + auto AddressSpace = static_cast(Ty->getAddressSpace()); + bool IsVectorCompute = + BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute) && + GV->hasAttribute(kVCMetadata::VCGlobalVariable); + if (IsVectorCompute) + StorageClass = + VectorComputeUtil::getVCGlobalVarStorageClass(AddressSpace); + else + StorageClass = SPIRSPIRVAddrSpaceMap::map(AddressSpace); + + auto BVar = static_cast( + BM->addVariable(transType(Ty), GV->isConstant(), transLinkageType(GV), + BVarInit, GV->getName().str(), StorageClass, nullptr)); + + if (IsVectorCompute) { + BVar->addDecorate(DecorationVectorComputeVariableINTEL); + if (GV->hasAttribute(kVCMetadata::VCByteOffset)) { + SPIRVWord Offset; + GV->getAttribute(kVCMetadata::VCByteOffset) + .getValueAsString() + .getAsInteger(0, Offset); + BVar->addDecorate(DecorationGlobalVariableOffsetINTEL, Offset); + } + if (GV->hasAttribute(kVCMetadata::VCVolatile)) + BVar->addDecorate(DecorationVolatile); + } + mapValue(V, BVar); spv::BuiltIn Builtin = spv::BuiltInPosition; if (!GV->hasName() || !getSPIRVBuiltin(GV->getName().str(), Builtin)) @@ -2339,8 +2394,7 @@ void LLVMToSPIRV::transFunction(Function *I) { joinFPContract(I, FPContract::ENABLED); fpContractUpdateRecursive(I, getFPContract(I)); - bool IsKernelEntryPoint = - BF->getModule()->isEntryPoint(spv::ExecutionModelKernel, BF->getId()); + bool IsKernelEntryPoint = isKernel(I); if (IsKernelEntryPoint) { collectInputOutputVariables(BF, I); diff --git a/llvm-spirv/lib/SPIRV/SPIRVWriter.h b/llvm-spirv/lib/SPIRV/SPIRVWriter.h index 743044ee3ecb8..698f4d4e270cb 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVWriter.h +++ b/llvm-spirv/lib/SPIRV/SPIRVWriter.h @@ -105,6 +105,7 @@ class LLVMToSPIRV : public ModulePass { bool transDecoration(Value *V, SPIRVValue *BV); SPIRVWord transFunctionControlMask(Function *); SPIRVFunction *transFunctionDecl(Function *F); + void transVectorComputeMetadata(Function *F); bool transGlobalVariables(); Op transBoolOpCode(SPIRVValue *Opn, Op OC); @@ -172,7 +173,7 @@ class LLVMToSPIRV : public ModulePass { SPIRVExtInstSetKind *BuiltinSet = nullptr, SPIRVWord *EntryPoint = nullptr, SmallVectorImpl *Dec = nullptr); - bool oclIsKernel(Function *F); + bool isKernel(Function *F); bool transMetadata(); bool transOCLMetadata(); SPIRVInstruction *transBuiltinToInst(StringRef DemangledName, CallInst *CI, diff --git a/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp b/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp index a4491c155ff28..c2cf8cd86b26a 100755 --- a/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp +++ b/llvm-spirv/lib/SPIRV/VectorComputeUtil.cpp @@ -57,6 +57,23 @@ template <> inline void SPIRVMap::init() { namespace VectorComputeUtil { +VCRoundMode getVCRoundMode(unsigned FloatControl) noexcept { + return VCRoundModeControlBitMap::rmap( + VCFloatControl(VC_ROUND_MASK & FloatControl)); +} + +VCDenormMode getVCDenormPreserve(unsigned FloatControl, + VCFloatType FloatType) noexcept { + VCFloatControl DenormMask = + VCFloatTypeDenormMaskMap::map(FloatType); // 1 Bit mask + return (DenormMask == (DenormMask & FloatControl)) ? Preserve : FlushToZero; +} + +VCFloatMode getVCFloatMode(unsigned FloatControl) noexcept { + return VCFloatModeControlBitMap::rmap( + VCFloatControl(VC_FLOAT_MASK & FloatControl)); +} + unsigned getVCFloatControl(VCRoundMode RoundMode) noexcept { return VCRoundModeControlBitMap::map(RoundMode); } diff --git a/llvm-spirv/lib/SPIRV/VectorComputeUtil.h b/llvm-spirv/lib/SPIRV/VectorComputeUtil.h index 77ae02757a696..4fd673be19e80 100755 --- a/llvm-spirv/lib/SPIRV/VectorComputeUtil.h +++ b/llvm-spirv/lib/SPIRV/VectorComputeUtil.h @@ -46,6 +46,12 @@ enum VCFloatType { Float, Half, }; + +VCRoundMode getVCRoundMode(unsigned FloatControl) noexcept; +VCDenormMode getVCDenormPreserve(unsigned FloatControl, + VCFloatType FloatType) noexcept; +VCFloatMode getVCFloatMode(unsigned FloatControl) noexcept; + unsigned getVCFloatControl(VCRoundMode RoundMode) noexcept; unsigned getVCFloatControl(VCFloatMode FloatMode) noexcept; unsigned getVCFloatControl(VCDenormMode DenormMode, From d9813da21307dcda41c4327edcd4c0317ff9b45c Mon Sep 17 00:00:00 2001 From: nrudenko Date: Thu, 21 May 2020 13:54:59 +0300 Subject: [PATCH 6/6] Add tests for implementations of SPV_INTEL_vector_compute, SPV_INTEL_float_controls2 and SPV_KHR_float_controls extensions Extensions are published at https://github.com/intel/llvm/pull/1612 https://github.com/intel/llvm/pull/1611 --- llvm-spirv/test/decoration_byte_offset.ll | 36 ++ llvm-spirv/test/decoration_volatile.ll | 36 ++ llvm-spirv/test/exec_mode_argument_io_kind.ll | 32 ++ llvm-spirv/test/exec_mode_float_control.ll | 318 ++++++++++++++++++ .../test/exec_mode_float_control_empty.ll | 28 ++ .../exec_mode_shared_local_memory_size.ll | 30 ++ .../extension_spirv_intel_vector_compute.ll | 32 ++ .../extension_vector_compute_stability.ll | 38 +++ 8 files changed, 550 insertions(+) create mode 100755 llvm-spirv/test/decoration_byte_offset.ll create mode 100755 llvm-spirv/test/decoration_volatile.ll create mode 100755 llvm-spirv/test/exec_mode_argument_io_kind.ll create mode 100755 llvm-spirv/test/exec_mode_float_control.ll create mode 100755 llvm-spirv/test/exec_mode_float_control_empty.ll create mode 100755 llvm-spirv/test/exec_mode_shared_local_memory_size.ll create mode 100755 llvm-spirv/test/extension_spirv_intel_vector_compute.ll create mode 100755 llvm-spirv/test/extension_vector_compute_stability.ll diff --git a/llvm-spirv/test/decoration_byte_offset.ll b/llvm-spirv/test/decoration_byte_offset.ll new file mode 100755 index 0000000000000..57be90c4d5fa9 --- /dev/null +++ b/llvm-spirv/test/decoration_byte_offset.ll @@ -0,0 +1,36 @@ +; 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 = 'slm.bc' +source_filename = "slm.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; LLVM-DAG: @in = internal global{{[^#]*}}#[[K_RTE:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTE]]{{.*"VCByteOffset"="1" }} +; SPV-DAG: Name [[IN:[0-9]+]] "in" +; SPV-DAG: Decorate [[IN]] GlobalVariableOffsetINTEL 1 + +@in = internal global <256 x i8> undef, align 256 #0 +declare <256 x i8> @llvm.genx.vload(<256 x i8>* nonnull %aaa) + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 %ibuf, i32 %obuf) local_unnamed_addr #1 { +entry: + %gload53 = tail call <256 x i8> @llvm.genx.vload(<256 x i8>* nonnull @in) + ret void +} + +attributes #0 = { "VCByteOffset"="1" "VCVolatile" "VCGlobalVariable" } +attributes #1 = { noinline norecurse nounwind readnone "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/decoration_volatile.ll b/llvm-spirv/test/decoration_volatile.ll new file mode 100755 index 0000000000000..83aecefbf6c28 --- /dev/null +++ b/llvm-spirv/test/decoration_volatile.ll @@ -0,0 +1,36 @@ +; 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 = 'slm.bc' +source_filename = "slm.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; LLVM-DAG: @in = internal global{{[^#]*}}#[[K_RTE:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTE]]{{.*"VCVolatile" }} +; SPV-DAG: Name [[IN:[0-9]+]] "in" +; SPV-DAG: Decorate [[IN]] Volatile + +@in = internal global <256 x i8> undef, align 256 #0 +declare <256 x i8> @llvm.genx.vload(<256 x i8>* nonnull %aaa) + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 %ibuf, i32 %obuf) local_unnamed_addr #1 { +entry: + %gload53 = tail call <256 x i8> @llvm.genx.vload(<256 x i8>* nonnull @in) + ret void +} + +attributes #0 = { "VCByteOffset"="0" "VCVolatile" "VCGlobalVariable" } +attributes #1 = { noinline norecurse nounwind readnone "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/exec_mode_argument_io_kind.ll b/llvm-spirv/test/exec_mode_argument_io_kind.ll new file mode 100755 index 0000000000000..6000bcc03cb3b --- /dev/null +++ b/llvm-spirv/test/exec_mode_argument_io_kind.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute +; 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 = 'slm.bc' +source_filename = "slm.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; LLVM: @k_rte(i32 "VCArgumentIOKind"="0" %ibuf, i32 "VCArgumentIOKind"="1" %obuf) +; SPV: Name [[IBUF:[0-9]+]] "ibuf" +; SPV: Name [[OBUF:[0-9]+]] "obuf" +; SPV: Decorate [[IBUF]] FuncParamIOKind 0 +; SPV: Decorate [[OBUF]] FuncParamIOKind 1 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 "VCArgumentIOKind"="0" %ibuf, i32 "VCArgumentIOKind"="1" %obuf) local_unnamed_addr #1 { +entry: + ret void +} + +attributes #1 = { noinline norecurse nounwind readnone "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +; Note +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/exec_mode_float_control.ll b/llvm-spirv/test/exec_mode_float_control.ll new file mode 100755 index 0000000000000..032abb7a586f2 --- /dev/null +++ b/llvm-spirv/test/exec_mode_float_control.ll @@ -0,0 +1,318 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-ext=+SPV_KHR_float_controls --spirv-ext=+SPV_INTEL_float_controls2 +; 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 = 'float_control.bc' +source_filename = "float_control.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + + +; SPV-DAG: Extension "SPV_KHR_float_controls" +; SPV-DAG: Extension "SPV_INTEL_float_controls2" + +; LLVM-DAG: @k_rte{{[^a-zA-Z0-9_][^#]*}}#[[K_RTE:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTE]]{{[^0-9].*"VCFloatControl"="0"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTE:[0-9]+]] "k_rte" +; SPV-DAG: ExecutionMode [[S_RTE]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTE]] 4460 32 +; SPV-DAG: ExecutionMode [[S_RTE]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTE]] 4462 64 +; SPV-DAG: ExecutionMode [[S_RTE]] 4462 32 +; SPV-DAG: ExecutionMode [[S_RTE]] 4462 16 +; SPV-DAG: ExecutionMode [[S_RTE]] 5623 64 +; SPV-DAG: ExecutionMode [[S_RTE]] 5623 32 +; SPV-DAG: ExecutionMode [[S_RTE]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 %ibuf, i32 %obuf) local_unnamed_addr #16 { +entry: + ret void +} + +; LLVM-DAG: @k_rtp{{[^a-zA-Z0-9_][^#]*}}#[[K_RTP:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTP]]{{[^0-9].*"VCFloatControl"="16"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTP:[0-9]+]] "k_rtp" +; SPV-DAG: ExecutionMode [[S_RTP]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTP]] 4460 32 +; SPV-DAG: ExecutionMode [[S_RTP]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTP]] 5620 64 +; SPV-DAG: ExecutionMode [[S_RTP]] 5620 32 +; SPV-DAG: ExecutionMode [[S_RTP]] 5620 16 +; SPV-DAG: ExecutionMode [[S_RTP]] 5623 64 +; SPV-DAG: ExecutionMode [[S_RTP]] 5623 32 +; SPV-DAG: ExecutionMode [[S_RTP]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rtp(i32 %ibuf, i32 %obuf) local_unnamed_addr #17 { +entry: + ret void +} + +; LLVM-DAG: @k_rtn{{[^a-zA-Z0-9_][^#]*}}#[[K_RTN:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTN]]{{[^0-9].*"VCFloatControl"="32"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTN:[0-9]+]] "k_rtn" +; SPV-DAG: ExecutionMode [[S_RTN]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTN]] 4460 32 +; SPV-DAG: ExecutionMode [[S_RTN]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTN]] 5621 64 +; SPV-DAG: ExecutionMode [[S_RTN]] 5621 32 +; SPV-DAG: ExecutionMode [[S_RTN]] 5621 16 +; SPV-DAG: ExecutionMode [[S_RTN]] 5623 64 +; SPV-DAG: ExecutionMode [[S_RTN]] 5623 32 +; SPV-DAG: ExecutionMode [[S_RTN]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rtn(i32 %ibuf, i32 %obuf) local_unnamed_addr #18 { +entry: + ret void +} + +; LLVM-DAG: @k_rtz{{[^a-zA-Z0-9_][^#]*}}#[[K_RTZ:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTZ]]{{[^0-9].*"VCFloatControl"="48"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTZ:[0-9]+]] "k_rtz" +; SPV-DAG: ExecutionMode [[S_RTZ]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTZ]] 4460 32 +; SPV-DAG: ExecutionMode [[S_RTZ]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTZ]] 4463 64 +; SPV-DAG: ExecutionMode [[S_RTZ]] 4463 32 +; SPV-DAG: ExecutionMode [[S_RTZ]] 4463 16 +; SPV-DAG: ExecutionMode [[S_RTZ]] 5623 64 +; SPV-DAG: ExecutionMode [[S_RTZ]] 5623 32 +; SPV-DAG: ExecutionMode [[S_RTZ]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rtz(i32 %ibuf, i32 %obuf) local_unnamed_addr #19 { +entry: + ret void +} + +; LLVM-DAG: @k_ftz{{[^a-zA-Z0-9_][^#]*}}#[[K_RTE]]{{[^0-9]}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_FTZ:[0-9]+]] "k_ftz" +; SPV-DAG: ExecutionMode [[S_FTZ]] 4460 64 +; SPV-DAG: ExecutionMode [[S_FTZ]] 4460 32 +; SPV-DAG: ExecutionMode [[S_FTZ]] 4460 16 +; SPV-DAG: ExecutionMode [[S_FTZ]] 4462 64 +; SPV-DAG: ExecutionMode [[S_FTZ]] 4462 32 +; SPV-DAG: ExecutionMode [[S_FTZ]] 4462 16 +; SPV-DAG: ExecutionMode [[S_FTZ]] 5623 64 +; SPV-DAG: ExecutionMode [[S_FTZ]] 5623 32 +; SPV-DAG: ExecutionMode [[S_FTZ]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_ftz(i32 %ibuf, i32 %obuf) local_unnamed_addr #16 { +entry: + ret void +} + +; LLVM-DAG: @k_dd{{[^a-zA-Z0-9_][^#]*}}#[[K_DD:[0-9]+]] +; LLVM-DAG: attributes #[[K_DD]]{{[^0-9].*"VCFloatControl"="64"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_DD:[0-9]+]] "k_dd" +; SPV-DAG: ExecutionMode [[S_DD]] 4459 64 +; SPV-DAG: ExecutionMode [[S_DD]] 4460 32 +; SPV-DAG: ExecutionMode [[S_DD]] 4460 16 +; SPV-DAG: ExecutionMode [[S_DD]] 4462 64 +; SPV-DAG: ExecutionMode [[S_DD]] 4462 32 +; SPV-DAG: ExecutionMode [[S_DD]] 4462 16 +; SPV-DAG: ExecutionMode [[S_DD]] 5623 64 +; SPV-DAG: ExecutionMode [[S_DD]] 5623 32 +; SPV-DAG: ExecutionMode [[S_DD]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_dd(i32 %ibuf, i32 %obuf) local_unnamed_addr #20 { +entry: + ret void +} + +; LLVM-DAG: @k_df{{[^a-zA-Z0-9_][^#]*}}#[[K_DF:[0-9]+]] +; LLVM-DAG: attributes #[[K_DF]]{{[^0-9].*"VCFloatControl"="128"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_DF:[0-9]+]] "k_df" +; SPV-DAG: ExecutionMode [[S_DF]] 4459 32 +; SPV-DAG: ExecutionMode [[S_DF]] 4460 64 +; SPV-DAG: ExecutionMode [[S_DF]] 4460 16 +; SPV-DAG: ExecutionMode [[S_DF]] 4462 64 +; SPV-DAG: ExecutionMode [[S_DF]] 4462 32 +; SPV-DAG: ExecutionMode [[S_DF]] 4462 16 +; SPV-DAG: ExecutionMode [[S_DF]] 5623 64 +; SPV-DAG: ExecutionMode [[S_DF]] 5623 32 +; SPV-DAG: ExecutionMode [[S_DF]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_df(i32 %ibuf, i32 %obuf) local_unnamed_addr #21 { +entry: + ret void +} + +; LLVM-DAG: @k_dhf{{[^a-zA-Z0-9_][^#]*}}#[[K_DFH:[0-9]+]] +; LLVM-DAG: attributes #[[K_DFH]]{{[^0-9].*"VCFloatControl"="1024"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_DFH:[0-9]+]] "k_dhf" +; SPV-DAG: ExecutionMode [[S_DFH]] 4459 16 +; SPV-DAG: ExecutionMode [[S_DFH]] 4460 64 +; SPV-DAG: ExecutionMode [[S_DFH]] 4460 32 +; SPV-DAG: ExecutionMode [[S_DFH]] 4462 64 +; SPV-DAG: ExecutionMode [[S_DFH]] 4462 32 +; SPV-DAG: ExecutionMode [[S_DFH]] 4462 16 +; SPV-DAG: ExecutionMode [[S_DFH]] 5623 64 +; SPV-DAG: ExecutionMode [[S_DFH]] 5623 32 +; SPV-DAG: ExecutionMode [[S_DFH]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_dhf(i32 %ibuf, i32 %obuf) local_unnamed_addr #22 { +entry: + ret void +} + +; LLVM-DAG: @k_d{{[^a-zA-Z0-9_][^#]*}}#[[K_D:[0-9]+]] +; LLVM-DAG: attributes #[[K_D]]{{[^0-9].*"VCFloatControl"="1216"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_D:[0-9]+]] "k_d" +; SPV-DAG: ExecutionMode [[S_D]] 4459 64 +; SPV-DAG: ExecutionMode [[S_D]] 4459 32 +; SPV-DAG: ExecutionMode [[S_D]] 4459 16 +; SPV-DAG: ExecutionMode [[S_D]] 4462 64 +; SPV-DAG: ExecutionMode [[S_D]] 4462 32 +; SPV-DAG: ExecutionMode [[S_D]] 4462 16 +; SPV-DAG: ExecutionMode [[S_D]] 5623 64 +; SPV-DAG: ExecutionMode [[S_D]] 5623 32 +; SPV-DAG: ExecutionMode [[S_D]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_d(i32 %ibuf, i32 %obuf) local_unnamed_addr #23 { +entry: + ret void +} + +; LLVM-DAG: @k_ieee{{[^a-zA-Z0-9_][^#]*}}#[[K_RTE]]{{[^0-9]}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_IEEE:[0-9]+]] "k_ieee" +; SPV-DAG: ExecutionMode [[S_IEEE]] 4460 64 +; SPV-DAG: ExecutionMode [[S_IEEE]] 4460 32 +; SPV-DAG: ExecutionMode [[S_IEEE]] 4460 16 +; SPV-DAG: ExecutionMode [[S_IEEE]] 4462 64 +; SPV-DAG: ExecutionMode [[S_IEEE]] 4462 32 +; SPV-DAG: ExecutionMode [[S_IEEE]] 4462 16 +; SPV-DAG: ExecutionMode [[S_IEEE]] 5623 64 +; SPV-DAG: ExecutionMode [[S_IEEE]] 5623 32 +; SPV-DAG: ExecutionMode [[S_IEEE]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_ieee(i32 %ibuf, i32 %obuf) local_unnamed_addr #16 { +entry: + ret void +} + +; LLVM-DAG: @k_alt{{[^a-zA-Z0-9_][^#]*}}#[[K_ALT:[0-9]+]] +; LLVM-DAG: attributes #[[K_ALT]]{{[^0-9].*"VCFloatControl"="1"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_ALT:[0-9]+]] "k_alt" +; SPV-DAG: ExecutionMode [[S_ALT]] 4460 64 +; SPV-DAG: ExecutionMode [[S_ALT]] 4460 32 +; SPV-DAG: ExecutionMode [[S_ALT]] 4460 16 +; SPV-DAG: ExecutionMode [[S_ALT]] 4462 64 +; SPV-DAG: ExecutionMode [[S_ALT]] 4462 32 +; SPV-DAG: ExecutionMode [[S_ALT]] 4462 16 +; SPV-DAG: ExecutionMode [[S_ALT]] 5622 64 +; SPV-DAG: ExecutionMode [[S_ALT]] 5622 32 +; SPV-DAG: ExecutionMode [[S_ALT]] 5622 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_alt(i32 %ibuf, i32 %obuf) local_unnamed_addr #24 { +entry: + ret void +} + +; LLVM-DAG: @k_rtp_rtn{{[^a-zA-Z0-9_][^#]*}}#[[K_RTZ]]{{[^0-9]}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTP_RTN:[0-9]+]] "k_rtp_rtn" +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 4460 32 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 4463 64 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 4463 32 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 4463 16 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 5623 64 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 5623 32 +; SPV-DAG: ExecutionMode [[S_RTP_RTN]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rtp_rtn(i32 %ibuf, i32 %obuf) local_unnamed_addr #19 { +entry: + ret void +} + +; LLVM-DAG: @k_dd_df_dhf{{[^a-zA-Z0-9_][^#]*}}#[[K_D]]{{[^0-9]}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_DD_DF_DHF:[0-9]+]] "k_dd_df_dhf" +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 4459 64 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 4459 32 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 4459 16 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 4462 64 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 4462 32 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 4462 16 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 5623 64 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 5623 32 +; SPV-DAG: ExecutionMode [[S_DD_DF_DHF]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_dd_df_dhf(i32 %ibuf, i32 %obuf) local_unnamed_addr #23 { +entry: + ret void +} + +; LLVM-DAG: @k_rte_ftz_ieee{{[^#]*}}#[[K_RTE]]{{[^0-9]}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTE_FTZ_IEEE:[0-9]+]] "k_rte_ftz_ieee" +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 4460 32 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 4462 64 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 4462 32 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 4462 16 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 5623 64 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 5623 32 +; SPV-DAG: ExecutionMode [[S_RTE_FTZ_IEEE]] 5623 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte_ftz_ieee(i32 %ibuf, i32 %obuf) local_unnamed_addr #16 { +entry: + ret void +} + +; LLVM-DAG: @k_rtp_df_alt{{[^a-zA-Z0-9_][^#]*}}#[[K_RTP_DF_ALT:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTP_DF_ALT]]{{[^0-9].*"VCFloatControl"="145"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTP_DF_ALT:[0-9]+]] "k_rtp_df_alt" +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 4459 32 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 4460 64 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 4460 16 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 5620 64 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 5620 32 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 5620 16 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 5622 64 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 5622 32 +; SPV-DAG: ExecutionMode [[S_RTP_DF_ALT]] 5622 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rtp_df_alt(i32 %ibuf, i32 %obuf) local_unnamed_addr #25 { +entry: + ret void +} + +; LLVM-DAG: @k_rtz_d_alt{{[^a-zA-Z0-9_][^#]*}}#[[K_RTZ_D_ALT:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTZ_D_ALT]]{{[^0-9].*"VCFloatControl"="1265"}} +; SPV-DAG: EntryPoint {{[0-9]+}} [[S_RTZ_D_ALT:[0-9]+]] "k_rtz_d_alt" +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 4459 64 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 4459 32 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 4459 16 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 4463 64 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 4463 32 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 4463 16 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 5622 64 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 5622 32 +; SPV-DAG: ExecutionMode [[S_RTZ_D_ALT]] 5622 16 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rtz_d_alt(i32 %ibuf, i32 %obuf) local_unnamed_addr #26 { +entry: + ret void +} + +attributes #16 = { noinline norecurse nounwind readnone "VCFloatControl"="0" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #17 = { noinline norecurse nounwind readnone "VCFloatControl"="16" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #18 = { noinline norecurse nounwind readnone "VCFloatControl"="32" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #19 = { noinline norecurse nounwind readnone "VCFloatControl"="48" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #20 = { noinline norecurse nounwind readnone "VCFloatControl"="64" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #21 = { noinline norecurse nounwind readnone "VCFloatControl"="128" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #22 = { noinline norecurse nounwind readnone "VCFloatControl"="1024" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #23 = { noinline norecurse nounwind readnone "VCFloatControl"="1216" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #24 = { noinline norecurse nounwind readnone "VCFloatControl"="1" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #25 = { noinline norecurse nounwind readnone "VCFloatControl"="145" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #26 = { noinline norecurse nounwind readnone "VCFloatControl"="1265" "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/exec_mode_float_control_empty.ll b/llvm-spirv/test/exec_mode_float_control_empty.ll new file mode 100755 index 0000000000000..3de49cb55d68d --- /dev/null +++ b/llvm-spirv/test/exec_mode_float_control_empty.ll @@ -0,0 +1,28 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv --spirv-ext=+SPV_KHR_float_controls --spirv-ext=+SPV_INTEL_float_controls2 %t.bc -o %t.spv +; 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 = 'float_control_empty.bc' +source_filename = "float_control_empty.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; LLVM-NOT: VCFloatControl +; SPV-NOT: {{ExecutionMode.*(4459|4460|4461|4462|4463|5620|5621|5622|5623)}} +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_no_fc(i32 %ibuf, i32 %obuf) local_unnamed_addr #16 { +entry: + ret void +} + +attributes #16 = { noinline norecurse nounwind readnone "VCMain" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/exec_mode_shared_local_memory_size.ll b/llvm-spirv/test/exec_mode_shared_local_memory_size.ll new file mode 100755 index 0000000000000..13d83c549eeef --- /dev/null +++ b/llvm-spirv/test/exec_mode_shared_local_memory_size.ll @@ -0,0 +1,30 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute +; 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 = 'slm.bc' +source_filename = "slm.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; LLVM-DAG: @k_rte{{[^a-zA-Z0-9_][^#]*}}#[[K_RTE:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTE]]{{[^0-9].*"VCSLMSize"="256"}} +; SPV: EntryPoint {{[0-9]+}} [[S_RTE:[0-9]+]] "k_rte" +; SPV: ExecutionMode [[S_RTE]] 5618 256 +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 %ibuf, i32 %obuf) local_unnamed_addr #1 { +entry: + ret void +} + +attributes #1 = { noinline norecurse nounwind readnone "VCMain" "VCFunction" "VCSLMSize"="256" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/extension_spirv_intel_vector_compute.ll b/llvm-spirv/test/extension_spirv_intel_vector_compute.ll new file mode 100755 index 0000000000000..aecaeb66eb82b --- /dev/null +++ b/llvm-spirv/test/extension_spirv_intel_vector_compute.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-ext=+SPV_KHR_float_controls --spirv-ext=+SPV_INTEL_float_controls2 +; 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 = 'float_control.bc' +source_filename = "float_control.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + +; SPV-NOT: ExtInstImport {{[0-9]+}} "OpenCL.std" +; SPV-DAG: Extension "SPV_INTEL_vector_compute" +; SPV-DAG: Capability VectorComputeINTEL +; LLVM-DAG: @k_rte{{[^a-zA-Z0-9_][^#]*}}#[[K_RTE:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTE]]{{[^0-9].*"VCFunction"}} +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 %ibuf, i32 %obuf) local_unnamed_addr #1 { +entry: + ret void +} + +attributes #1 = { noinline norecurse nounwind readnone "VCFloatControl"="0" "VCFunction" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"} diff --git a/llvm-spirv/test/extension_vector_compute_stability.ll b/llvm-spirv/test/extension_vector_compute_stability.ll new file mode 100755 index 0000000000000..4e271adae2df9 --- /dev/null +++ b/llvm-spirv/test/extension_vector_compute_stability.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-ext=+SPV_KHR_float_controls --spirv-ext=+SPV_INTEL_float_controls2 --spirv-allow-unknown-intrinsics +; RUN: llvm-spirv -r %t.spv -o %t.bc +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-ext=+SPV_KHR_float_controls --spirv-ext=+SPV_INTEL_float_controls2 --spirv-allow-unknown-intrinsics +; RUN: llvm-spirv -r %t.spv -o %t.bc +; RUN: llvm-dis %t.bc -o %t.ll +; RUN: FileCheck %s --input-file %t.ll -check-prefix=LLVM + +; ModuleID = 'slm.bc' +source_filename = "slm.cpp" +target datalayout = "e-p:64:64-i64:64-n8:16:32" +target triple = "spir" + + +; LLVM-DAG: @k_rte{{[^a-zA-Z0-9_][^#]*}}#[[K_RTE_ATTR:[0-9]+]] +; LLVM-DAG: attributes #[[K_RTE_ATTR]]{{[^0-9].*"VCFloatControl"="0".*"VCFunction".*"VCSLMSize"="256"}} +; LLVM-DAG: @in = internal global{{[^#]*}}#[[IN_ATTR:[0-9]+]] +; LLVM-DAG: attributes #[[IN_ATTR]]{{[^0-9].*"VCByteOffset"="1".*"VCGlobalVariable".*"VCVolatile"}} + +@in = internal global <256 x i8> undef, align 256 #0 +declare <256 x i8> @llvm.genx.vload(<256 x i8>* nonnull %aaa) + +; Function Attrs: noinline norecurse nounwind readnone +define dso_local dllexport spir_kernel void @k_rte(i32 %ibuf, i32 %obuf) local_unnamed_addr #1 { +entry: + %gload53 = tail call <256 x i8> @llvm.genx.vload(<256 x i8>* nonnull @in) + ret void +} + +attributes #0 = { "VCByteOffset"="1" "VCVolatile" "VCGlobalVariable"} +attributes #1 = { noinline norecurse nounwind readnone "VCFloatControl"="0" "VCFunction" "VCSLMSize"="256" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "oclrt"="1" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +; Note +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 8.0.1"}