191 lines · plain
1// RUN: cir-opt %s -cir-to-llvm -o %t.mlir2// RUN: FileCheck --input-file=%t.mlir %s3 4!s8i = !cir.int<s, 8>5!s32i = !cir.int<s, 32>6!s64i = !cir.int<s, 64>7 8module {9 cir.func @shouldLowerSwitchWithDefault(%arg0: !s8i) {10 cir.switch (%arg0 : !s8i) {11 // CHECK: llvm.switch %arg0 : i8, ^bb[[#DEFAULT:]] [12 // CHECK: 1: ^bb[[#CASE1:]]13 // CHECK: ]14 cir.case (equal, [#cir.int<1> : !s8i]) {15 cir.break16 }17 // CHECK: ^bb[[#CASE1]]:18 // CHECK: llvm.br ^bb[[#EXIT:]]19 cir.case (default, []) {20 cir.break21 }22 // CHECK: ^bb[[#DEFAULT]]:23 // CHECK: llvm.br ^bb[[#EXIT]]24 cir.yield25 }26 // CHECK: ^bb[[#EXIT]]:27 cir.return28 }29 30 31 cir.func @shouldLowerSwitchWithoutDefault(%arg0: !s32i) {32 cir.switch (%arg0 : !s32i) {33 // Default block is the exit block:34 // CHECK: llvm.switch %arg0 : i32, ^bb[[#EXIT:]] [35 // CHECK: 1: ^bb[[#CASE1:]]36 // CHECK: ]37 cir.case (equal, [#cir.int<1> : !s32i]) {38 cir.break39 }40 // CHECK: ^bb[[#CASE1]]:41 // CHECK: llvm.br ^bb[[#EXIT]]42 cir.yield43 }44 // CHECK: ^bb[[#EXIT]]:45 cir.return46 }47 48 49 cir.func @shouldLowerSwitchWithImplicitFallthrough(%arg0: !s64i) {50 cir.switch (%arg0 : !s64i) {51 // CHECK: llvm.switch %arg0 : i64, ^bb[[#EXIT:]] [52 // CHECK: 1: ^bb[[#CASE1N2:]],53 // CHECK: 2: ^bb[[#CASE1N2]]54 // CHECK: ]55 cir.case (anyof, [#cir.int<1> : !s64i, #cir.int<2> : !s64i]) { // case 1 and 2 use same region56 cir.break57 }58 // CHECK: ^bb[[#CASE1N2]]:59 // CHECK: llvm.br ^bb[[#EXIT]]60 cir.yield61 }62 // CHECK: ^bb[[#EXIT]]:63 cir.return64 }65 66 67 cir.func @shouldLowerSwitchWithExplicitFallthrough(%arg0: !s64i) {68 cir.switch (%arg0 : !s64i) {69 // CHECK: llvm.switch %arg0 : i64, ^bb[[#EXIT:]] [70 // CHECK: 1: ^bb[[#CASE1:]],71 // CHECK: 2: ^bb[[#CASE2:]]72 // CHECK: ]73 cir.case (equal, [#cir.int<1> : !s64i]) { // case 1 has its own region74 cir.yield // fallthrough to case 275 }76 // CHECK: ^bb[[#CASE1]]:77 // CHECK: llvm.br ^bb[[#CASE2]]78 cir.case (equal, [#cir.int<2> : !s64i]) {79 cir.break80 }81 // CHECK: ^bb[[#CASE2]]:82 // CHECK: llvm.br ^bb[[#EXIT]]83 cir.yield84 }85 // CHECK: ^bb[[#EXIT]]:86 cir.return87 }88 89 90 cir.func @shouldLowerSwitchWithFallthroughToExit(%arg0: !s64i) {91 cir.switch (%arg0 : !s64i) {92 // CHECK: llvm.switch %arg0 : i64, ^bb[[#EXIT:]] [93 // CHECK: 1: ^bb[[#CASE1:]]94 // CHECK: ]95 cir.case (equal, [#cir.int<1> : !s64i]) {96 cir.yield // fallthrough to exit97 }98 // CHECK: ^bb[[#CASE1]]:99 // CHECK: llvm.br ^bb[[#EXIT]]100 cir.yield101 }102 // CHECK: ^bb[[#EXIT]]:103 cir.return104 }105 106 107 cir.func @shouldDropEmptySwitch(%arg0: !s64i) {108 cir.switch (%arg0 : !s64i) {109 cir.yield110 }111 // CHECK-NOT: llvm.switch112 cir.return113 }114 115 cir.func @shouldLowerMultiBlockCase(%arg0: !s32i) {116 %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init] {alignment = 4 : i64}117 cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i>118 cir.scope {119 %1 = cir.load %0 : !cir.ptr<!s32i>, !s32i120 cir.switch (%1 : !s32i) {121 cir.case (equal, [#cir.int<3> : !s32i]) {122 cir.return123 ^bb1: // no predecessors124 cir.break125 }126 cir.yield127 }128 }129 cir.return130 }131 // CHECK: llvm.func @shouldLowerMultiBlockCase132 // CHECK: ^bb1: // pred: ^bb0133 // CHECK: llvm.switch {{.*}} : i32, ^[[DEFAULT_BB:.+]] [134 // CHECK: 3: ^[[DIRECTLY_RET_BB:.+]]135 // CHECK: ]136 // CHECK: ^[[DIRECTLY_RET_BB]]:137 // CHECK: llvm.return138 // CHECK: ^[[DEFAULT_BB:.+]]:139 // CHECK: llvm.br ^[[RET_BB:.+]]140 // CHECK: ^[[RET_BB:.+]]: // pred: ^[[DEFAULT_BB:.+]]141 // CHECK: llvm.return142 // CHECK: }143 144 cir.func @shouldLowerNestedBreak(%arg0: !s32i, %arg1: !s32i) -> !s32i {145 %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}146 %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init] {alignment = 4 : i64}147 %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}148 cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i>149 cir.store %arg1, %1 : !s32i, !cir.ptr<!s32i>150 cir.scope {151 %5 = cir.load %0 : !cir.ptr<!s32i>, !s32i152 cir.switch (%5 : !s32i) {153 cir.case (equal, [#cir.int<0> : !s32i]) {154 cir.scope {155 %6 = cir.load %1 : !cir.ptr<!s32i>, !s32i156 %7 = cir.const #cir.int<0> : !s32i157 %8 = cir.cmp(ge, %6, %7) : !s32i, !cir.bool158 cir.if %8 {159 cir.break160 }161 }162 cir.break163 }164 cir.yield165 }166 }167 %3 = cir.const #cir.int<3> : !s32i168 cir.store %3, %2 : !s32i, !cir.ptr<!s32i>169 %4 = cir.load %2 : !cir.ptr<!s32i>, !s32i170 cir.return %4 : !s32i171 }172 // CHECK: llvm.func @shouldLowerNestedBreak173 // CHECK: llvm.switch %6 : i32, ^[[DEFAULT_BB:.+]] [174 // CHECK: 0: ^[[ZERO_BB:.+]]175 // CHECK: ]176 // CHECK: ^[[ZERO_BB]]:177 // CHECK: llvm.br ^[[ZERO_BB_SUCC:.+]]178 // CHECK: ^[[ZERO_BB_SUCC]]: // pred: ^[[ZERO_BB:]]179 // CHECK: llvm.cond_br {{%.*}}, ^[[DEFAULT_BB_PRED1:.+]], ^[[DEFAULT_BB_PRED12:.+]]180 // CHECK: ^[[DEFAULT_BB_PRED1]]: // pred: ^[[ZERO_BB_SUCC]]181 // CHECK: llvm.br ^[[DEFAULT_BB]]182 // CHECK: ^[[DEFAULT_BB_PRED12]]: // pred: ^[[ZERO_BB_SUCC]]183 // CHECK: llvm.br ^[[DEFAULT_BB_PRED1:.+]]184 // CHECK: ^[[DEFAULT_BB_PRED1]]: // pred: ^[[DEFAULT_BB_PRED12]]185 // CHECK: llvm.br ^[[DEFAULT_BB]]186 // CHECK: ^[[DEFAULT_BB]]:187 // CHECK: llvm.br ^[[RET_BB:.+]]188 // CHECK: ^[[RET_BB]]: // pred: ^[[DEFAULT_BB]]189 // CHECK: llvm.return190}191