1// RUN: mlir-opt -convert-spirv-to-llvm -split-input-file -verify-diagnostics %s | FileCheck %s 2 3//===----------------------------------------------------------------------===// 4// spirv.Branch 5//===----------------------------------------------------------------------===// 6 7spirv.module Logical GLSL450 { 8 spirv.func @branch_without_arguments() -> () "None" { 9 // CHECK: llvm.br ^bb1 10 spirv.Branch ^label 11 // CHECK: ^bb1 12 ^label: 13 spirv.Return 14 } 15 16 spirv.func @branch_with_arguments() -> () "None" { 17 %0 = spirv.Constant 0 : i32 18 %1 = spirv.Constant true 19 // CHECK: llvm.br ^bb1(%{{.*}}, %{{.*}} : i32, i1) 20 spirv.Branch ^label(%0, %1: i32, i1) 21 // CHECK: ^bb1(%{{.*}}: i32, %{{.*}}: i1) 22 ^label(%arg0: i32, %arg1: i1): 23 spirv.Return 24 } 25} 26 27// ----- 28 29//===----------------------------------------------------------------------===// 30// spirv.BranchConditional 31//===----------------------------------------------------------------------===// 32 33spirv.module Logical GLSL450 { 34 spirv.func @cond_branch_without_arguments() -> () "None" { 35 // CHECK: %[[COND:.*]] = llvm.mlir.constant(true) : i1 36 %cond = spirv.Constant true 37 // CHECK: lvm.cond_br %[[COND]], ^bb1, ^bb2 38 spirv.BranchConditional %cond, ^true, ^false 39 // CHECK: ^bb1: 40 ^true: 41 spirv.Return 42 // CHECK: ^bb2: 43 ^false: 44 spirv.Return 45 } 46 47 spirv.func @cond_branch_with_arguments_nested() -> () "None" { 48 // CHECK: %[[COND1:.*]] = llvm.mlir.constant(true) : i1 49 %cond = spirv.Constant true 50 %0 = spirv.Constant 0 : i32 51 // CHECK: %[[COND2:.*]] = llvm.mlir.constant(false) : i1 52 %false = spirv.Constant false 53 // CHECK: llvm.cond_br %[[COND1]], ^bb1(%{{.*}}, %[[COND2]] : i32, i1), ^bb2 54 spirv.BranchConditional %cond, ^outer_true(%0, %false: i32, i1), ^outer_false 55 // CHECK: ^bb1(%{{.*}}: i32, %[[COND:.*]]: i1): 56 ^outer_true(%arg0: i32, %arg1: i1): 57 // CHECK: llvm.cond_br %[[COND]], ^bb3, ^bb4(%{{.*}}, %{{.*}} : i32, i32) 58 spirv.BranchConditional %arg1, ^inner_true, ^inner_false(%arg0, %arg0: i32, i32) 59 // CHECK: ^bb2: 60 ^outer_false: 61 spirv.Return 62 // CHECK: ^bb3: 63 ^inner_true: 64 spirv.Return 65 // CHECK: ^bb4(%{{.*}}: i32, %{{.*}}: i32): 66 ^inner_false(%arg3: i32, %arg4: i32): 67 spirv.Return 68 } 69 70 spirv.func @cond_branch_with_weights(%cond: i1) -> () "None" { 71 // CHECK: llvm.cond_br %{{.*}} weights([1, 2]), ^bb1, ^bb2 72 spirv.BranchConditional %cond [1, 2], ^true, ^false 73 // CHECK: ^bb1: 74 ^true: 75 spirv.Return 76 // CHECK: ^bb2: 77 ^false: 78 spirv.Return 79 } 80} 81 82// ----- 83 84//===----------------------------------------------------------------------===// 85// spirv.mlir.loop 86//===----------------------------------------------------------------------===// 87 88spirv.module Logical GLSL450 { 89 // CHECK-LABEL: @empty_loop 90 spirv.func @empty_loop() "None" { 91 // CHECK: llvm.return 92 spirv.mlir.loop { 93 } 94 spirv.Return 95 } 96 97 // CHECK-LABEL: @infinite_loop 98 spirv.func @infinite_loop(%count : i32) -> () "None" { 99 // CHECK: llvm.br ^[[BB1:.*]] 100 // CHECK: ^[[BB1]]: 101 // CHECK: %[[COND:.*]] = llvm.mlir.constant(true) : i1 102 // CHECK: llvm.cond_br %[[COND]], ^[[BB2:.*]], ^[[BB4:.*]] 103 // CHECK: ^[[BB2]]: 104 // CHECK: llvm.br ^[[BB3:.*]] 105 // CHECK: ^[[BB3]]: 106 // CHECK: llvm.br ^[[BB1:.*]] 107 // CHECK: ^[[BB4]]: 108 // CHECK: llvm.br ^[[BB5:.*]] 109 // CHECK: ^[[BB5]]: 110 // CHECK: llvm.return 111 spirv.mlir.loop { 112 spirv.Branch ^header 113 ^header: 114 %cond = spirv.Constant true 115 spirv.BranchConditional %cond, ^body, ^merge 116 ^body: 117 // Do nothing 118 spirv.Branch ^continue 119 ^continue: 120 // Do nothing 121 spirv.Branch ^header 122 ^merge: 123 spirv.mlir.merge 124 } 125 spirv.Return 126 } 127} 128 129// ----- 130 131//===----------------------------------------------------------------------===// 132// spirv.mlir.selection 133//===----------------------------------------------------------------------===// 134 135spirv.module Logical GLSL450 { 136 spirv.func @selection_empty() -> () "None" { 137 // CHECK: llvm.return 138 spirv.mlir.selection { 139 } 140 spirv.Return 141 } 142 143 spirv.func @selection_with_merge_block_only() -> () "None" { 144 %cond = spirv.Constant true 145 // CHECK: llvm.return 146 spirv.mlir.selection { 147 spirv.BranchConditional %cond, ^merge, ^merge 148 ^merge: 149 spirv.mlir.merge 150 } 151 spirv.Return 152 } 153 154 spirv.func @selection_with_true_block_only() -> () "None" { 155 // CHECK: %[[COND:.*]] = llvm.mlir.constant(true) : i1 156 %cond = spirv.Constant true 157 // CHECK: llvm.cond_br %[[COND]], ^bb1, ^bb2 158 spirv.mlir.selection { 159 spirv.BranchConditional %cond, ^true, ^merge 160 // CHECK: ^bb1: 161 ^true: 162 // CHECK: llvm.br ^bb2 163 spirv.Branch ^merge 164 // CHECK: ^bb2: 165 ^merge: 166 // CHECK: llvm.br ^bb3 167 spirv.mlir.merge 168 } 169 // CHECK: ^bb3: 170 // CHECK-NEXT: llvm.return 171 spirv.Return 172 } 173 174 spirv.func @selection_with_both_true_and_false_block() -> () "None" { 175 // CHECK: %[[COND:.*]] = llvm.mlir.constant(true) : i1 176 %cond = spirv.Constant true 177 // CHECK: llvm.cond_br %[[COND]], ^bb1, ^bb2 178 spirv.mlir.selection { 179 spirv.BranchConditional %cond, ^true, ^false 180 // CHECK: ^bb1: 181 ^true: 182 // CHECK: llvm.br ^bb3 183 spirv.Branch ^merge 184 // CHECK: ^bb2: 185 ^false: 186 // CHECK: llvm.br ^bb3 187 spirv.Branch ^merge 188 // CHECK: ^bb3: 189 ^merge: 190 // CHECK: llvm.br ^bb4 191 spirv.mlir.merge 192 } 193 // CHECK: ^bb4: 194 // CHECK-NEXT: llvm.return 195 spirv.Return 196 } 197 198 spirv.func @selection_with_early_return(%arg0: i1) -> i32 "None" { 199 // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32 200 %0 = spirv.Constant 0 : i32 201 // CHECK: llvm.cond_br %{{.*}}, ^bb1(%[[ZERO]] : i32), ^bb2 202 spirv.mlir.selection { 203 spirv.BranchConditional %arg0, ^true(%0 : i32), ^merge 204 // CHECK: ^bb1(%[[ARG:.*]]: i32): 205 ^true(%arg1: i32): 206 // CHECK: llvm.return %[[ARG]] : i32 207 spirv.ReturnValue %arg1 : i32 208 // CHECK: ^bb2: 209 ^merge: 210 // CHECK: llvm.br ^bb3 211 spirv.mlir.merge 212 } 213 // CHECK: ^bb3: 214 %one = spirv.Constant 1 : i32 215 spirv.ReturnValue %one : i32 216 } 217} 218