diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 2a128a6669..cdfa978cf0 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}