1// RUN: mlir-translate -split-input-file -test-spirv-roundtrip %s | FileCheck %s 2 3// Test branch with one block argument 4 5spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 6 spv.func @foo() -> () "None" { 7// CHECK: %[[CST:.*]] = spv.constant 0 8 %zero = spv.constant 0 : i32 9// CHECK-NEXT: spv.Branch ^bb1(%[[CST]] : i32) 10 spv.Branch ^bb1(%zero : i32) 11// CHECK-NEXT: ^bb1(%{{.*}}: i32): 12 ^bb1(%arg0: i32): 13 spv.Return 14 } 15 16 spv.func @main() -> () "None" { 17 spv.Return 18 } 19 spv.EntryPoint "GLCompute" @main 20} 21 22// ----- 23 24// Test branch with multiple block arguments 25 26spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 27 spv.func @foo() -> () "None" { 28// CHECK: %[[ZERO:.*]] = spv.constant 0 29 %zero = spv.constant 0 : i32 30// CHECK-NEXT: %[[ONE:.*]] = spv.constant 1 31 %one = spv.constant 1.0 : f32 32// CHECK-NEXT: spv.Branch ^bb1(%[[ZERO]], %[[ONE]] : i32, f32) 33 spv.Branch ^bb1(%zero, %one : i32, f32) 34 35// CHECK-NEXT: ^bb1(%{{.*}}: i32, %{{.*}}: f32): // pred: ^bb0 36 ^bb1(%arg0: i32, %arg1: f32): 37 spv.Return 38 } 39 40 spv.func @main() -> () "None" { 41 spv.Return 42 } 43 spv.EntryPoint "GLCompute" @main 44} 45 46// ----- 47 48// Test using block arguments within branch 49 50spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 51 spv.func @foo() -> () "None" { 52// CHECK: %[[CST0:.*]] = spv.constant 0 53 %zero = spv.constant 0 : i32 54// CHECK-NEXT: spv.Branch ^bb1(%[[CST0]] : i32) 55 spv.Branch ^bb1(%zero : i32) 56 57// CHECK-NEXT: ^bb1(%[[ARG:.*]]: i32): 58 ^bb1(%arg0: i32): 59// CHECK-NEXT: %[[ADD:.*]] = spv.IAdd %[[ARG]], %[[ARG]] : i32 60 %0 = spv.IAdd %arg0, %arg0 : i32 61// CHECK-NEXT: %[[CST1:.*]] = spv.constant 0 62// CHECK-NEXT: spv.Branch ^bb2(%[[CST1]], %[[ADD]] : i32, i32) 63 spv.Branch ^bb2(%zero, %0 : i32, i32) 64 65// CHECK-NEXT: ^bb2(%{{.*}}: i32, %{{.*}}: i32): 66 ^bb2(%arg1: i32, %arg2: i32): 67 spv.Return 68 } 69 70 spv.func @main() -> () "None" { 71 spv.Return 72 } 73 spv.EntryPoint "GLCompute" @main 74} 75 76// ----- 77 78// Test block not following domination order 79 80spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 81 spv.func @foo() -> () "None" { 82// CHECK: spv.Branch ^bb1 83 spv.Branch ^bb1 84 85// CHECK-NEXT: ^bb1: 86// CHECK-NEXT: %[[ZERO:.*]] = spv.constant 0 87// CHECK-NEXT: %[[ONE:.*]] = spv.constant 1 88// CHECK-NEXT: spv.Branch ^bb2(%[[ZERO]], %[[ONE]] : i32, f32) 89 90// CHECK-NEXT: ^bb2(%{{.*}}: i32, %{{.*}}: f32): 91 ^bb2(%arg0: i32, %arg1: f32): 92// CHECK-NEXT: spv.Return 93 spv.Return 94 95 // This block is reordered to follow domination order. 96 ^bb1: 97 %zero = spv.constant 0 : i32 98 %one = spv.constant 1.0 : f32 99 spv.Branch ^bb2(%zero, %one : i32, f32) 100 } 101 102 spv.func @main() -> () "None" { 103 spv.Return 104 } 105 spv.EntryPoint "GLCompute" @main 106} 107 108// ----- 109 110// Test multiple predecessors 111 112spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 113 spv.func @foo() -> () "None" { 114 %var = spv.Variable : !spv.ptr<i32, Function> 115 116// CHECK: spv.selection 117 spv.selection { 118 %true = spv.constant true 119// CHECK: spv.BranchConditional %{{.*}}, ^bb1, ^bb2 120 spv.BranchConditional %true, ^true, ^false 121 122// CHECK-NEXT: ^bb1: 123 ^true: 124// CHECK-NEXT: %[[ZERO:.*]] = spv.constant 0 125 %zero = spv.constant 0 : i32 126// CHECK-NEXT: spv.Branch ^bb3(%[[ZERO]] : i32) 127 spv.Branch ^phi(%zero: i32) 128 129// CHECK-NEXT: ^bb2: 130 ^false: 131// CHECK-NEXT: %[[ONE:.*]] = spv.constant 1 132 %one = spv.constant 1 : i32 133// CHECK-NEXT: spv.Branch ^bb3(%[[ONE]] : i32) 134 spv.Branch ^phi(%one: i32) 135 136// CHECK-NEXT: ^bb3(%[[ARG:.*]]: i32): 137 ^phi(%arg: i32): 138// CHECK-NEXT: spv.Store "Function" %{{.*}}, %[[ARG]] : i32 139 spv.Store "Function" %var, %arg : i32 140// CHECK-NEXT: spv.Return 141 spv.Return 142 143// CHECK-NEXT: ^bb4: 144 ^merge: 145// CHECK-NEXT: spv.mlir.merge 146 spv.mlir.merge 147 } 148 spv.Return 149 } 150 151 spv.func @main() -> () "None" { 152 spv.Return 153 } 154 spv.EntryPoint "GLCompute" @main 155} 156 157// ----- 158 159// Test nested loops with block arguments 160 161spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 162 spv.globalVariable @__builtin_var_NumWorkgroups__ built_in("NumWorkgroups") : !spv.ptr<vector<3xi32>, Input> 163 spv.globalVariable @__builtin_var_WorkgroupId__ built_in("WorkgroupId") : !spv.ptr<vector<3xi32>, Input> 164 spv.func @fmul_kernel() "None" { 165 %3 = spv.constant 12 : i32 166 %4 = spv.constant 32 : i32 167 %5 = spv.constant 4 : i32 168 %6 = spv.mlir.addressof @__builtin_var_WorkgroupId__ : !spv.ptr<vector<3xi32>, Input> 169 %7 = spv.Load "Input" %6 : vector<3xi32> 170 %8 = spv.CompositeExtract %7[0 : i32] : vector<3xi32> 171 %9 = spv.mlir.addressof @__builtin_var_WorkgroupId__ : !spv.ptr<vector<3xi32>, Input> 172 %10 = spv.Load "Input" %9 : vector<3xi32> 173 %11 = spv.CompositeExtract %10[1 : i32] : vector<3xi32> 174 %18 = spv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spv.ptr<vector<3xi32>, Input> 175 %19 = spv.Load "Input" %18 : vector<3xi32> 176 %20 = spv.CompositeExtract %19[0 : i32] : vector<3xi32> 177 %21 = spv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spv.ptr<vector<3xi32>, Input> 178 %22 = spv.Load "Input" %21 : vector<3xi32> 179 %23 = spv.CompositeExtract %22[1 : i32] : vector<3xi32> 180 %30 = spv.IMul %11, %4 : i32 181 %31 = spv.IMul %23, %4 : i32 182 183// CHECK: spv.Branch ^[[FN_BB:.*]](%{{.*}} : i32) 184// CHECK: ^[[FN_BB]](%[[FN_BB_ARG:.*]]: i32): 185// CHECK: spv.loop { 186 spv.loop { 187// CHECK: spv.Branch ^bb1(%[[FN_BB_ARG]] : i32) 188 spv.Branch ^bb1(%30 : i32) 189// CHECK: ^[[LP1_HDR:.*]](%[[LP1_HDR_ARG:.*]]: i32): 190 ^bb1(%32: i32): 191// CHECK: spv.SLessThan 192 %33 = spv.SLessThan %32, %3 : i32 193// CHECK: spv.BranchConditional %{{.*}}, ^[[LP1_BDY:.*]], ^[[LP1_MG:.*]] 194 spv.BranchConditional %33, ^bb2, ^bb3 195// CHECK: ^[[LP1_BDY]]: 196 ^bb2: 197// CHECK: %[[MUL:.*]] = spv.IMul 198 %34 = spv.IMul %8, %5 : i32 199// CHECK: spv.IMul 200 %35 = spv.IMul %20, %5 : i32 201// CHECK: spv.Branch ^[[LP1_CNT:.*]](%[[MUL]] : i32) 202// CHECK: ^[[LP1_CNT]](%[[LP1_CNT_ARG:.*]]: i32): 203// CHECK: spv.loop { 204 spv.loop { 205// CHECK: spv.Branch ^[[LP2_HDR:.*]](%[[LP1_CNT_ARG]] : i32) 206 spv.Branch ^bb1(%34 : i32) 207// CHECK: ^[[LP2_HDR]](%[[LP2_HDR_ARG:.*]]: i32): 208 ^bb1(%37: i32): 209// CHECK: spv.SLessThan %[[LP2_HDR_ARG]] 210 %38 = spv.SLessThan %37, %5 : i32 211// CHECK: spv.BranchConditional %{{.*}}, ^[[LP2_BDY:.*]], ^[[LP2_MG:.*]] 212 spv.BranchConditional %38, ^bb2, ^bb3 213// CHECK: ^[[LP2_BDY]]: 214 ^bb2: 215// CHECK: %[[ADD1:.*]] = spv.IAdd 216 %48 = spv.IAdd %37, %35 : i32 217// CHECK: spv.Branch ^[[LP2_HDR]](%[[ADD1]] : i32) 218 spv.Branch ^bb1(%48 : i32) 219// CHECK: ^[[LP2_MG]]: 220 ^bb3: 221// CHECK: spv.mlir.merge 222 spv.mlir.merge 223 } 224// CHECK: %[[ADD2:.*]] = spv.IAdd %[[LP1_HDR_ARG]] 225 %36 = spv.IAdd %32, %31 : i32 226// CHECK: spv.Branch ^[[LP1_HDR]](%[[ADD2]] : i32) 227 spv.Branch ^bb1(%36 : i32) 228// CHECK: ^[[LP1_MG]]: 229 ^bb3: 230// CHECK: spv.mlir.merge 231 spv.mlir.merge 232 } 233 spv.Return 234 } 235 236 spv.EntryPoint "GLCompute" @fmul_kernel, @__builtin_var_WorkgroupId__, @__builtin_var_NumWorkgroups__ 237 spv.ExecutionMode @fmul_kernel "LocalSize", 32, 1, 1 238} 239 240// ----- 241 242// Test back-to-back loops with block arguments 243 244spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> { 245 spv.func @fmul_kernel() "None" { 246 %cst4 = spv.constant 4 : i32 247 248 %val1 = spv.constant 43 : i32 249 %val2 = spv.constant 44 : i32 250 251// CHECK: spv.constant 43 252// CHECK-NEXT: spv.Branch ^[[BB1:.+]](%{{.+}} : i32) 253// CHECK-NEXT: ^[[BB1]](%{{.+}}: i32): 254// CHECK-NEXT: spv.loop 255 spv.loop { // loop 1 256 spv.Branch ^bb1(%val1 : i32) 257 ^bb1(%loop1_bb_arg: i32): 258 %loop1_lt = spv.SLessThan %loop1_bb_arg, %cst4 : i32 259 spv.BranchConditional %loop1_lt, ^bb2, ^bb3 260 ^bb2: 261 %loop1_add = spv.IAdd %loop1_bb_arg, %cst4 : i32 262 spv.Branch ^bb1(%loop1_add : i32) 263 ^bb3: 264 spv.mlir.merge 265 } 266 267// CHECK: spv.constant 44 268// CHECK-NEXT: spv.Branch ^[[BB2:.+]](%{{.+}} : i32) 269// CHECK-NEXT: ^[[BB2]](%{{.+}}: i32): 270// CHECK-NEXT: spv.loop 271 spv.loop { // loop 2 272 spv.Branch ^bb1(%val2 : i32) 273 ^bb1(%loop2_bb_arg: i32): 274 %loop2_lt = spv.SLessThan %loop2_bb_arg, %cst4 : i32 275 spv.BranchConditional %loop2_lt, ^bb2, ^bb3 276 ^bb2: 277 %loop2_add = spv.IAdd %loop2_bb_arg, %cst4 : i32 278 spv.Branch ^bb1(%loop2_add : i32) 279 ^bb3: 280 spv.mlir.merge 281 } 282 283 spv.Return 284 } 285 286 spv.EntryPoint "GLCompute" @fmul_kernel 287 spv.ExecutionMode @fmul_kernel "LocalSize", 32, 1, 1 288} 289