314 lines
10 KiB
LLVM
314 lines
10 KiB
LLVM
; Source:
|
|
; /*** for ***/
|
|
; void for_count()
|
|
; {
|
|
; __attribute__((opencl_unroll_hint(1)))
|
|
; for( int i = 0; i < 1024; ++i) {
|
|
; if(i%2) continue;
|
|
; int x = i;
|
|
; }
|
|
; }
|
|
;
|
|
; /*** while ***/
|
|
; void while_count()
|
|
; {
|
|
; int i = 1024;
|
|
; __attribute__((opencl_unroll_hint(8)))
|
|
; while(i-->0) {
|
|
; if(i%2) continue;
|
|
; int x = i;
|
|
; }
|
|
; }
|
|
;
|
|
; /*** do ***/
|
|
; void do_count()
|
|
; {
|
|
; int i = 1024;
|
|
; __attribute__((opencl_unroll_hint))
|
|
; do {
|
|
; if(i%2) continue;
|
|
; int x = i;
|
|
; } while(i--> 0);
|
|
; }
|
|
;
|
|
; for_count_unusual() is a synthetically written function
|
|
;
|
|
; Command:
|
|
; clang -cc1 -triple spir64 -O0 LoopUnroll.cl -emit-llvm -o /test/SPIRV/transcoding/LoopUnroll.ll
|
|
;
|
|
; unroll_full() test was generated from the following source with -O2
|
|
; void foo();
|
|
;
|
|
; void unroll_full() {
|
|
; #pragma clang unroll(full)
|
|
; for (int i = 0; i != 1024; ++i) {
|
|
; foo();
|
|
; }
|
|
; }
|
|
|
|
; RUN: llvm-as < %s > %t.bc
|
|
; RUN: llvm-spirv %t.bc -o %t.spv
|
|
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
|
|
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
|
|
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
|
|
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefixes=CHECK-LLVM
|
|
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-max-version=1.1
|
|
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
|
|
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV-NEGATIVE
|
|
|
|
; Check SPIR-V versions in a format magic number + version
|
|
; CHECK-SPIRV: 119734787 66560
|
|
; CHECK-SPIRV-NEGATIVE: 119734787 65536
|
|
|
|
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
|
|
target triple = "spir64"
|
|
|
|
; CHECK-SPIRV: Function
|
|
; Function Attrs: noinline nounwind optnone
|
|
define spir_func void @for_count() #0 {
|
|
entry:
|
|
; CHECK-SPIRV: Label
|
|
%i = alloca i32, align 4
|
|
%x = alloca i32, align 4
|
|
store i32 0, ptr %i, align 4
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.inc, %entry
|
|
; CHECK-SPIRV: Label [[#HEADER:]]
|
|
%0 = load i32, ptr %i, align 4
|
|
%cmp = icmp slt i32 %0, 1024
|
|
; Per SPIRV spec p3.23 "DontUnroll" loop control = 0x2
|
|
; CHECK-SPIRV: LoopMerge [[#MERGEBLOCK:]] [[#CONTINUE:]] 2
|
|
; CHECK-SPIRV: BranchConditional [[#]] [[#]] [[#MERGEBLOCK]]
|
|
br i1 %cmp, label %for.body, label %for.end
|
|
|
|
for.body: ; preds = %for.cond
|
|
; CHECK-SPIRV: Label
|
|
%1 = load i32, ptr %i, align 4
|
|
%rem = srem i32 %1, 2
|
|
%tobool = icmp ne i32 %rem, 0
|
|
br i1 %tobool, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %for.body
|
|
; CHECK-SPIRV: Label
|
|
br label %for.inc
|
|
|
|
if.end: ; preds = %for.body
|
|
; CHECK-SPIRV: Label
|
|
%2 = load i32, ptr %i, align 4
|
|
store i32 %2, ptr %x, align 4
|
|
br label %for.inc
|
|
|
|
for.inc: ; preds = %if.end, %if.then
|
|
; CHECK-SPIRV: Label [[#CONTINUE]]
|
|
%3 = load i32, ptr %i, align 4
|
|
%inc = add nsw i32 %3, 1
|
|
store i32 %inc, ptr %i, align 4
|
|
br label %for.cond, !llvm.loop !5
|
|
; CHECK-LLVM: br label %for.cond, !llvm.loop ![[#UNROLLDISABLE:]]
|
|
; CHECK-SPIRV: Branch [[#HEADER]]
|
|
|
|
for.end: ; preds = %for.cond
|
|
; CHECK-SPIRV: Label [[#MERGEBLOCK]]
|
|
ret void
|
|
}
|
|
|
|
; CHECK-SPIRV: Function
|
|
; Function Attrs: noinline nounwind optnone
|
|
define spir_func void @while_count() #0 {
|
|
entry:
|
|
; CHECK-SPIRV: Label
|
|
%i = alloca i32, align 4
|
|
%x = alloca i32, align 4
|
|
store i32 1024, ptr %i, align 4
|
|
br label %while.cond
|
|
|
|
while.cond: ; preds = %if.end, %if.then, %entry
|
|
; CHECK-SPIRV: Label [[#HEADER:]]
|
|
%0 = load i32, ptr %i, align 4
|
|
%dec = add nsw i32 %0, -1
|
|
store i32 %dec, ptr %i, align 4
|
|
%cmp = icmp sgt i32 %0, 0
|
|
; Per SPIRV spec p3.23 "Unroll" loop control = 0x1
|
|
; CHECK-SPIRV: LoopMerge [[#MERGEBLOCK:]] [[#CONTINUE:]] 256 8
|
|
; CHECK-SPIRV: BranchConditional [[#]] [[#]] [[#MERGEBLOCK]]
|
|
; CHECK-SPIRV-NEGATIVE-NOT: LoopMerge {{.*}} 256
|
|
br i1 %cmp, label %while.body, label %while.end
|
|
|
|
while.body: ; preds = %while.cond
|
|
; CHECK-SPIRV: Label
|
|
%1 = load i32, ptr %i, align 4
|
|
%rem = srem i32 %1, 2
|
|
%tobool = icmp ne i32 %rem, 0
|
|
br i1 %tobool, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %while.body
|
|
; CHECK-SPIRV: Label
|
|
; CHECK-LLVM: br label %while.cond, !llvm.loop ![[#UNROLLCOUNT:]]
|
|
br label %while.cond, !llvm.loop !7
|
|
|
|
; loop-simplify pass will create extra basic block which is the only one in
|
|
; loop having a back-edge to the header
|
|
; CHECK-SPIRV: [[#CONTINUE]]
|
|
; CHECK-SPIRV: Branch [[#HEADER]]
|
|
|
|
if.end: ; preds = %while.body
|
|
; CHECK-SPIRV: Label
|
|
%2 = load i32, ptr %i, align 4
|
|
store i32 %2, ptr %x, align 4
|
|
br label %while.cond, !llvm.loop !7
|
|
|
|
while.end: ; preds = %while.cond
|
|
; CHECK-SPIRV: [[#MERGEBLOCK]]
|
|
ret void
|
|
}
|
|
|
|
; CHECK-SPIRV: Function
|
|
; Function Attrs: noinline nounwind optnone
|
|
define spir_func void @do_count() #0 {
|
|
entry:
|
|
; CHECK-SPIRV: Label
|
|
%i = alloca i32, align 4
|
|
%x = alloca i32, align 4
|
|
store i32 1024, ptr %i, align 4
|
|
br label %do.body
|
|
|
|
do.body: ; preds = %do.cond, %entry
|
|
; CHECK-SPIRV: Label [[#HEADER:]]
|
|
%0 = load i32, ptr %i, align 4
|
|
%rem = srem i32 %0, 2
|
|
%tobool = icmp ne i32 %rem, 0
|
|
; Per SPIRV spec p3.23 "Unroll" loop control = 0x1
|
|
; CHECK-SPIRV: LoopMerge [[#MERGEBLOCK:]] [[#CONTINUE:]] 1
|
|
; CHECK-SPIRV: BranchConditional
|
|
br i1 %tobool, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %do.body
|
|
; CHECK-SPIRV: Label
|
|
br label %do.cond
|
|
|
|
if.end: ; preds = %do.body
|
|
; CHECK-SPIRV: Label
|
|
%1 = load i32, ptr %i, align 4
|
|
store i32 %1, ptr %x, align 4
|
|
br label %do.cond
|
|
|
|
do.cond: ; preds = %if.end, %if.then
|
|
; CHECK-SPIRV: Label [[#CONTINUE]]
|
|
%2 = load i32, ptr %i, align 4
|
|
%dec = add nsw i32 %2, -1
|
|
store i32 %dec, ptr %i, align 4
|
|
%cmp = icmp sgt i32 %2, 0
|
|
; CHECK-SPIRV: BranchConditional [[#]] [[#HEADER]] [[#MERGEBLOCK]]
|
|
; CHECK-LLVM: br i1 %cmp, label %do.body, label %do.end, !llvm.loop ![[#UNROLLENABLE1:]]
|
|
br i1 %cmp, label %do.body, label %do.end, !llvm.loop !9
|
|
|
|
do.end: ; preds = %do.cond
|
|
; CHECK-SPIRV: Label [[#MERGEBLOCK]]
|
|
ret void
|
|
}
|
|
|
|
; CHECK-SPIRV: Function
|
|
; Function Attrs: noinline nounwind optnone
|
|
define spir_func void @for_count_unusual() #0 {
|
|
entry:
|
|
; CHECK-SPIRV: Label
|
|
%i = alloca i32, align 4
|
|
%x = alloca i32, align 4
|
|
store i32 1024, ptr %i, align 4
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %for.cond, %entry
|
|
; CHECK-SPIRV: Label [[#HEADER:]]
|
|
%0 = load i32, ptr %i, align 4
|
|
%rem = srem i32 %0, 2
|
|
%tobool = icmp ne i32 %rem, 0
|
|
; Per SPIRV spec p3.23 "Unroll" loop control = 0x1
|
|
; CHECK-SPIRV: LoopMerge [[#MERGEBLOCK:]] [[#CONTINUE:]] 1
|
|
; CHECK-SPIRV: BranchConditional
|
|
br i1 %tobool, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %for.body
|
|
; CHECK-SPIRV: Label
|
|
br label %for.cond
|
|
|
|
if.end: ; preds = %for.body
|
|
; CHECK-SPIRV: Label
|
|
%1 = load i32, ptr %i, align 4
|
|
store i32 %1, ptr %x, align 4
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %if.end, %if.then
|
|
; CHECK-SPIRV: Label [[#CONTINUE]]
|
|
%2 = load i32, ptr %i, align 4
|
|
%dec = add nsw i32 %2, -1
|
|
store i32 %dec, ptr %i, align 4
|
|
%cmp = icmp sgt i32 %2, 0
|
|
; CHECK-SPIRV: BranchConditional [[#]] [[#MERGEBLOCK]] [[#HEADER]]
|
|
; CHECK-LLVM: br i1 %cmp, label %for.end, label %for.body, !llvm.loop ![[#UNROLLENABLE2:]]
|
|
br i1 %cmp, label %for.end, label %for.body, !llvm.loop !9
|
|
|
|
for.end: ; preds = %for.cond
|
|
; CHECK-SPIRV: Label [[#MERGEBLOCK]]
|
|
ret void
|
|
}
|
|
|
|
; CHECK-SPIRV: Function
|
|
; CHECK-SPIRV: Label
|
|
; CHECK-SPIRV: Branch [[#Header:]]
|
|
; CHECK-SPIRV: LoopMerge [[#Return:]] [[#Header]] 257 1
|
|
; CHECK-SPIRV: BranchConditional [[#]] [[#Return]] [[#Header]]
|
|
; CHECK-SPIRV: Label [[#Return]]
|
|
; Function Attrs: noinline nounwind optnone
|
|
define spir_func void @unroll_full() {
|
|
br label %2
|
|
|
|
1: ; preds = %2
|
|
ret void
|
|
|
|
2: ; preds = %0, %2
|
|
%3 = phi i32 [ 0, %0 ], [ %4, %2 ]
|
|
tail call void @_Z3foov()
|
|
%4 = add nuw nsw i32 %3, 1
|
|
%5 = icmp eq i32 %4, 1024
|
|
; CHECK-LLVM: br i1 %[[#]], label %[[#]], label %[[#]], !llvm.loop ![[#FULL:]]
|
|
br i1 %5, label %1, label %2, !llvm.loop !11
|
|
}
|
|
|
|
declare void @_Z3foov()
|
|
|
|
attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "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}
|
|
!opencl.enable.FP_CONTRACT = !{}
|
|
!opencl.ocl.version = !{!1}
|
|
!opencl.spir.version = !{!2}
|
|
!opencl.used.extensions = !{!3}
|
|
!opencl.used.optional.core.features = !{!3}
|
|
!opencl.compiler.options = !{!3}
|
|
!llvm.ident = !{!4}
|
|
|
|
!0 = !{i32 1, !"wchar_size", i32 4}
|
|
!1 = !{i32 1, i32 0}
|
|
!2 = !{i32 1, i32 2}
|
|
!3 = !{}
|
|
!4 = !{!"clang version 5.0.1 (cfe/trunk)"}
|
|
!5 = distinct !{!5, !6}
|
|
!6 = !{!"llvm.loop.unroll.disable"}
|
|
!7 = distinct !{!7, !8}
|
|
!8 = !{!"llvm.loop.unroll.count", i32 8}
|
|
!9 = distinct !{!9, !10}
|
|
!10 = !{!"llvm.loop.unroll.enable"}
|
|
!11 = distinct !{!11, !12}
|
|
!12 = !{!"llvm.loop.unroll.full"}
|
|
|
|
; CHECK-LLVM: ![[#UNROLLDISABLE]] = distinct !{![[#UNROLLDISABLE]], ![[#DISABLE:]]}
|
|
; CHECK-LLVM: ![[#DISABLE]] = !{!"llvm.loop.unroll.disable"}
|
|
; CHECK-LLVM: ![[#UNROLLCOUNT]] = distinct !{![[#UNROLLCOUNT]], ![[#COUNT:]]}
|
|
; CHECK-LLVM: ![[#COUNT]] = !{!"llvm.loop.unroll.count", i32 8}
|
|
; CHECK-LLVM: ![[#UNROLLENABLE1]] = distinct !{![[#UNROLLENABLE1]], ![[#ENABLE:]]}
|
|
; CHECK-LLVM: ![[#ENABLE]] = !{!"llvm.loop.unroll.enable"}
|
|
; CHECK-LLVM: ![[#UNROLLENABLE2]] = distinct !{![[#UNROLLENABLE2]], ![[#ENABLE]]}
|
|
; CHECK-LLVM: ![[#FULL]] = distinct !{![[#FULL]], ![[#UNROLLFULL:]]}
|
|
; CHECK-LLVM: ![[#UNROLLFULL]] = !{!"llvm.loop.unroll.full"}
|