270 lines · plain
1// RUN: mlir-opt %s --split-input-file --pass-pipeline='builtin.module(spirv.module(inline{default-pipeline=''}))' | FileCheck %s2 3spirv.module Logical GLSL450 {4 spirv.func @callee() "None" {5 spirv.Return6 }7 8 // CHECK-LABEL: @calling_single_block_ret_func9 spirv.func @calling_single_block_ret_func() "None" {10 // CHECK-NEXT: spirv.Return11 spirv.FunctionCall @callee() : () -> ()12 spirv.Return13 }14}15 16// -----17 18spirv.module Logical GLSL450 {19 spirv.func @callee() -> i32 "None" {20 %0 = spirv.Constant 42 : i3221 spirv.ReturnValue %0 : i3222 }23 24 // CHECK-LABEL: @calling_single_block_retval_func25 spirv.func @calling_single_block_retval_func() -> i32 "None" {26 // CHECK-NEXT: %[[CST:.*]] = spirv.Constant 4227 %0 = spirv.FunctionCall @callee() : () -> (i32)28 // CHECK-NEXT: spirv.ReturnValue %[[CST]]29 spirv.ReturnValue %0 : i3230 }31}32 33// -----34 35spirv.module Logical GLSL450 {36 spirv.GlobalVariable @data bind(0, 0) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32> [0])>, StorageBuffer>37 spirv.func @callee() "None" {38 %0 = spirv.mlir.addressof @data : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32> [0])>, StorageBuffer>39 %1 = spirv.Constant 0: i3240 %2 = spirv.AccessChain %0[%1, %1] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i32, StorageBuffer>41 spirv.Branch ^next42 43 ^next:44 %3 = spirv.Constant 42: i3245 spirv.Store "StorageBuffer" %2, %3 : i3246 spirv.Return47 }48 49 // CHECK-LABEL: @calling_multi_block_ret_func50 spirv.func @calling_multi_block_ret_func() "None" {51 // CHECK-NEXT: spirv.mlir.addressof52 // CHECK-NEXT: spirv.Constant 053 // CHECK-NEXT: spirv.AccessChain54 // CHECK-NEXT: spirv.Branch ^bb155 // CHECK-NEXT: ^bb1:56 // CHECK-NEXT: spirv.Constant57 // CHECK-NEXT: spirv.Store58 // CHECK-NEXT: spirv.Branch ^bb259 spirv.FunctionCall @callee() : () -> ()60 // CHECK-NEXT: ^bb2:61 // CHECK-NEXT: spirv.Return62 spirv.Return63 }64}65 66// TODO: calling_multi_block_retval_func67 68// -----69 70spirv.module Logical GLSL450 {71 spirv.func @callee(%cond : i1) -> () "None" {72 spirv.mlir.selection {73 spirv.BranchConditional %cond, ^then, ^merge74 ^then:75 spirv.Return76 ^merge:77 spirv.mlir.merge78 }79 spirv.Return80 }81 82 // CHECK-LABEL: @calling_selection_ret_func83 spirv.func @calling_selection_ret_func() "None" {84 %0 = spirv.Constant true85 // CHECK: spirv.FunctionCall86 spirv.FunctionCall @callee(%0) : (i1) -> ()87 spirv.Return88 }89}90 91// -----92 93spirv.module Logical GLSL450 {94 spirv.func @callee(%cond : i1) -> () "None" {95 spirv.mlir.selection {96 spirv.BranchConditional %cond, ^then, ^merge97 ^then:98 spirv.Branch ^merge99 ^merge:100 spirv.mlir.merge101 }102 spirv.Return103 }104 105 // CHECK-LABEL: @calling_selection_no_ret_func106 spirv.func @calling_selection_no_ret_func() "None" {107 // CHECK-NEXT: %[[TRUE:.*]] = spirv.Constant true108 %0 = spirv.Constant true109 // CHECK-NEXT: spirv.mlir.selection110 // CHECK-NEXT: spirv.BranchConditional %[[TRUE]], ^bb1, ^bb2111 // CHECK-NEXT: ^bb1:112 // CHECK-NEXT: spirv.Branch ^bb2113 // CHECK-NEXT: ^bb2:114 // CHECK-NEXT: spirv.mlir.merge115 spirv.FunctionCall @callee(%0) : (i1) -> ()116 spirv.Return117 }118}119 120// -----121 122spirv.module Logical GLSL450 {123 spirv.func @callee(%cond : i1) -> () "None" {124 spirv.mlir.loop {125 spirv.Branch ^header126 ^header:127 spirv.BranchConditional %cond, ^body, ^merge128 ^body:129 spirv.Return130 ^continue:131 spirv.Branch ^header132 ^merge:133 spirv.mlir.merge134 }135 spirv.Return136 }137 138 // CHECK-LABEL: @calling_loop_ret_func139 spirv.func @calling_loop_ret_func() "None" {140 %0 = spirv.Constant true141 // CHECK: spirv.FunctionCall142 spirv.FunctionCall @callee(%0) : (i1) -> ()143 spirv.Return144 }145}146 147// -----148 149spirv.module Logical GLSL450 {150 spirv.func @callee(%cond : i1) -> () "None" {151 spirv.mlir.loop {152 spirv.Branch ^header153 ^header:154 spirv.BranchConditional %cond, ^body, ^merge155 ^body:156 spirv.Branch ^continue157 ^continue:158 spirv.Branch ^header159 ^merge:160 spirv.mlir.merge161 }162 spirv.Return163 }164 165 // CHECK-LABEL: @calling_loop_no_ret_func166 spirv.func @calling_loop_no_ret_func() "None" {167 // CHECK-NEXT: %[[TRUE:.*]] = spirv.Constant true168 %0 = spirv.Constant true169 // CHECK-NEXT: spirv.mlir.loop170 // CHECK-NEXT: spirv.Branch ^bb1171 // CHECK-NEXT: ^bb1:172 // CHECK-NEXT: spirv.BranchConditional %[[TRUE]], ^bb2, ^bb4173 // CHECK-NEXT: ^bb2:174 // CHECK-NEXT: spirv.Branch ^bb3175 // CHECK-NEXT: ^bb3:176 // CHECK-NEXT: spirv.Branch ^bb1177 // CHECK-NEXT: ^bb4:178 // CHECK-NEXT: spirv.mlir.merge179 spirv.FunctionCall @callee(%0) : (i1) -> ()180 spirv.Return181 }182}183 184// -----185 186spirv.module Logical GLSL450 {187 spirv.GlobalVariable @arg_0 bind(0, 0) : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>188 spirv.GlobalVariable @arg_1 bind(0, 1) : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>189 190 // CHECK: @inline_into_selection_region191 spirv.func @inline_into_selection_region() "None" {192 %1 = spirv.Constant 0 : i32193 // CHECK-DAG: [[ADDRESS_ARG0:%.*]] = spirv.mlir.addressof @arg_0194 // CHECK-DAG: [[ADDRESS_ARG1:%.*]] = spirv.mlir.addressof @arg_1195 // CHECK-DAG: [[LOADPTR:%.*]] = spirv.AccessChain [[ADDRESS_ARG0]]196 // CHECK: [[VAL:%.*]] = spirv.Load "StorageBuffer" [[LOADPTR]]197 %2 = spirv.mlir.addressof @arg_0 : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>198 %3 = spirv.mlir.addressof @arg_1 : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>199 %4 = spirv.AccessChain %2[%1] : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>, i32 -> !spirv.ptr<i32, StorageBuffer>200 %5 = spirv.Load "StorageBuffer" %4 : i32201 %6 = spirv.SGreaterThan %5, %1 : i32202 // CHECK: spirv.mlir.selection203 spirv.mlir.selection {204 spirv.BranchConditional %6, ^bb1, ^bb2205 ^bb1: // pred: ^bb0206 // CHECK: [[STOREPTR:%.*]] = spirv.AccessChain [[ADDRESS_ARG1]]207 %7 = spirv.AccessChain %3[%1] : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>, i32 -> !spirv.ptr<i32, StorageBuffer>208 // CHECK-NOT: spirv.FunctionCall209 // CHECK: spirv.AtomicIAdd <Device> <AcquireRelease> [[STOREPTR]], [[VAL]]210 // CHECK: spirv.Branch211 spirv.FunctionCall @atomic_add(%5, %7) : (i32, !spirv.ptr<i32, StorageBuffer>) -> ()212 spirv.Branch ^bb2213 ^bb2 : // 2 preds: ^bb0, ^bb1214 spirv.mlir.merge215 }216 // CHECK: spirv.Return217 spirv.Return218 }219 spirv.func @atomic_add(%arg0: i32, %arg1: !spirv.ptr<i32, StorageBuffer>) "None" {220 %0 = spirv.AtomicIAdd <Device> <AcquireRelease> %arg1, %arg0 : !spirv.ptr<i32, StorageBuffer>221 spirv.Return222 }223 spirv.EntryPoint "GLCompute" @inline_into_selection_region224 spirv.ExecutionMode @inline_into_selection_region "LocalSize", 32, 1, 1225}226 227// -----228 229spirv.module Logical GLSL450 {230 // CHECK-LABEL: @foo231 spirv.func @foo(%arg0: i32) -> i32 "None" {232 // CHECK-NOT: spirv.FunctionCall233 // CHECK-NEXT: spirv.Constant 1234 %res = spirv.FunctionCall @bar(%arg0) : (i32) -> i32235 spirv.ReturnValue %res : i32236 }237 238 spirv.func @bar(%arg1: i32) -> i32 "None" attributes {sym_visibility = "private"} {239 %cst1_i32 = spirv.Constant 1 : i32240 %0 = spirv.IEqual %arg1, %cst1_i32 : i32241 spirv.BranchConditional %0, ^bb1(%cst1_i32 : i32), ^bb2242 ^bb1(%1: i32):243 spirv.ReturnValue %1 : i32244 ^bb2:245 spirv.ReturnValue %cst1_i32 : i32246 }247}248 249// -----250 251spirv.module Logical GLSL450 {252 // CHECK-LABEL: @callee253 spirv.func @callee() -> () "None" {254 // CHECK-NEXT: spirv.Kill255 spirv.Kill256 }257 258 // CHECK-LABEL: @do_not_inline_kill259 spirv.func @do_not_inline_kill() -> () "None" {260 // CHECK-NOT: spirv.Kill261 // CHECK-NEXT: spirv.FunctionCall @callee() : () -> ()262 spirv.FunctionCall @callee() : () -> ()263 // CHECK-NEXT: spirv.Return264 spirv.Return265 }266}267 268// TODO: Add tests for inlining structured control flow into269// structured control flow.270