384 lines · plain
1// RUN: mlir-translate -no-implicit-module -split-input-file -test-spirv-roundtrip %s | FileCheck %s2 3// RUN: %if spirv-tools %{ rm -rf %t %}4// RUN: %if spirv-tools %{ mkdir %t %}5// RUN: %if spirv-tools %{ mlir-translate --no-implicit-module --serialize-spirv --split-input-file --spirv-save-validation-files-with-prefix=%t/module %s %}6// RUN: %if spirv-tools %{ spirv-val %t %}7 8// Test branch with one block argument9 10spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {11 spirv.func @foo() -> () "None" {12// CHECK: %[[CST:.*]] = spirv.Constant 013 %zero = spirv.Constant 0 : i3214// CHECK-NEXT: spirv.Branch ^bb1(%[[CST]] : i32)15 spirv.Branch ^bb1(%zero : i32)16// CHECK-NEXT: ^bb1(%{{.*}}: i32):17 ^bb1(%arg0: i32):18 spirv.Return19 }20 21 spirv.func @main() -> () "None" {22 spirv.Return23 }24 spirv.EntryPoint "GLCompute" @main25}26 27// -----28 29// Test branch with multiple block arguments30 31spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {32 spirv.func @foo() -> () "None" {33// CHECK: %[[ZERO:.*]] = spirv.Constant 034 %zero = spirv.Constant 0 : i3235// CHECK-NEXT: %[[ONE:.*]] = spirv.Constant 136 %one = spirv.Constant 1.0 : f3237// CHECK-NEXT: spirv.Branch ^bb1(%[[ZERO]], %[[ONE]] : i32, f32)38 spirv.Branch ^bb1(%zero, %one : i32, f32)39 40// CHECK-NEXT: ^bb1(%{{.*}}: i32, %{{.*}}: f32): // pred: ^bb041 ^bb1(%arg0: i32, %arg1: f32):42 spirv.Return43 }44 45 spirv.func @main() -> () "None" {46 spirv.Return47 }48 spirv.EntryPoint "GLCompute" @main49}50 51// -----52 53// Test using block arguments within branch54 55spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {56 spirv.func @foo() -> () "None" {57// CHECK: %[[CST0:.*]] = spirv.Constant 058 %zero = spirv.Constant 0 : i3259// CHECK-NEXT: spirv.Branch ^bb1(%[[CST0]] : i32)60 spirv.Branch ^bb1(%zero : i32)61 62// CHECK-NEXT: ^bb1(%[[ARG:.*]]: i32):63 ^bb1(%arg0: i32):64// CHECK-NEXT: %[[ADD:.*]] = spirv.IAdd %[[ARG]], %[[ARG]] : i3265 %0 = spirv.IAdd %arg0, %arg0 : i3266// CHECK-NEXT: %[[CST1:.*]] = spirv.Constant 067// CHECK-NEXT: spirv.Branch ^bb2(%[[CST1]], %[[ADD]] : i32, i32)68 spirv.Branch ^bb2(%zero, %0 : i32, i32)69 70// CHECK-NEXT: ^bb2(%{{.*}}: i32, %{{.*}}: i32):71 ^bb2(%arg1: i32, %arg2: i32):72 spirv.Return73 }74 75 spirv.func @main() -> () "None" {76 spirv.Return77 }78 spirv.EntryPoint "GLCompute" @main79}80 81// -----82 83// Test block not following domination order84 85spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {86 spirv.func @foo() -> () "None" {87// CHECK: spirv.Branch ^bb188 spirv.Branch ^bb189 90// CHECK-NEXT: ^bb1:91// CHECK-NEXT: %[[ZERO:.*]] = spirv.Constant 092// CHECK-NEXT: %[[ONE:.*]] = spirv.Constant 193// CHECK-NEXT: spirv.Branch ^bb2(%[[ZERO]], %[[ONE]] : i32, f32)94 95// CHECK-NEXT: ^bb2(%{{.*}}: i32, %{{.*}}: f32):96 ^bb2(%arg0: i32, %arg1: f32):97// CHECK-NEXT: spirv.Return98 spirv.Return99 100 // This block is reordered to follow domination order.101 ^bb1:102 %zero = spirv.Constant 0 : i32103 %one = spirv.Constant 1.0 : f32104 spirv.Branch ^bb2(%zero, %one : i32, f32)105 }106 107 spirv.func @main() -> () "None" {108 spirv.Return109 }110 spirv.EntryPoint "GLCompute" @main111}112 113// -----114 115// Test multiple predecessors116 117spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {118 spirv.func @foo() -> () "None" {119 %var = spirv.Variable : !spirv.ptr<i32, Function>120 121// CHECK: spirv.mlir.selection122 spirv.mlir.selection {123 %true = spirv.Constant true124// CHECK: spirv.BranchConditional %{{.*}}, ^bb1, ^bb2125 spirv.BranchConditional %true, ^true, ^false126 127// CHECK-NEXT: ^bb1:128 ^true:129// CHECK-NEXT: %[[ZERO:.*]] = spirv.Constant 0130 %zero = spirv.Constant 0 : i32131// CHECK-NEXT: spirv.Branch ^bb3(%[[ZERO]] : i32)132 spirv.Branch ^phi(%zero: i32)133 134// CHECK-NEXT: ^bb2:135 ^false:136// CHECK-NEXT: %[[ONE:.*]] = spirv.Constant 1137 %one = spirv.Constant 1 : i32138// CHECK-NEXT: spirv.Branch ^bb3(%[[ONE]] : i32)139 spirv.Branch ^phi(%one: i32)140 141// CHECK-NEXT: ^bb3(%[[ARG:.*]]: i32):142 ^phi(%arg: i32):143// CHECK-NEXT: spirv.Store "Function" %{{.*}}, %[[ARG]] : i32144 spirv.Store "Function" %var, %arg : i32145// CHECK-NEXT: spirv.Return146 spirv.Return147 148// CHECK-NEXT: ^bb4:149 ^merge:150// CHECK-NEXT: spirv.mlir.merge151 spirv.mlir.merge152 }153 spirv.Return154 }155 156 spirv.func @main() -> () "None" {157 spirv.Return158 }159 spirv.EntryPoint "GLCompute" @main160}161 162// -----163 164// Test nested loops with block arguments165 166spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {167 spirv.GlobalVariable @__builtin_var_NumWorkgroups__ built_in("NumWorkgroups") : !spirv.ptr<vector<3xi32>, Input>168 spirv.GlobalVariable @__builtin_var_WorkgroupId__ built_in("WorkgroupId") : !spirv.ptr<vector<3xi32>, Input>169 spirv.func @fmul_kernel() "None" {170 %3 = spirv.Constant 12 : i32171 %4 = spirv.Constant 32 : i32172 %5 = spirv.Constant 4 : i32173 %6 = spirv.mlir.addressof @__builtin_var_WorkgroupId__ : !spirv.ptr<vector<3xi32>, Input>174 %7 = spirv.Load "Input" %6 : vector<3xi32>175 %8 = spirv.CompositeExtract %7[0 : i32] : vector<3xi32>176 %9 = spirv.mlir.addressof @__builtin_var_WorkgroupId__ : !spirv.ptr<vector<3xi32>, Input>177 %10 = spirv.Load "Input" %9 : vector<3xi32>178 %11 = spirv.CompositeExtract %10[1 : i32] : vector<3xi32>179 %18 = spirv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spirv.ptr<vector<3xi32>, Input>180 %19 = spirv.Load "Input" %18 : vector<3xi32>181 %20 = spirv.CompositeExtract %19[0 : i32] : vector<3xi32>182 %21 = spirv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spirv.ptr<vector<3xi32>, Input>183 %22 = spirv.Load "Input" %21 : vector<3xi32>184 %23 = spirv.CompositeExtract %22[1 : i32] : vector<3xi32>185 %30 = spirv.IMul %11, %4 : i32186 %31 = spirv.IMul %23, %4 : i32187 188// CHECK: spirv.Branch ^[[FN_BB:.*]](%{{.*}} : i32)189// CHECK: ^[[FN_BB]](%[[FN_BB_ARG:.*]]: i32):190// CHECK: spirv.mlir.loop {191 spirv.mlir.loop {192// CHECK: spirv.Branch ^bb1(%[[FN_BB_ARG]] : i32)193 spirv.Branch ^bb1(%30 : i32)194// CHECK: ^[[LP1_HDR:.*]](%[[LP1_HDR_ARG:.*]]: i32):195 ^bb1(%32: i32):196// CHECK: spirv.SLessThan197 %33 = spirv.SLessThan %32, %3 : i32198// CHECK: spirv.BranchConditional %{{.*}}, ^[[LP1_BDY:.*]], ^[[LP1_MG:.*]]199 spirv.BranchConditional %33, ^bb2, ^bb3200// CHECK: ^[[LP1_BDY]]:201 ^bb2:202// CHECK: %[[MUL:.*]] = spirv.IMul203 %34 = spirv.IMul %8, %5 : i32204// CHECK: spirv.IMul205 %35 = spirv.IMul %20, %5 : i32206// CHECK: spirv.Branch ^[[LP1_CNT:.*]](%[[MUL]] : i32)207// CHECK: ^[[LP1_CNT]](%[[LP1_CNT_ARG:.*]]: i32):208// CHECK: spirv.mlir.loop {209 spirv.mlir.loop {210// CHECK: spirv.Branch ^[[LP2_HDR:.*]](%[[LP1_CNT_ARG]] : i32)211 spirv.Branch ^bb1(%34 : i32)212// CHECK: ^[[LP2_HDR]](%[[LP2_HDR_ARG:.*]]: i32):213 ^bb1(%37: i32):214// CHECK: spirv.SLessThan %[[LP2_HDR_ARG]]215 %38 = spirv.SLessThan %37, %5 : i32216// CHECK: spirv.BranchConditional %{{.*}}, ^[[LP2_BDY:.*]], ^[[LP2_MG:.*]]217 spirv.BranchConditional %38, ^bb2, ^bb3218// CHECK: ^[[LP2_BDY]]:219 ^bb2:220// CHECK: %[[ADD1:.*]] = spirv.IAdd221 %48 = spirv.IAdd %37, %35 : i32222// CHECK: spirv.Branch ^[[LP2_HDR]](%[[ADD1]] : i32)223 spirv.Branch ^bb1(%48 : i32)224// CHECK: ^[[LP2_MG]]:225 ^bb3:226// CHECK: spirv.mlir.merge227 spirv.mlir.merge228 }229// CHECK: %[[ADD2:.*]] = spirv.IAdd %[[LP1_HDR_ARG]]230 %36 = spirv.IAdd %32, %31 : i32231// CHECK: spirv.Branch ^[[LP1_HDR]](%[[ADD2]] : i32)232 spirv.Branch ^bb1(%36 : i32)233// CHECK: ^[[LP1_MG]]:234 ^bb3:235// CHECK: spirv.mlir.merge236 spirv.mlir.merge237 }238 spirv.Return239 }240 241 spirv.EntryPoint "GLCompute" @fmul_kernel, @__builtin_var_WorkgroupId__, @__builtin_var_NumWorkgroups__242 spirv.ExecutionMode @fmul_kernel "LocalSize", 32, 1, 1243}244 245// -----246 247// Test back-to-back loops with block arguments248 249spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {250 spirv.func @fmul_kernel() "None" {251 %cst4 = spirv.Constant 4 : i32252 253 %val1 = spirv.Constant 43 : i32254 %val2 = spirv.Constant 44 : i32255 256// CHECK: spirv.Constant 43257// CHECK-NEXT: spirv.Branch ^[[BB1:.+]](%{{.+}} : i32)258// CHECK-NEXT: ^[[BB1]](%{{.+}}: i32):259// CHECK-NEXT: spirv.mlir.loop260 spirv.mlir.loop { // loop 1261 spirv.Branch ^bb1(%val1 : i32)262 ^bb1(%loop1_bb_arg: i32):263 %loop1_lt = spirv.SLessThan %loop1_bb_arg, %cst4 : i32264 spirv.BranchConditional %loop1_lt, ^bb2, ^bb3265 ^bb2:266 %loop1_add = spirv.IAdd %loop1_bb_arg, %cst4 : i32267 spirv.Branch ^bb1(%loop1_add : i32)268 ^bb3:269 spirv.mlir.merge270 }271 272// CHECK: spirv.Constant 44273// CHECK-NEXT: spirv.Branch ^[[BB2:.+]](%{{.+}} : i32)274// CHECK-NEXT: ^[[BB2]](%{{.+}}: i32):275// CHECK-NEXT: spirv.mlir.loop276 spirv.mlir.loop { // loop 2277 spirv.Branch ^bb1(%val2 : i32)278 ^bb1(%loop2_bb_arg: i32):279 %loop2_lt = spirv.SLessThan %loop2_bb_arg, %cst4 : i32280 spirv.BranchConditional %loop2_lt, ^bb2, ^bb3281 ^bb2:282 %loop2_add = spirv.IAdd %loop2_bb_arg, %cst4 : i32283 spirv.Branch ^bb1(%loop2_add : i32)284 ^bb3:285 spirv.mlir.merge286 }287 288 spirv.Return289 }290 291 spirv.EntryPoint "GLCompute" @fmul_kernel292 spirv.ExecutionMode @fmul_kernel "LocalSize", 32, 1, 1293}294 295// -----296 297spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {298// CHECK-LABEL: @cond_branch_true_argument299 spirv.func @cond_branch_true_argument() -> () "None" {300 %true = spirv.Constant true301 %zero = spirv.Constant 0 : i32302 %one = spirv.Constant 1 : i32303 spirv.mlir.selection {304// CHECK: spirv.BranchConditional %{{.*}}, ^[[true1:.*]](%{{.*}}, %{{.*}} : i32, i32), ^[[false1:.*]]305 spirv.BranchConditional %true, ^true1(%zero, %zero: i32, i32), ^false1306// CHECK: [[true1]](%{{.*}}: i32, %{{.*}}: i32)307 ^true1(%arg0: i32, %arg1: i32):308 spirv.Return309// CHECK: [[false1]]:310 ^false1:311 spirv.Return312 ^merge:313 spirv.mlir.merge314 }315 316 spirv.Return317 }318 319 spirv.func @main() -> () "None" {320 spirv.Return321 }322 spirv.EntryPoint "GLCompute" @main323}324 325// -----326 327spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {328// CHECK-LABEL: @cond_branch_false_argument329 spirv.func @cond_branch_false_argument() -> () "None" {330 %true = spirv.Constant true331 %zero = spirv.Constant 0 : i32332 %one = spirv.Constant 1 : i32333 spirv.mlir.selection {334// CHECK: spirv.BranchConditional %{{.*}}, ^[[true1:.*]], ^[[false1:.*]](%{{.*}}, %{{.*}} : i32, i32)335 spirv.BranchConditional %true, ^true1, ^false1(%zero, %zero: i32, i32)336// CHECK: [[true1]]:337 ^true1:338 spirv.Return339// CHECK: [[false1]](%{{.*}}: i32, %{{.*}}: i32):340 ^false1(%arg0: i32, %arg1: i32):341 spirv.Return342 ^merge:343 spirv.mlir.merge344 }345 346 spirv.Return347 }348 349 spirv.func @main() -> () "None" {350 spirv.Return351 }352 spirv.EntryPoint "GLCompute" @main353}354 355// -----356 357spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {358// CHECK-LABEL: @cond_branch_true_and_false_argument359 spirv.func @cond_branch_true_and_false_argument() -> () "None" {360 %true = spirv.Constant true361 %zero = spirv.Constant 0 : i32362 %one = spirv.Constant 1 : i32363 spirv.mlir.selection {364// CHECK: spirv.BranchConditional %{{.*}}, ^[[true1:.*]](%{{.*}} : i32), ^[[false1:.*]](%{{.*}}, %{{.*}} : i32, i32)365 spirv.BranchConditional %true, ^true1(%one: i32), ^false1(%zero, %zero: i32, i32)366// CHECK: [[true1]](%{{.*}}: i32):367 ^true1(%arg0: i32):368 spirv.Return369// CHECK: [[false1]](%{{.*}}: i32, %{{.*}}: i32):370 ^false1(%arg1: i32, %arg2: i32):371 spirv.Return372 ^merge:373 spirv.mlir.merge374 }375 376 spirv.Return377 }378 379 spirv.func @main() -> () "None" {380 spirv.Return381 }382 spirv.EntryPoint "GLCompute" @main383}384