1// RUN: mlir-translate -split-input-file -test-spirv-roundtrip %s | FileCheck %s 2 3// Single loop 4 5spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 6 // for (int i = 0; i < count; ++i) {} 7 spv.func @loop(%count : i32) -> () "None" { 8 %zero = spv.Constant 0: i32 9 %one = spv.Constant 1: i32 10 %var = spv.Variable init(%zero) : !spv.ptr<i32, Function> 11 12// CHECK: spv.Branch ^bb1 13// CHECK-NEXT: ^bb1: 14// CHECK-NEXT: spv.mlir.loop 15 spv.mlir.loop { 16// CHECK-NEXT: spv.Branch ^bb1 17 spv.Branch ^header 18 19// CHECK-NEXT: ^bb1: 20 ^header: 21// CHECK-NEXT: spv.Load 22 %val0 = spv.Load "Function" %var : i32 23// CHECK-NEXT: spv.SLessThan 24 %cmp = spv.SLessThan %val0, %count : i32 25// CHECK-NEXT: spv.BranchConditional %{{.*}} [1, 1], ^bb2, ^bb4 26 spv.BranchConditional %cmp [1, 1], ^body, ^merge 27 28// CHECK-NEXT: ^bb2: 29 ^body: 30 // Do nothing 31// CHECK-NEXT: spv.Branch ^bb3 32 spv.Branch ^continue 33 34// CHECK-NEXT: ^bb3: 35 ^continue: 36// CHECK-NEXT: spv.Load 37 %val1 = spv.Load "Function" %var : i32 38// CHECK-NEXT: spv.Constant 1 39// CHECK-NEXT: spv.IAdd 40 %add = spv.IAdd %val1, %one : i32 41// CHECK-NEXT: spv.Store 42 spv.Store "Function" %var, %add : i32 43// CHECK-NEXT: spv.Branch ^bb1 44 spv.Branch ^header 45 46// CHECK-NEXT: ^bb4: 47// CHECK-NEXT: spv.mlir.merge 48 ^merge: 49 spv.mlir.merge 50 } 51 spv.Return 52 } 53 54 spv.func @main() -> () "None" { 55 spv.Return 56 } 57 spv.EntryPoint "GLCompute" @main 58} 59 60// ----- 61 62spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 63 spv.GlobalVariable @GV1 bind(0, 0) : !spv.ptr<!spv.struct<(!spv.array<10 x f32, stride=4> [0])>, StorageBuffer> 64 spv.GlobalVariable @GV2 bind(0, 1) : !spv.ptr<!spv.struct<(!spv.array<10 x f32, stride=4> [0])>, StorageBuffer> 65 spv.func @loop_kernel() "None" { 66 %0 = spv.mlir.addressof @GV1 : !spv.ptr<!spv.struct<(!spv.array<10 x f32, stride=4> [0])>, StorageBuffer> 67 %1 = spv.Constant 0 : i32 68 %2 = spv.AccessChain %0[%1] : !spv.ptr<!spv.struct<(!spv.array<10 x f32, stride=4> [0])>, StorageBuffer>, i32 69 %3 = spv.mlir.addressof @GV2 : !spv.ptr<!spv.struct<(!spv.array<10 x f32, stride=4> [0])>, StorageBuffer> 70 %5 = spv.AccessChain %3[%1] : !spv.ptr<!spv.struct<(!spv.array<10 x f32, stride=4> [0])>, StorageBuffer>, i32 71 %6 = spv.Constant 4 : i32 72 %7 = spv.Constant 42 : i32 73 %8 = spv.Constant 2 : i32 74// CHECK: spv.Branch ^bb1(%{{.*}} : i32) 75// CHECK-NEXT: ^bb1(%[[OUTARG:.*]]: i32): 76// CHECK-NEXT: spv.mlir.loop { 77 spv.mlir.loop { 78// CHECK-NEXT: spv.Branch ^bb1(%[[OUTARG]] : i32) 79 spv.Branch ^header(%6 : i32) 80// CHECK-NEXT: ^bb1(%[[HEADARG:.*]]: i32): 81 ^header(%9: i32): 82 %10 = spv.SLessThan %9, %7 : i32 83// CHECK: spv.BranchConditional %{{.*}}, ^bb2, ^bb3 84 spv.BranchConditional %10, ^body, ^merge 85// CHECK-NEXT: ^bb2: // pred: ^bb1 86 ^body: 87 %11 = spv.AccessChain %2[%9] : !spv.ptr<!spv.array<10 x f32, stride=4>, StorageBuffer>, i32 88 %12 = spv.Load "StorageBuffer" %11 : f32 89 %13 = spv.AccessChain %5[%9] : !spv.ptr<!spv.array<10 x f32, stride=4>, StorageBuffer>, i32 90 spv.Store "StorageBuffer" %13, %12 : f32 91// CHECK: %[[ADD:.*]] = spv.IAdd 92 %14 = spv.IAdd %9, %8 : i32 93// CHECK-NEXT: spv.Branch ^bb1(%[[ADD]] : i32) 94 spv.Branch ^header(%14 : i32) 95// CHECK-NEXT: ^bb3: 96 ^merge: 97// CHECK-NEXT: spv.mlir.merge 98 spv.mlir.merge 99 } 100 spv.Return 101 } 102 spv.EntryPoint "GLCompute" @loop_kernel 103 spv.ExecutionMode @loop_kernel "LocalSize", 1, 1, 1 104} 105 106// ----- 107 108// Nested loop 109 110spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 111 // for (int i = 0; i < count; ++i) { 112 // for (int j = 0; j < count; ++j) { } 113 // } 114 spv.func @loop(%count : i32) -> () "None" { 115 %zero = spv.Constant 0: i32 116 %one = spv.Constant 1: i32 117 %ivar = spv.Variable init(%zero) : !spv.ptr<i32, Function> 118 %jvar = spv.Variable init(%zero) : !spv.ptr<i32, Function> 119 120// CHECK: spv.Branch ^bb1 121// CHECK-NEXT: ^bb1: 122// CHECK-NEXT: spv.mlir.loop control(Unroll) 123 spv.mlir.loop control(Unroll) { 124// CHECK-NEXT: spv.Branch ^bb1 125 spv.Branch ^header 126 127// CHECK-NEXT: ^bb1: 128 ^header: 129// CHECK-NEXT: spv.Load 130 %ival0 = spv.Load "Function" %ivar : i32 131// CHECK-NEXT: spv.SLessThan 132 %icmp = spv.SLessThan %ival0, %count : i32 133// CHECK-NEXT: spv.BranchConditional %{{.*}}, ^bb2, ^bb5 134 spv.BranchConditional %icmp, ^body, ^merge 135 136// CHECK-NEXT: ^bb2: 137 ^body: 138// CHECK-NEXT: spv.Constant 0 139// CHECK-NEXT: spv.Store 140 spv.Store "Function" %jvar, %zero : i32 141// CHECK-NEXT: spv.Branch ^bb3 142// CHECK-NEXT: ^bb3: 143// CHECK-NEXT: spv.mlir.loop control(DontUnroll) 144 spv.mlir.loop control(DontUnroll) { 145// CHECK-NEXT: spv.Branch ^bb1 146 spv.Branch ^header 147 148// CHECK-NEXT: ^bb1: 149 ^header: 150// CHECK-NEXT: spv.Load 151 %jval0 = spv.Load "Function" %jvar : i32 152// CHECK-NEXT: spv.SLessThan 153 %jcmp = spv.SLessThan %jval0, %count : i32 154// CHECK-NEXT: spv.BranchConditional %{{.*}}, ^bb2, ^bb4 155 spv.BranchConditional %jcmp, ^body, ^merge 156 157// CHECK-NEXT: ^bb2: 158 ^body: 159 // Do nothing 160// CHECK-NEXT: spv.Branch ^bb3 161 spv.Branch ^continue 162 163// CHECK-NEXT: ^bb3: 164 ^continue: 165// CHECK-NEXT: spv.Load 166 %jval1 = spv.Load "Function" %jvar : i32 167// CHECK-NEXT: spv.Constant 1 168// CHECK-NEXT: spv.IAdd 169 %add = spv.IAdd %jval1, %one : i32 170// CHECK-NEXT: spv.Store 171 spv.Store "Function" %jvar, %add : i32 172// CHECK-NEXT: spv.Branch ^bb1 173 spv.Branch ^header 174 175// CHECK-NEXT: ^bb4: 176 ^merge: 177// CHECK-NEXT: spv.mlir.merge 178 spv.mlir.merge 179 } // end inner loop 180 181// CHECK: spv.Branch ^bb4 182 spv.Branch ^continue 183 184// CHECK-NEXT: ^bb4: 185 ^continue: 186// CHECK-NEXT: spv.Load 187 %ival1 = spv.Load "Function" %ivar : i32 188// CHECK-NEXT: spv.Constant 1 189// CHECK-NEXT: spv.IAdd 190 %add = spv.IAdd %ival1, %one : i32 191// CHECK-NEXT: spv.Store 192 spv.Store "Function" %ivar, %add : i32 193// CHECK-NEXT: spv.Branch ^bb1 194 spv.Branch ^header 195 196// CHECK-NEXT: ^bb5: 197// CHECK-NEXT: spv.mlir.merge 198 ^merge: 199 spv.mlir.merge 200 } // end outer loop 201 spv.Return 202 } 203 204 spv.func @main() -> () "None" { 205 spv.Return 206 } 207 spv.EntryPoint "GLCompute" @main 208} 209 210