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