xref: /llvm-project/mlir/test/Target/SPIRV/selection.mlir (revision e4889c0a046e251bfaf27a637df606112659be89)
1// RUN: mlir-translate -no-implicit-module -test-spirv-roundtrip -split-input-file %s | FileCheck %s
2
3// Selection with both then and else branches
4
5spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
6// CHECK-LABEL: @selection
7  spirv.func @selection(%cond: i1) -> () "None" {
8// CHECK-NEXT:   spirv.Constant 0
9// CHECK-NEXT:   spirv.Variable
10// CHECK:        spirv.Branch ^[[BB:.+]]
11// CHECK-NEXT: ^[[BB]]:
12    %zero = spirv.Constant 0: i32
13    %one = spirv.Constant 1: i32
14    %two = spirv.Constant 2: i32
15    %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
16
17// CHECK-NEXT:   spirv.mlir.selection control(Flatten)
18    spirv.mlir.selection control(Flatten) {
19// CHECK-NEXT: spirv.BranchConditional %{{.*}} [5, 10], ^[[THEN:.+]], ^[[ELSE:.+]]
20      spirv.BranchConditional %cond [5, 10], ^then, ^else
21
22// CHECK-NEXT:   ^[[THEN]]:
23    ^then:
24// CHECK-NEXT:     spirv.Constant 1
25// CHECK-NEXT:     spirv.Store
26      spirv.Store "Function" %var, %one : i32
27// CHECK-NEXT:     spirv.Branch ^[[MERGE:.+]]
28      spirv.Branch ^merge
29
30// CHECK-NEXT:   ^[[ELSE]]:
31    ^else:
32// CHECK-NEXT:     spirv.Constant 2
33// CHECK-NEXT:     spirv.Store
34      spirv.Store "Function" %var, %two : i32
35// CHECK-NEXT:     spirv.Branch ^[[MERGE]]
36      spirv.Branch ^merge
37
38// CHECK-NEXT:   ^[[MERGE]]:
39    ^merge:
40// CHECK-NEXT:     spirv.mlir.merge
41      spirv.mlir.merge
42    }
43
44    spirv.Return
45  }
46
47  spirv.func @main() -> () "None" {
48    spirv.Return
49  }
50  spirv.EntryPoint "GLCompute" @main
51  spirv.ExecutionMode @main "LocalSize", 1, 1, 1
52}
53
54// -----
55
56// Selection with only then branch
57// Selection in function entry block
58
59spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
60// CHECK-LABEL: spirv.func @selection
61//  CHECK-SAME: (%[[ARG:.*]]: i1)
62  spirv.func @selection(%cond: i1) -> (i32) "None" {
63// CHECK:        spirv.Branch ^[[BB:.+]]
64// CHECK-NEXT: ^[[BB]]:
65// CHECK-NEXT:   spirv.mlir.selection
66    spirv.mlir.selection {
67// CHECK-NEXT: spirv.BranchConditional %[[ARG]], ^[[THEN:.+]], ^[[ELSE:.+]]
68      spirv.BranchConditional %cond, ^then, ^merge
69
70// CHECK:        ^[[THEN]]:
71    ^then:
72      %zero = spirv.Constant 0 : i32
73      spirv.ReturnValue  %zero : i32
74
75// CHECK:        ^[[ELSE]]:
76    ^merge:
77// CHECK-NEXT:     spirv.mlir.merge
78      spirv.mlir.merge
79    }
80
81    %one = spirv.Constant 1 : i32
82    spirv.ReturnValue  %one : i32
83  }
84
85  spirv.func @main() -> () "None" {
86    spirv.Return
87  }
88  spirv.EntryPoint "GLCompute" @main
89  spirv.ExecutionMode @main "LocalSize", 1, 1, 1
90}
91
92// -----
93
94// Selection with control flow afterwards
95// SSA value def before selection and use after selection
96
97spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
98// CHECK-LABEL: @selection_cf()
99  spirv.func @selection_cf() -> () "None" {
100    %true = spirv.Constant true
101    %false = spirv.Constant false
102    %zero = spirv.Constant 0 : i32
103    %one = spirv.Constant 1 : i32
104// CHECK-NEXT:    %[[VAR:.+]] = spirv.Variable
105    %var = spirv.Variable : !spirv.ptr<i1, Function>
106// CHECK-NEXT:    spirv.Branch ^[[BB:.+]]
107// CHECK-NEXT:  ^[[BB]]:
108
109// CHECK-NEXT:    spirv.mlir.selection {
110    spirv.mlir.selection {
111//      CHECK:      spirv.BranchConditional %{{.+}}, ^[[THEN0:.+]], ^[[ELSE0:.+]]
112      spirv.BranchConditional %true, ^then0, ^else0
113
114// CHECK-NEXT:    ^[[THEN0]]:
115//      CHECK:      spirv.Store "Function" %[[VAR]]
116// CHECK-NEXT:      spirv.Branch ^[[MERGE:.+]]
117    ^then0:
118      spirv.Store "Function" %var, %true : i1
119      spirv.Branch ^merge
120
121// CHECK-NEXT:    ^[[ELSE0]]:
122//      CHECK:      spirv.Store "Function" %[[VAR]]
123// CHECK-NEXT:      spirv.Branch ^[[MERGE]]
124    ^else0:
125      spirv.Store "Function" %var, %false : i1
126      spirv.Branch ^merge
127
128// CHECK-NEXT:    ^[[MERGE]]:
129// CHECK-NEXT:      spirv.mlir.merge
130    ^merge:
131      spirv.mlir.merge
132// CHECK-NEXT:    }
133    }
134
135// CHECK-NEXT:    spirv.Load "Function" %[[VAR]]
136    %cond = spirv.Load "Function" %var : i1
137//      CHECK:    spirv.BranchConditional %1, ^[[THEN1:.+]](%{{.+}} : i32), ^[[ELSE1:.+]](%{{.+}}, %{{.+}} : i32, i32)
138    spirv.BranchConditional %cond, ^then1(%one: i32), ^else1(%zero, %zero: i32, i32)
139
140// CHECK-NEXT:  ^[[THEN1]](%{{.+}}: i32):
141// CHECK-NEXT:    spirv.Return
142  ^then1(%arg0: i32):
143    spirv.Return
144
145// CHECK-NEXT:  ^[[ELSE1]](%{{.+}}: i32, %{{.+}}: i32):
146// CHECK-NEXT:    spirv.Return
147  ^else1(%arg1: i32, %arg2: i32):
148    spirv.Return
149  }
150}
151