From 9ddd30291652f53d7be5adf11638c53334b94663 Mon Sep 17 00:00:00 2001 From: Viktoria Maksimova Date: Fri, 13 Mar 2020 16:41:24 +0300 Subject: [PATCH 1/3] Translate new set of Intel FPGA Loop Controls Specification can be found here: https://github.com/KhronosGroup/SPIRV-Registry/pull/62 As per revision C -> revision E transition in the spec, patch introduces translation of the following loop controls: * PipelineDisableINTEL * LoopCoalesceINTEL * MaxInterleavingINTEL * SpeculatedIterationsINTEL --- lib/SPIRV/SPIRVReader.cpp | 41 +++++ lib/SPIRV/SPIRVWriter.cpp | 28 ++++ lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h | 4 + lib/SPIRV/libSPIRV/spirv.hpp | 4 + test/transcoding/FPGALoopAttr.ll | 211 ++++++++++++++++++++++++++ 5 files changed, 288 insertions(+) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 3283646f30..ffe874acfc 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -786,6 +786,47 @@ void SPIRVToLLVM::setLLVMLoopMetadata(const LoopInstType *LM, Metadata.push_back(llvm::MDNode::get(*Context, Parameters)); } } + if (LC & LoopControlPipelineEnableINTEL) { + Metadata.push_back(llvm::MDNode::get( + *Context, + getMetadataFromNameAndParameter("llvm.loop.intel.pipelining.enable", + LoopControlParameters[NumParam]))); + ++NumParam; + assert(NumParam <= LoopControlParameters.size() && + "Missing loop control parameter!"); + } + if (LC & LoopControlLoopCoalesceINTEL) { + if (LoopControlParameters.size()) { + Metadata.push_back(llvm::MDNode::get( + *Context, + getMetadataFromNameAndParameter("llvm.loop.coalesce.count", + LoopControlParameters[NumParam]))); + ++NumParam; + } else { // If LoopCoalesce has no parameters + Metadata.push_back(llvm::MDNode::get( + *Context, getMetadataFromName("llvm.loop.coalesce.enable"))); + } + assert(NumParam <= LoopControlParameters.size() && + "Missing loop control parameter!"); + } + if (LC & LoopControlMaxInterleavingINTEL) { + Metadata.push_back(llvm::MDNode::get( + *Context, + getMetadataFromNameAndParameter("llvm.loop.max_interleaving.count", + LoopControlParameters[NumParam]))); + ++NumParam; + assert(NumParam <= LoopControlParameters.size() && + "Missing loop control parameter!"); + } + if (LC & LoopControlSpeculatedIterationsINTEL) { + Metadata.push_back(llvm::MDNode::get( + *Context, getMetadataFromNameAndParameter( + "llvm.loop.intel.speculated.iterations.count", + LoopControlParameters[NumParam]))); + ++NumParam; + assert(NumParam <= LoopControlParameters.size() && + "Missing loop control parameter!"); + } llvm::MDNode *Node = llvm::MDNode::get(*Context, Metadata); // Set the first operand to refer itself diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 20b0718179..682cc82dad 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -848,6 +848,34 @@ LLVMToSPIRV::getLoopControl(const BranchInst *Branch, unsigned SafeLen = IVDep.getSafeLen(); for (auto &ArrayId : IVDep.getArrayVariables()) DependencyArrayParameters.emplace_back(ArrayId, SafeLen); + } else if (S == "llvm.loop.intel.pipelining.enable") { + BM->addExtension(ExtensionID::SPV_INTEL_fpga_loop_controls); + BM->addCapability(CapabilityFPGALoopControlsINTEL); + size_t I = getMDOperandAsInt(Node, 1); + Parameters.push_back(I); + LoopControl |= spv::LoopControlPipelineEnableINTEL; + } else if (S == "llvm.loop.coalesce.enable") { + BM->addExtension(ExtensionID::SPV_INTEL_fpga_loop_controls); + BM->addCapability(CapabilityFPGALoopControlsINTEL); + LoopControl |= spv::LoopControlLoopCoalesceINTEL; + } else if (S == "llvm.loop.coalesce.count") { + BM->addExtension(ExtensionID::SPV_INTEL_fpga_loop_controls); + BM->addCapability(CapabilityFPGALoopControlsINTEL); + size_t I = getMDOperandAsInt(Node, 1); + Parameters.push_back(I); + LoopControl |= spv::LoopControlLoopCoalesceINTEL; + } else if (S == "llvm.loop.max_interleaving.count") { + BM->addExtension(ExtensionID::SPV_INTEL_fpga_loop_controls); + BM->addCapability(CapabilityFPGALoopControlsINTEL); + size_t I = getMDOperandAsInt(Node, 1); + Parameters.push_back(I); + LoopControl |= spv::LoopControlMaxInterleavingINTEL; + } else if (S == "llvm.loop.intel.speculated.iterations.count") { + BM->addExtension(ExtensionID::SPV_INTEL_fpga_loop_controls); + BM->addCapability(CapabilityFPGALoopControlsINTEL); + size_t I = getMDOperandAsInt(Node, 1); + Parameters.push_back(I); + LoopControl |= spv::LoopControlSpeculatedIterationsINTEL; } } } diff --git a/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h b/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h index 5e59bd704b..41e3d6d372 100644 --- a/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h @@ -1065,6 +1065,10 @@ inline bool isValidLoopControlMask(SPIRVWord Mask) { ValidMask |= LoopControlInitiationIntervalINTEL; ValidMask |= LoopControlMaxConcurrencyINTEL; ValidMask |= LoopControlDependencyArrayINTEL; + ValidMask |= LoopControlPipelineEnableINTEL; + ValidMask |= LoopControlLoopCoalesceINTEL; + ValidMask |= LoopControlMaxInterleavingINTEL; + ValidMask |= LoopControlSpeculatedIterationsINTEL; return (Mask & ~ValidMask) == 0; } diff --git a/lib/SPIRV/libSPIRV/spirv.hpp b/lib/SPIRV/libSPIRV/spirv.hpp index b9e0fb3247..810c7bc56a 100644 --- a/lib/SPIRV/libSPIRV/spirv.hpp +++ b/lib/SPIRV/libSPIRV/spirv.hpp @@ -504,6 +504,10 @@ enum LoopControlMask { LoopControlInitiationIntervalINTEL = 0x10000, LoopControlMaxConcurrencyINTEL = 0x20000, LoopControlDependencyArrayINTEL = 0x40000, + LoopControlPipelineEnableINTEL = 0x80000, + LoopControlLoopCoalesceINTEL = 0x100000, + LoopControlMaxInterleavingINTEL = 0x200000, + LoopControlSpeculatedIterationsINTEL = 0x400000, }; enum FunctionControlShift { diff --git a/test/transcoding/FPGALoopAttr.ll b/test/transcoding/FPGALoopAttr.ll index 366577a8b8..10a6f3277e 100644 --- a/test/transcoding/FPGALoopAttr.ll +++ b/test/transcoding/FPGALoopAttr.ll @@ -168,6 +168,175 @@ for.end36: ; preds = %for.cond29 ret void } +; Function Attrs: noinline nounwind optnone +define spir_func void @loop_pipelining() #0 { +entry: + %a = alloca [10 x i32], align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +; Per SPIR-V spec, LoopControlPipelineEnableINTEL = 0x80000 (524288) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 524288 1 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 524288 1 +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp ne i32 %0, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom + store i32 0, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %2 = load i32, i32* %i, align 4 + %inc = add nsw i32 %2, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !12 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone +define spir_func void @loop_coalesce() #0 { +entry: + %i = alloca i32, align 4 + %m = alloca i32, align 4 + store i32 0, i32* %i, align 4 + store i32 42, i32* %m, align 4 + br label %while.cond + +; Per SPIR-V spec, LoopControlLoopCoalesceINTEL = 0x100000 (1048576) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 4 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 4 +while.cond: ; preds = %if.end, %if.then, %entry + %0 = load i32, i32* %i, align 4 + %1 = load i32, i32* %m, align 4 + %cmp = icmp slt i32 %0, %1 + br i1 %cmp, label %while.body, label %while.end + +while.body: ; preds = %while.cond + %2 = load i32, i32* %i, align 4 + %rem = srem i32 %2, 2 + %tobool = icmp ne i32 %rem, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: ; preds = %while.body + %3 = load i32, i32* %i, align 4 + %inc = add nsw i32 %3, 1 + store i32 %inc, i32* %i, align 4 + br label %while.cond, !llvm.loop !14 + +if.end: ; preds = %while.body + br label %while.cond, !llvm.loop !14 + +while.end: ; preds = %while.cond + store i32 0, i32* %i, align 4 + br label %while.cond1 + +; Per SPIR-V spec, LoopControlLoopCoalesceINTEL = 0x100000 (1048576) +; CHECK-SPIRV: 4 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 4 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 +while.cond1: ; preds = %if.end8, %if.then6, %while.end + %4 = load i32, i32* %i, align 4 + %5 = load i32, i32* %m, align 4 + %cmp2 = icmp slt i32 %4, %5 + br i1 %cmp2, label %while.body3, label %while.end9 + +while.body3: ; preds = %while.cond1 + %6 = load i32, i32* %i, align 4 + %rem4 = srem i32 %6, 3 + %tobool5 = icmp ne i32 %rem4, 0 + br i1 %tobool5, label %if.then6, label %if.end8 + +if.then6: ; preds = %while.body3 + %7 = load i32, i32* %i, align 4 + %inc7 = add nsw i32 %7, 1 + store i32 %inc7, i32* %i, align 4 + br label %while.cond1, !llvm.loop !16 + +if.end8: ; preds = %while.body3 + br label %while.cond1, !llvm.loop !16 + +while.end9: ; preds = %while.cond1 + ret void +} + +; Function Attrs: noinline nounwind optnone +define spir_func void @max_interleaving() #0 { +entry: + %a = alloca [10 x i32], align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +; Per SPIR-V spec, LoopControlMaxInterleavingINTEL = 0x200000 (2097152) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 2097152 3 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 2097152 3 +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp ne i32 %0, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom + store i32 0, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %2 = load i32, i32* %i, align 4 + %inc = add nsw i32 %2, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !18 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone +define spir_func void @speculated_iterations() #0 { +entry: + %a = alloca [10 x i32], align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +; Per SPIR-V spec, LoopControlSpeculatedIterationsINTEL = 0x400000 (4194304) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 4194304 4 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 4194304 4 +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp ne i32 %0, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom + store i32 0, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %2 = load i32, i32* %i, align 4 + %inc = add nsw i32 %2, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !20 + +for.end: ; preds = %for.cond + ret void +} + attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "denorms-are-zero"="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" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0} @@ -186,18 +355,38 @@ attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide !9 = distinct !{!9, !10} !10 = !{!"llvm.loop.max_concurrency.count", i32 2} !11 = distinct !{!11, !8, !10} +!12 = distinct !{!12, !13} +!13 = !{!"llvm.loop.intel.pipelining.enable", i32 1} +!14 = distinct !{!14, !15} +!15 = !{!"llvm.loop.coalesce.count", i32 4} +!16 = distinct !{!16, !17} +!17 = !{!"llvm.loop.coalesce.enable"} +!18 = distinct !{!18, !19} +!19 = !{!"llvm.loop.max_interleaving.count", i32 3} +!20 = distinct !{!20, !21} +!21 = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} ; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_A:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_B:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_C:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_D:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_E:[0-9]+]] +; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_F:[0-9]+]] +; CHECK-LLVM: br label %while.cond{{[0-9]*}}, !llvm.loop ![[MD_G:[0-9]+]] +; CHECK-LLVM: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_H:[0-9]+]] +; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_I:[0-9]+]] +; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_J:[0-9]+]] ; CHECK-LLVM-NEGATIVE: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_A:[0-9]+]] ; CHECK-LLVM-NEGATIVE: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_B:[0-9]+]] ; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_C:[0-9]+]] ; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_D:[0-9]+]] ; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_E:[0-9]+]] +; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_F:[0-9]+]] +; CHECK-LLVM-NEGATIVE-NOT: br label %while.cond{{[0-9]*}}, !llvm.loop ![[MD_G:[0-9]+]] +; CHECK-LLVM-NEGATIVE-NOT: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_H:[0-9]+]] +; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_I:[0-9]+]] +; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_J:[0-9]+]] ; CHECK-LLVM: ![[MD_A]] = distinct !{![[MD_A]], ![[MD_ivdep_enable:[0-9]+]]} ; CHECK-LLVM: ![[MD_ivdep_enable]] = !{!"llvm.loop.ivdep.enable"} @@ -208,6 +397,17 @@ attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide ; CHECK-LLVM: ![[MD_D]] = distinct !{![[MD_D]], ![[MD_max_concurrency:[0-9]+]]} ; CHECK-LLVM: ![[MD_max_concurrency]] = !{!"llvm.loop.max_concurrency.count", i32 2} ; CHECK-LLVM: ![[MD_E]] = distinct !{![[MD_E]], ![[MD_ii:[0-9]+]], ![[MD_max_concurrency:[0-9]+]]} +; CHECK-LLVM: ![[MD_F]] = distinct !{![[MD_F]], ![[MD_pipelining:[0-9]+]]} +; CHECK-LLVM: ![[MD_pipelining]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} +; CHECK-LLVM: ![[MD_G]] = distinct !{![[MD_G]], ![[MD_loop_coalesce_count:[0-9]+]]} +; CHECK-LLVM: ![[MD_loop_coalesce_count]] = !{!"llvm.loop.coalesce.count", i32 4} +; CHECK-LLVM: ![[MD_H]] = distinct !{![[MD_H]], ![[MD_loop_coalesce:[0-9]+]]} +; CHECK-LLVM: ![[MD_loop_coalesce]] = !{![[MD_loop_coalesce_enable:[0-9]+]]} +; CHECK-LLVM: ![[MD_loop_coalesce_enable]] = !{!"llvm.loop.coalesce.enable"} +; CHECK-LLVM: ![[MD_I]] = distinct !{![[MD_I]], ![[MD_max_interleaving:[0-9]+]]} +; CHECK-LLVM: ![[MD_max_interleaving]] = !{!"llvm.loop.max_interleaving.count", i32 3} +; CHECK-LLVM: ![[MD_J]] = distinct !{![[MD_J]], ![[MD_spec_iterations:[0-9]+]]} +; CHECK-LLVM: ![[MD_spec_iterations]] = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} ; CHECK-LLVM-NEGATIVE: ![[MD_A]] = distinct !{![[MD_A]], ![[MD_ivdep_enable:[0-9]+]]} ; CHECK-LLVM-NEGATIVE: ![[MD_ivdep_enable]] = !{!"llvm.loop.ivdep.enable"} @@ -218,3 +418,14 @@ attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide ; CHECK-LLVM-NEGATIVE-NOT: ![[MD_D]] = distinct !{![[MD_D]], ![[MD_max_concurrency:[0-9]+]]} ; CHECK-LLVM-NEGATIVE-NOT: ![[MD_max_concurrency]] = !{!"llvm.loop.max_concurrency.count", i32 2} ; CHECK-LLVM-NEGATIVE-NOT: ![[MD_E]] = distinct !{![[MD_E]], ![[MD_ii:[0-9]+]], ![[MD_max_concurrency:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_F]] = distinct !{![[MD_F]], ![[MD_pipelining:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_pipelining]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_G]] = distinct !{![[MD_G]], ![[MD_loop_coalesce_count:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_loop_coalesce_count]] = !{!"llvm.loop.coalesce.count", i32 4} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_H]] = distinct !{![[MD_H]], ![[MD_loop_coalesce:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_loop_coalesce]] = !{![[MD_loop_coalesce_enable:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_loop_coalesce_enable]] = !{!"llvm.loop.coalesce.enable"} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_I]] = distinct !{![[MD_I]], ![[MD_max_interleaving:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_max_interleaving]] = !{!"llvm.loop.max_interleaving.count", i32 3} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_J]] = distinct !{![[MD_J]], ![[MD_spec_iterations:[0-9]+]]} +; CHECK-LLVM-NEGATIVE-NOT: ![[MD_spec_iterations]] = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} \ No newline at end of file From 483439232ca837cd9fd67d3d3ba7bc8d670e9ead Mon Sep 17 00:00:00 2001 From: Viktoria Maksimova Date: Tue, 24 Mar 2020 14:53:39 +0300 Subject: [PATCH 2/3] Apply suggestions --- lib/SPIRV/SPIRVReader.cpp | 12 +- test/transcoding/FPGALoopAttr.ll | 211 ----------------------- test/transcoding/FPGALoopMergeInst.ll | 235 ++++++++++++++++++++++++++ 3 files changed, 239 insertions(+), 219 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index ffe874acfc..ed35a0b347 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -790,8 +790,7 @@ void SPIRVToLLVM::setLLVMLoopMetadata(const LoopInstType *LM, Metadata.push_back(llvm::MDNode::get( *Context, getMetadataFromNameAndParameter("llvm.loop.intel.pipelining.enable", - LoopControlParameters[NumParam]))); - ++NumParam; + LoopControlParameters[NumParam++]))); assert(NumParam <= LoopControlParameters.size() && "Missing loop control parameter!"); } @@ -800,8 +799,7 @@ void SPIRVToLLVM::setLLVMLoopMetadata(const LoopInstType *LM, Metadata.push_back(llvm::MDNode::get( *Context, getMetadataFromNameAndParameter("llvm.loop.coalesce.count", - LoopControlParameters[NumParam]))); - ++NumParam; + LoopControlParameters[NumParam++]))); } else { // If LoopCoalesce has no parameters Metadata.push_back(llvm::MDNode::get( *Context, getMetadataFromName("llvm.loop.coalesce.enable"))); @@ -813,8 +811,7 @@ void SPIRVToLLVM::setLLVMLoopMetadata(const LoopInstType *LM, Metadata.push_back(llvm::MDNode::get( *Context, getMetadataFromNameAndParameter("llvm.loop.max_interleaving.count", - LoopControlParameters[NumParam]))); - ++NumParam; + LoopControlParameters[NumParam++]))); assert(NumParam <= LoopControlParameters.size() && "Missing loop control parameter!"); } @@ -822,8 +819,7 @@ void SPIRVToLLVM::setLLVMLoopMetadata(const LoopInstType *LM, Metadata.push_back(llvm::MDNode::get( *Context, getMetadataFromNameAndParameter( "llvm.loop.intel.speculated.iterations.count", - LoopControlParameters[NumParam]))); - ++NumParam; + LoopControlParameters[NumParam++]))); assert(NumParam <= LoopControlParameters.size() && "Missing loop control parameter!"); } diff --git a/test/transcoding/FPGALoopAttr.ll b/test/transcoding/FPGALoopAttr.ll index 10a6f3277e..366577a8b8 100644 --- a/test/transcoding/FPGALoopAttr.ll +++ b/test/transcoding/FPGALoopAttr.ll @@ -168,175 +168,6 @@ for.end36: ; preds = %for.cond29 ret void } -; Function Attrs: noinline nounwind optnone -define spir_func void @loop_pipelining() #0 { -entry: - %a = alloca [10 x i32], align 4 - %i = alloca i32, align 4 - store i32 0, i32* %i, align 4 - br label %for.cond - -; Per SPIR-V spec, LoopControlPipelineEnableINTEL = 0x80000 (524288) -; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 524288 1 -; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} -; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 524288 1 -for.cond: ; preds = %for.inc, %entry - %0 = load i32, i32* %i, align 4 - %cmp = icmp ne i32 %0, 10 - br i1 %cmp, label %for.body, label %for.end - -for.body: ; preds = %for.cond - %1 = load i32, i32* %i, align 4 - %idxprom = sext i32 %1 to i64 - %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom - store i32 0, i32* %arrayidx, align 4 - br label %for.inc - -for.inc: ; preds = %for.body - %2 = load i32, i32* %i, align 4 - %inc = add nsw i32 %2, 1 - store i32 %inc, i32* %i, align 4 - br label %for.cond, !llvm.loop !12 - -for.end: ; preds = %for.cond - ret void -} - -; Function Attrs: noinline nounwind optnone -define spir_func void @loop_coalesce() #0 { -entry: - %i = alloca i32, align 4 - %m = alloca i32, align 4 - store i32 0, i32* %i, align 4 - store i32 42, i32* %m, align 4 - br label %while.cond - -; Per SPIR-V spec, LoopControlLoopCoalesceINTEL = 0x100000 (1048576) -; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 4 -; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} -; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 4 -while.cond: ; preds = %if.end, %if.then, %entry - %0 = load i32, i32* %i, align 4 - %1 = load i32, i32* %m, align 4 - %cmp = icmp slt i32 %0, %1 - br i1 %cmp, label %while.body, label %while.end - -while.body: ; preds = %while.cond - %2 = load i32, i32* %i, align 4 - %rem = srem i32 %2, 2 - %tobool = icmp ne i32 %rem, 0 - br i1 %tobool, label %if.then, label %if.end - -if.then: ; preds = %while.body - %3 = load i32, i32* %i, align 4 - %inc = add nsw i32 %3, 1 - store i32 %inc, i32* %i, align 4 - br label %while.cond, !llvm.loop !14 - -if.end: ; preds = %while.body - br label %while.cond, !llvm.loop !14 - -while.end: ; preds = %while.cond - store i32 0, i32* %i, align 4 - br label %while.cond1 - -; Per SPIR-V spec, LoopControlLoopCoalesceINTEL = 0x100000 (1048576) -; CHECK-SPIRV: 4 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 -; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} -; CHECK-SPIRV-NEGATIVE-NOT: 4 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 -while.cond1: ; preds = %if.end8, %if.then6, %while.end - %4 = load i32, i32* %i, align 4 - %5 = load i32, i32* %m, align 4 - %cmp2 = icmp slt i32 %4, %5 - br i1 %cmp2, label %while.body3, label %while.end9 - -while.body3: ; preds = %while.cond1 - %6 = load i32, i32* %i, align 4 - %rem4 = srem i32 %6, 3 - %tobool5 = icmp ne i32 %rem4, 0 - br i1 %tobool5, label %if.then6, label %if.end8 - -if.then6: ; preds = %while.body3 - %7 = load i32, i32* %i, align 4 - %inc7 = add nsw i32 %7, 1 - store i32 %inc7, i32* %i, align 4 - br label %while.cond1, !llvm.loop !16 - -if.end8: ; preds = %while.body3 - br label %while.cond1, !llvm.loop !16 - -while.end9: ; preds = %while.cond1 - ret void -} - -; Function Attrs: noinline nounwind optnone -define spir_func void @max_interleaving() #0 { -entry: - %a = alloca [10 x i32], align 4 - %i = alloca i32, align 4 - store i32 0, i32* %i, align 4 - br label %for.cond - -; Per SPIR-V spec, LoopControlMaxInterleavingINTEL = 0x200000 (2097152) -; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 2097152 3 -; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} -; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 2097152 3 -for.cond: ; preds = %for.inc, %entry - %0 = load i32, i32* %i, align 4 - %cmp = icmp ne i32 %0, 10 - br i1 %cmp, label %for.body, label %for.end - -for.body: ; preds = %for.cond - %1 = load i32, i32* %i, align 4 - %idxprom = sext i32 %1 to i64 - %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom - store i32 0, i32* %arrayidx, align 4 - br label %for.inc - -for.inc: ; preds = %for.body - %2 = load i32, i32* %i, align 4 - %inc = add nsw i32 %2, 1 - store i32 %inc, i32* %i, align 4 - br label %for.cond, !llvm.loop !18 - -for.end: ; preds = %for.cond - ret void -} - -; Function Attrs: noinline nounwind optnone -define spir_func void @speculated_iterations() #0 { -entry: - %a = alloca [10 x i32], align 4 - %i = alloca i32, align 4 - store i32 0, i32* %i, align 4 - br label %for.cond - -; Per SPIR-V spec, LoopControlSpeculatedIterationsINTEL = 0x400000 (4194304) -; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 4194304 4 -; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} -; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 4194304 4 -for.cond: ; preds = %for.inc, %entry - %0 = load i32, i32* %i, align 4 - %cmp = icmp ne i32 %0, 10 - br i1 %cmp, label %for.body, label %for.end - -for.body: ; preds = %for.cond - %1 = load i32, i32* %i, align 4 - %idxprom = sext i32 %1 to i64 - %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom - store i32 0, i32* %arrayidx, align 4 - br label %for.inc - -for.inc: ; preds = %for.body - %2 = load i32, i32* %i, align 4 - %inc = add nsw i32 %2, 1 - store i32 %inc, i32* %i, align 4 - br label %for.cond, !llvm.loop !20 - -for.end: ; preds = %for.cond - ret void -} - attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "denorms-are-zero"="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" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0} @@ -355,38 +186,18 @@ attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide !9 = distinct !{!9, !10} !10 = !{!"llvm.loop.max_concurrency.count", i32 2} !11 = distinct !{!11, !8, !10} -!12 = distinct !{!12, !13} -!13 = !{!"llvm.loop.intel.pipelining.enable", i32 1} -!14 = distinct !{!14, !15} -!15 = !{!"llvm.loop.coalesce.count", i32 4} -!16 = distinct !{!16, !17} -!17 = !{!"llvm.loop.coalesce.enable"} -!18 = distinct !{!18, !19} -!19 = !{!"llvm.loop.max_interleaving.count", i32 3} -!20 = distinct !{!20, !21} -!21 = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} ; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_A:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_B:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_C:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_D:[0-9]+]] ; CHECK-LLVM: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_E:[0-9]+]] -; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_F:[0-9]+]] -; CHECK-LLVM: br label %while.cond{{[0-9]*}}, !llvm.loop ![[MD_G:[0-9]+]] -; CHECK-LLVM: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_H:[0-9]+]] -; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_I:[0-9]+]] -; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_J:[0-9]+]] ; CHECK-LLVM-NEGATIVE: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_A:[0-9]+]] ; CHECK-LLVM-NEGATIVE: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_B:[0-9]+]] ; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_C:[0-9]+]] ; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_D:[0-9]+]] ; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]+}}, !llvm.loop ![[MD_E:[0-9]+]] -; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_F:[0-9]+]] -; CHECK-LLVM-NEGATIVE-NOT: br label %while.cond{{[0-9]*}}, !llvm.loop ![[MD_G:[0-9]+]] -; CHECK-LLVM-NEGATIVE-NOT: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_H:[0-9]+]] -; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_I:[0-9]+]] -; CHECK-LLVM-NEGATIVE-NOT: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_J:[0-9]+]] ; CHECK-LLVM: ![[MD_A]] = distinct !{![[MD_A]], ![[MD_ivdep_enable:[0-9]+]]} ; CHECK-LLVM: ![[MD_ivdep_enable]] = !{!"llvm.loop.ivdep.enable"} @@ -397,17 +208,6 @@ attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide ; CHECK-LLVM: ![[MD_D]] = distinct !{![[MD_D]], ![[MD_max_concurrency:[0-9]+]]} ; CHECK-LLVM: ![[MD_max_concurrency]] = !{!"llvm.loop.max_concurrency.count", i32 2} ; CHECK-LLVM: ![[MD_E]] = distinct !{![[MD_E]], ![[MD_ii:[0-9]+]], ![[MD_max_concurrency:[0-9]+]]} -; CHECK-LLVM: ![[MD_F]] = distinct !{![[MD_F]], ![[MD_pipelining:[0-9]+]]} -; CHECK-LLVM: ![[MD_pipelining]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} -; CHECK-LLVM: ![[MD_G]] = distinct !{![[MD_G]], ![[MD_loop_coalesce_count:[0-9]+]]} -; CHECK-LLVM: ![[MD_loop_coalesce_count]] = !{!"llvm.loop.coalesce.count", i32 4} -; CHECK-LLVM: ![[MD_H]] = distinct !{![[MD_H]], ![[MD_loop_coalesce:[0-9]+]]} -; CHECK-LLVM: ![[MD_loop_coalesce]] = !{![[MD_loop_coalesce_enable:[0-9]+]]} -; CHECK-LLVM: ![[MD_loop_coalesce_enable]] = !{!"llvm.loop.coalesce.enable"} -; CHECK-LLVM: ![[MD_I]] = distinct !{![[MD_I]], ![[MD_max_interleaving:[0-9]+]]} -; CHECK-LLVM: ![[MD_max_interleaving]] = !{!"llvm.loop.max_interleaving.count", i32 3} -; CHECK-LLVM: ![[MD_J]] = distinct !{![[MD_J]], ![[MD_spec_iterations:[0-9]+]]} -; CHECK-LLVM: ![[MD_spec_iterations]] = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} ; CHECK-LLVM-NEGATIVE: ![[MD_A]] = distinct !{![[MD_A]], ![[MD_ivdep_enable:[0-9]+]]} ; CHECK-LLVM-NEGATIVE: ![[MD_ivdep_enable]] = !{!"llvm.loop.ivdep.enable"} @@ -418,14 +218,3 @@ attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide ; CHECK-LLVM-NEGATIVE-NOT: ![[MD_D]] = distinct !{![[MD_D]], ![[MD_max_concurrency:[0-9]+]]} ; CHECK-LLVM-NEGATIVE-NOT: ![[MD_max_concurrency]] = !{!"llvm.loop.max_concurrency.count", i32 2} ; CHECK-LLVM-NEGATIVE-NOT: ![[MD_E]] = distinct !{![[MD_E]], ![[MD_ii:[0-9]+]], ![[MD_max_concurrency:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_F]] = distinct !{![[MD_F]], ![[MD_pipelining:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_pipelining]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_G]] = distinct !{![[MD_G]], ![[MD_loop_coalesce_count:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_loop_coalesce_count]] = !{!"llvm.loop.coalesce.count", i32 4} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_H]] = distinct !{![[MD_H]], ![[MD_loop_coalesce:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_loop_coalesce]] = !{![[MD_loop_coalesce_enable:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_loop_coalesce_enable]] = !{!"llvm.loop.coalesce.enable"} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_I]] = distinct !{![[MD_I]], ![[MD_max_interleaving:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_max_interleaving]] = !{!"llvm.loop.max_interleaving.count", i32 3} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_J]] = distinct !{![[MD_J]], ![[MD_spec_iterations:[0-9]+]]} -; CHECK-LLVM-NEGATIVE-NOT: ![[MD_spec_iterations]] = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} \ No newline at end of file diff --git a/test/transcoding/FPGALoopMergeInst.ll b/test/transcoding/FPGALoopMergeInst.ll index e7f7f70fc4..3ae05d91a6 100644 --- a/test/transcoding/FPGALoopMergeInst.ll +++ b/test/transcoding/FPGALoopMergeInst.ll @@ -44,6 +44,46 @@ ; } ; } +; void loop_pipelining() { +; int a[10]; +; [[intelfpga::disable_loop_pipelining]] +; for (int i = 0; i != 10; ++i) +; a[i] = 0; +; } + +; void loop_coalesce() { +; int i = 0, m = 42; +; [[intelfpga::loop_coalesce(4)]] +; while (i < m) { +; if (i % 2) { +; ++i; +; continue; +; } +; } +; i = 0; +; [[intelfpga::loop_coalesce]] +; while (i < m) { +; if (i % 3) { +; ++i; +; continue; +; } +; } +; } + +; void max_interleaving() { +; int a[10]; +; [[intelfpga::max_interleaving(3)]] +; for (int i = 0; i != 10; ++i) +; a[i] = 0; +; } + +; void speculated_iterations() { +; int a[10]; +; [[intelfpga::speculated_iterations(4)]] +; for (int i = 0; i != 10; ++i) +; a[i] = 0; +; } + ; TODO: This source code will result in different LLVM IR after ; rev [a47242e4b2c1c9] of https://github.com/intel/llvm (the ; [[intelfpga::ivdep]] attribute will be represented otherwise). @@ -228,6 +268,175 @@ while.end30: ; preds = %if.then28 ret void } +; Function Attrs: noinline nounwind optnone +define spir_func void @loop_pipelining() #3 { +entry: + %a = alloca [10 x i32], align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +; Per SPIR-V spec, LoopControlPipelineEnableINTEL = 0x80000 (524288) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 524288 1 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 524288 1 +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp ne i32 %0, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom + store i32 0, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %2 = load i32, i32* %i, align 4 + %inc = add nsw i32 %2, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !19 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone +define spir_func void @loop_coalesce() #3 { +entry: + %i = alloca i32, align 4 + %m = alloca i32, align 4 + store i32 0, i32* %i, align 4 + store i32 42, i32* %m, align 4 + br label %while.cond + +; Per SPIR-V spec, LoopControlLoopCoalesceINTEL = 0x100000 (1048576) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 4 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 4 +while.cond: ; preds = %if.end, %if.then, %entry + %0 = load i32, i32* %i, align 4 + %1 = load i32, i32* %m, align 4 + %cmp = icmp slt i32 %0, %1 + br i1 %cmp, label %while.body, label %while.end + +while.body: ; preds = %while.cond + %2 = load i32, i32* %i, align 4 + %rem = srem i32 %2, 2 + %tobool = icmp ne i32 %rem, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: ; preds = %while.body + %3 = load i32, i32* %i, align 4 + %inc = add nsw i32 %3, 1 + store i32 %inc, i32* %i, align 4 + br label %while.cond, !llvm.loop !21 + +if.end: ; preds = %while.body + br label %while.cond, !llvm.loop !21 + +while.end: ; preds = %while.cond + store i32 0, i32* %i, align 4 + br label %while.cond1 + +; Per SPIR-V spec, LoopControlLoopCoalesceINTEL = 0x100000 (1048576) +; CHECK-SPIRV: 4 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 4 LoopMerge {{[0-9]+}} {{[0-9]+}} 1048576 +while.cond1: ; preds = %if.end8, %if.then6, %while.end + %4 = load i32, i32* %i, align 4 + %5 = load i32, i32* %m, align 4 + %cmp2 = icmp slt i32 %4, %5 + br i1 %cmp2, label %while.body3, label %while.end9 + +while.body3: ; preds = %while.cond1 + %6 = load i32, i32* %i, align 4 + %rem4 = srem i32 %6, 3 + %tobool5 = icmp ne i32 %rem4, 0 + br i1 %tobool5, label %if.then6, label %if.end8 + +if.then6: ; preds = %while.body3 + %7 = load i32, i32* %i, align 4 + %inc7 = add nsw i32 %7, 1 + store i32 %inc7, i32* %i, align 4 + br label %while.cond1, !llvm.loop !23 + +if.end8: ; preds = %while.body3 + br label %while.cond1, !llvm.loop !23 + +while.end9: ; preds = %while.cond1 + ret void +} + +; Function Attrs: noinline nounwind optnone +define spir_func void @max_interleaving() #3 { +entry: + %a = alloca [10 x i32], align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +; Per SPIR-V spec, LoopControlMaxInterleavingINTEL = 0x200000 (2097152) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 2097152 3 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 2097152 3 +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp ne i32 %0, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom + store i32 0, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %2 = load i32, i32* %i, align 4 + %inc = add nsw i32 %2, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !25 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone +define spir_func void @speculated_iterations() #3 { +entry: + %a = alloca [10 x i32], align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +; Per SPIR-V spec, LoopControlSpeculatedIterationsINTEL = 0x400000 (4194304) +; CHECK-SPIRV: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 4194304 4 +; CHECK-SPIRV-NEXT: 4 BranchConditional {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV-NEGATIVE-NOT: 5 LoopMerge {{[0-9]+}} {{[0-9]+}} 4194304 4 +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp ne i32 %0, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 %idxprom + store i32 0, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %2 = load i32, i32* %i, align 4 + %inc = add nsw i32 %2, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !27 + +for.end: ; preds = %for.cond + ret void +} + attributes #0 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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" "sycl-module-id"="FPGALoopMergeInst.cpp" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { argmemonly nounwind willreturn } attributes #2 = { inlinehint nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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" } @@ -258,11 +467,26 @@ attributes #4 = { nounwind } !16 = !{!"llvm.loop.max_concurrency.count", i32 4} !17 = distinct !{!17, !18} !18 = !{!"llvm.loop.ivdep.safelen", i32 2} +!19 = distinct !{!19, !20} +!20 = !{!"llvm.loop.intel.pipelining.enable", i32 1} +!21 = distinct !{!21, !22} +!22 = !{!"llvm.loop.coalesce.count", i32 4} +!23 = distinct !{!23, !24} +!24 = !{!"llvm.loop.coalesce.enable"} +!25 = distinct !{!25, !26} +!26 = !{!"llvm.loop.max_interleaving.count", i32 3} +!27 = distinct !{!27, !28} +!28 = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} ; CHECK-LLVM: br label %while.cond, !llvm.loop ![[MD_A:[0-9]+]] ; CHECK-LLVM: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_B:[0-9]+]] ; CHECK-LLVM: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_C:[0-9]+]] ; CHECK-LLVM: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_D:[0-9]+]] +; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_E:[0-9]+]] +; CHECK-LLVM: br label %while.cond{{[0-9]*}}, !llvm.loop ![[MD_F:[0-9]+]] +; CHECK-LLVM: br label %while.cond{{[0-9]+}}, !llvm.loop ![[MD_G:[0-9]+]] +; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_H:[0-9]+]] +; CHECK-LLVM: br label %for.cond{{[0-9]*}}, !llvm.loop ![[MD_I:[0-9]+]] ; CHECK-LLVM: ![[MD_A]] = distinct !{![[MD_A]], ![[MD_ivdep_enable:[0-9]+]]} ; CHECK-LLVM: ![[MD_ivdep_enable]] = !{!"llvm.loop.ivdep.enable"} @@ -272,3 +496,14 @@ attributes #4 = { nounwind } ; CHECK-LLVM: ![[MD_max_conc]] = !{!"llvm.loop.max_concurrency.count", i32 4} ; CHECK-LLVM: ![[MD_D]] = distinct !{![[MD_D]], ![[MD_ivdep:[0-9]+]]} ; CHECK-LLVM: ![[MD_ivdep]] = !{!"llvm.loop.ivdep.safelen", i32 2} +; CHECK-LLVM: ![[MD_E]] = distinct !{![[MD_E]], ![[MD_pipelining:[0-9]+]]} +; CHECK-LLVM: ![[MD_pipelining]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} +; CHECK-LLVM: ![[MD_F]] = distinct !{![[MD_F]], ![[MD_loop_coalesce_count:[0-9]+]]} +; CHECK-LLVM: ![[MD_loop_coalesce_count]] = !{!"llvm.loop.coalesce.count", i32 4} +; CHECK-LLVM: ![[MD_G]] = distinct !{![[MD_G]], ![[MD_loop_coalesce:[0-9]+]]} +; CHECK-LLVM: ![[MD_loop_coalesce]] = !{![[MD_loop_coalesce_enable:[0-9]+]]} +; CHECK-LLVM: ![[MD_loop_coalesce_enable]] = !{!"llvm.loop.coalesce.enable"} +; CHECK-LLVM: ![[MD_H]] = distinct !{![[MD_H]], ![[MD_max_interleaving:[0-9]+]]} +; CHECK-LLVM: ![[MD_max_interleaving]] = !{!"llvm.loop.max_interleaving.count", i32 3} +; CHECK-LLVM: ![[MD_I]] = distinct !{![[MD_I]], ![[MD_spec_iterations:[0-9]+]]} +; CHECK-LLVM: ![[MD_spec_iterations]] = !{!"llvm.loop.intel.speculated.iterations.count", i32 4} From 13c007151ae63773b9454d39f1d2aa7b9f985635 Mon Sep 17 00:00:00 2001 From: Viktoria Maksimova Date: Thu, 26 Mar 2020 15:56:50 +0300 Subject: [PATCH 3/3] Apply more suggestions --- lib/SPIRV/SPIRVReader.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index ed35a0b347..2cccd0f1aa 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -795,14 +795,15 @@ void SPIRVToLLVM::setLLVMLoopMetadata(const LoopInstType *LM, "Missing loop control parameter!"); } if (LC & LoopControlLoopCoalesceINTEL) { - if (LoopControlParameters.size()) { + // If LoopCoalesce has no parameters + if (LoopControlParameters.empty()) { + Metadata.push_back(llvm::MDNode::get( + *Context, getMetadataFromName("llvm.loop.coalesce.enable"))); + } else { Metadata.push_back(llvm::MDNode::get( *Context, getMetadataFromNameAndParameter("llvm.loop.coalesce.count", LoopControlParameters[NumParam++]))); - } else { // If LoopCoalesce has no parameters - Metadata.push_back(llvm::MDNode::get( - *Context, getMetadataFromName("llvm.loop.coalesce.enable"))); } assert(NumParam <= LoopControlParameters.size() && "Missing loop control parameter!");