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