// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
/// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
void sw1(int a) {
  switch (int b = 1; a) {
  case 0:
    b = b + 1;
    break;
  case 1:
    break;
  case 2: {
    b = b + 1;
    int yolo = 100;
    break;
  }
  }
}

// CIR: cir.func{{.*}} @_Z3sw1i
// CIR: cir.switch(%[[COND:.*]] : !s32i) {
// CIR-NEXT: cir.case(equal, [#cir.int<0> : !s32i]) {
// CIR: cir.break
// CIR: cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT: cir.break
// CIR: cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR: cir.scope {
// CIR: cir.alloca !s32i, !cir.ptr<!s32i>, ["yolo", init]
// CIR: cir.break

// LLVM: define{{.*}} void @_Z3sw1i
// LLVM:   store i32 1, ptr %[[B_ADDR:.*]], align 4
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
// LLVM:   br label %[[BB7:.*]]
// LLVM: [[BB7]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[EXIT:.*]] [
// LLVM-DAG:   i32 0, label %[[CASE0:.*]]
// LLVM-DAG:   i32 1, label %[[CASE1:.*]]
// LLVM-DAG:   i32 2, label %[[CASE2:.*]]
// LLVM:   ]
// LLVM: [[CASE0]]:
// LLVM:   %[[B:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   %[[INC0:.*]] = add nsw i32 %[[B]], 1
// LLVM:   store i32 %[[INC0]], ptr %[[B_ADDR]], align 4
// LLVM:   br label %[[EXIT]]
// LLVM: [[CASE1]]:
// LLVM:   br label %[[EXIT]]
// LLVM: [[CASE2]]:
// LLVM:   br label %[[BB14:.*]]
// LLVM: [[BB14]]:
// LLVM:   %[[B2:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   %[[INC2:.*]] = add nsw i32 %[[B2]], 1
// LLVM:   store i32 %[[INC2]], ptr %[[B_ADDR]], align 4
// LLVM:   store i32 100, ptr %[[YOLO:.*]], align 4
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[DEFAULT:.*]]
// LLVM: [[DEFAULT]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw1i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[B:.*]] = alloca i32, align 4
// OGCG:   %[[YOLO:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[SW_EPILOG:.*]] [
// OGCG:     i32 0, label %[[SW0:.*]]
// OGCG:     i32 1, label %[[SW1:.*]]
// OGCG:     i32 2, label %[[SW2:.*]]
// OGCG:   ]
// OGCG: [[SW0]]:
// OGCG:   %[[B_LOAD0:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   %[[B_INC0:.*]] = add nsw i32 %[[B_LOAD0]], 1
// OGCG:   store i32 %[[B_INC0]], ptr %[[B]], align 4
// OGCG:   br label %[[SW_EPILOG]]
// OGCG: [[SW1]]:
// OGCG:   br label %[[SW_EPILOG]]
// OGCG: [[SW2]]:
// OGCG:   %[[B_LOAD2:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   %[[B_INC2:.*]] = add nsw i32 %[[B_LOAD2]], 1
// OGCG:   store i32 %[[B_INC2]], ptr %[[B]], align 4
// OGCG:   store i32 100, ptr %[[YOLO]], align 4
// OGCG:   br label %[[SW_EPILOG]]
// OGCG: [[SW_EPILOG]]:
// OGCG:   ret void

void sw2(int a) {
  switch (int yolo = 2; a) {
  case 3:
    // "fomo" has the same lifetime as "yolo"
    int fomo = 0;
    yolo = yolo + fomo;
    break;
  }
}

// CIR: cir.func{{.*}} @_Z3sw2i
// CIR: cir.scope {
// CIR-NEXT:   %[[YOLO:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["yolo", init]
// CIR-NEXT:   %[[FOMO:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["fomo", init]
// CIR:        cir.switch(%[[COND:.*]] : !s32i) {
// CIR-NEXT:   cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:     %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
// CIR-NEXT:     cir.store{{.*}} %[[ZERO]], %[[FOMO]] : !s32i, !cir.ptr<!s32i>

// LLVM: define{{.*}} void @_Z3sw2i
// LLVM:   store i32 2, ptr %[[YOLO_ADDR:.*]], align 4
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[EXIT:.*]] [
// LLVM:     i32 3, label %[[CASE3:.*]]
// LLVM:   ]
// LLVM: [[CASE3]]:
// LLVM:   store i32 0, ptr %[[FOMO_ADDR:.*]], align 4
// LLVM:   %[[YOLO_VAL:.*]] = load i32, ptr %[[YOLO_ADDR]], align 4
// LLVM:   %[[FOMO_VAL:.*]] = load i32, ptr %[[FOMO_ADDR]], align 4
// LLVM:   %[[YOLO_PLUS_FOMO:.*]] = add nsw i32 %[[YOLO_VAL]], %[[FOMO_VAL]]
// LLVM:   store i32 %[[YOLO_PLUS_FOMO]], ptr %[[YOLO_ADDR]], align 4
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw2i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[YOLO:.*]] = alloca i32, align 4
// OGCG:   %[[FOMO:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[SW_EPILOG:.*]] [
// OGCG:     i32 3, label %[[SW3:.*]]
// OGCG:   ]
// OGCG: [[SW3]]:
// OGCG:   %[[Y:.*]] = load i32, ptr %[[YOLO]], align 4
// OGCG:   %[[F:.*]] = load i32, ptr %[[FOMO]], align 4
// OGCG:   %[[SUM:.*]] = add nsw i32 %[[Y]], %[[F]]
// OGCG:   store i32 %[[SUM]], ptr %[[YOLO]], align 4
// OGCG:   br label %[[SW_EPILOG]]
// OGCG: [[SW_EPILOG]]:
// OGCG:   ret void

void sw3(int a) {
  switch (a) {
  default:
    break;
  }
}

// CIR: cir.func{{.*}} @_Z3sw3i
// CIR: cir.scope {
// CIR-NEXT:   %[[COND:.*]] = cir.load{{.*}} %[[A:.*]] : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:   cir.switch(%[[COND]] : !s32i) {
// CIR-NEXT:   cir.case(default, []) {
// CIR-NEXT:     cir.break
// CIR-NEXT:   }
// CIR-NEXT:   cir.yield
// CIR-NEXT:   }

// LLVM-LABEL: define{{.*}} void @_Z3sw3i
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// LLVM:   ]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[EXIT:.*]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw3i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

int sw4(int a) {
  switch (a) {
  case 42: {
    return 3;
  }
  default:
    return 2;
  }
  return 0;
}

// CIR: cir.func{{.*}} @_Z3sw4i
// CIR:       cir.switch(%[[COND:.*]] : !s32i) {
// CIR-NEXT:       cir.case(equal, [#cir.int<42> : !s32i]) {
// CIR-NEXT:         cir.scope {
// CIR-NEXT:           %[[THREE:.*]] = cir.const #cir.int<3> : !s32i
// CIR-NEXT:           cir.store{{.*}} %[[THREE]], %[[RETVAL:.*]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT:           %[[RET3:.*]] = cir.load{{.*}} %[[RETVAL]] : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:           cir.return %[[RET3]] : !s32i
// CIR-NEXT:         }
// CIR-NEXT:         cir.yield
// CIR-NEXT:       }
// CIR-NEXT:       cir.case(default, []) {
// CIR-NEXT:         %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
// CIR-NEXT:         cir.store{{.*}} %[[TWO]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT:         %[[RET2:.*]] = cir.load{{.*}} %[[RETVAL]] : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:         cir.return %[[RET2]] : !s32i
// CIR-NEXT:       }
// CIR-NEXT:       cir.yield
// CIR-NEXT:  }

// LLVM: define{{.*}} i32 @_Z3sw4i
// LLVM:   %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM:   %[[RET_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM:   br label %[[ENTRY:.*]]
// LLVM: [[ENTRY]]:
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// LLVM-DAG:     i32 42, label %[[CASE42:.*]]
// LLVM:   ]
// LLVM: [[CASE42]]:
// LLVM:   br label %[[CASE42_BODY:.*]]
// LLVM: [[CASE42_BODY]]:
// LLVM:   store i32 3, ptr %[[RET_ADDR]], align 4
// LLVM:   %[[RET3:.*]] = load i32, ptr %[[RET_ADDR]], align 4
// LLVM:   ret i32 %[[RET3]]
// LLVM: [[DEFAULT]]:
// LLVM:   store i32 2, ptr %[[RET_ADDR]], align 4
// LLVM:   %[[RET2:.*]] = load i32, ptr %[[RET_ADDR]], align 4
// LLVM:   ret i32 %[[RET2]]
// LLVM: [[EXIT_UNRE:.*]]:
// LLVM:   store i32 0, ptr %[[RET_ADDR]], align 4
// LLVM:   %[[RET0:.*]] = load i32, ptr %[[RET_ADDR]], align 4
// LLVM:   ret i32 %[[RET0]]

// OGCG: define{{.*}} i32 @_Z3sw4i
// OGCG: entry:
// OGCG:   %[[RETVAL:.*]] = alloca i32, align 4
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// OGCG:     i32 42, label %[[SW42:.*]]
// OGCG:   ]
// OGCG: [[SW42]]:
// OGCG:   br label %[[RETURN:.*]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[RETURN]]
// OGCG: [[RETURN]]:
// OGCG:   %[[RETVAL_LOAD:.*]] = load i32, ptr %[[RETVAL]], align 4
// OGCG:   ret i32 %[[RETVAL_LOAD]]

void sw5(int a) {
  switch (a) {
  case 1:;
  }
}

// CIR: cir.func{{.*}} @_Z3sw5i
// CIR: cir.switch(%[[A:.*]] : !s32i) {
// CIR-NEXT:   cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT:   }
// CIR-NEXT:   cir.yield
// CIR-NEXT:   }

// LLVM-LABEL: define{{.*}} void @_Z3sw5i
// LLVM:   %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM:   br label %[[ENTRY:.*]]
// LLVM: [[ENTRY]]:
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[EXIT:.*]] [
// LLVM-DAG:     i32 1, label %[[CASE1:.*]]
// LLVM:   ]
// LLVM: [[CASE1]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw5i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[SW_EPILOG:.*]] [
// OGCG:     i32 1, label %[[SW1:.*]]
// OGCG:   ]
// OGCG: [[SW1]]:
// OGCG:   br label %[[SW_EPILOG]]
// OGCG: [[SW_EPILOG]]:
// OGCG:   ret void

void sw6(int a) {
  switch (a) {
  case 0:
  case 1:
  case 2:
    break;
  case 3:
  case 4:
  case 5:
    break;
  }
}

// CIR: cir.func{{.*}} @_Z3sw6i
// CIR: cir.switch(%[[A:.*]] : !s32i) {
// CIR-NEXT: cir.case(equal, [#cir.int<0> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR-NEXT:     cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<4> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<5> : !s32i]) {
// CIR-NEXT:     cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z3sw6i
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[EXIT:.*]] [
// LLVM-DAG:     i32 0, label %[[CASE0:.*]]
// LLVM-DAG:     i32 1, label %[[CASE1:.*]]
// LLVM-DAG:     i32 2, label %[[CASE2:.*]]
// LLVM-DAG:     i32 3, label %[[CASE3:.*]]
// LLVM-DAG:     i32 4, label %[[CASE4:.*]]
// LLVM-DAG:     i32 5, label %[[CASE5:.*]]
// LLVM:   ]
// LLVM: [[CASE0]]:
// LLVM:   br label %[[CASE0_CONT:.*]]
// LLVM: [[CASE0_CONT]]:
// LLVM:   br label %[[CASE1]]
// LLVM: [[CASE1]]:
// LLVM:   br label %[[CASE1_CONT:.*]]
// LLVM: [[CASE1_CONT]]:
// LLVM:   br label %[[CASE2]]
// LLVM: [[CASE2]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[CASE3]]:
// LLVM:   br label %[[CASE3_CONT:.*]]
// LLVM: [[CASE3_CONT]]:
// LLVM:   br label %[[CASE4]]
// LLVM: [[CASE4]]:
// LLVM:   br label %[[CASE4_CONT:.*]]
// LLVM: [[CASE4_CONT]]:
// LLVM:   br label %[[CASE5]]
// LLVM: [[CASE5]]:
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw6i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   store i32 %a, ptr %[[A_ADDR]], align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[EPILOG:.*]] [
// OGCG:     i32 0, label %[[BB0:.*]]
// OGCG:     i32 1, label %[[BB0]]
// OGCG:     i32 2, label %[[BB0]]
// OGCG:     i32 3, label %[[BB1:.*]]
// OGCG:     i32 4, label %[[BB1]]
// OGCG:     i32 5, label %[[BB1]]
// OGCG:   ]
// OGCG: [[BB0]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[BB1]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

void sw7(int a) {
  switch (a) {
  case 0:
  case 1:
  case 2:
    int x;
  case 3:
  case 4:
  case 5:
    break;
  }
}

// CIR: cir.func{{.*}} @_Z3sw7i
// CIR: %[[X:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x"]
// CIR: cir.switch(%[[A:.*]] : !s32i)
// CIR-NEXT: cir.case(equal, [#cir.int<0> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<4> : !s32i]) {
// CIR-NEXT:     cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<5> : !s32i]) {
// CIR-NEXT:     cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.yield
// CIR: }

// LLVM: define{{.*}} void @_Z3sw7i
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[EXIT:.*]] [
// LLVM-DAG:     i32 0, label %[[CASE0:.*]]
// LLVM-DAG:     i32 1, label %[[CASE1:.*]]
// LLVM-DAG:     i32 2, label %[[CASE2:.*]]
// LLVM-DAG:     i32 3, label %[[CASE3:.*]]
// LLVM-DAG:     i32 4, label %[[CASE4:.*]]
// LLVM-DAG:     i32 5, label %[[CASE5:.*]]
// LLVM:   ]
// LLVM: [[CASE0]]:
// LLVM:   br label %[[CASE0_CONT:.*]]
// LLVM: [[CASE0_CONT]]:
// LLVM:   br label %[[CASE1]]
// LLVM: [[CASE1]]:
// LLVM:   br label %[[CASE1_CONT:.*]]
// LLVM: [[CASE1_CONT]]:
// LLVM:   br label %[[CASE2]]
// LLVM: [[CASE2]]:
// LLVM:   br label %[[CASE2_CONT:.*]]
// LLVM: [[CASE2_CONT]]:
// LLVM:   br label %[[CASE3]]
// LLVM: [[CASE3]]:
// LLVM:   br label %[[CASE3_CONT:.*]]
// LLVM: [[CASE3_CONT]]:
// LLVM:   br label %[[CASE4]]
// LLVM: [[CASE4]]:
// LLVM:   br label %[[CASE4_CONT:.*]]
// LLVM: [[CASE4_CONT]]:
// LLVM:   br label %[[CASE5]]
// LLVM: [[CASE5]]:
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw7i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[EPILOG:.*]] [
// OGCG:     i32 0, label %[[BB0:.*]]
// OGCG:     i32 1, label %[[BB0]]
// OGCG:     i32 2, label %[[BB0]]
// OGCG:     i32 3, label %[[BB1:.*]]
// OGCG:     i32 4, label %[[BB1]]
// OGCG:     i32 5, label %[[BB1]]
// OGCG:   ]
// OGCG: [[BB0]]:
// OGCG:   br label %[[BB1]]
// OGCG: [[BB1]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void


void sw8(int a) {
  switch (a)
  {
  case 3:
    break;
  case 4:
  default:
    break;
  }
}

// CIR:    cir.func{{.*}} @_Z3sw8i
// CIR:    cir.switch(%[[A:.*]] : !s32i)
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<4> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(default, []) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z3sw8i
// LLVM:   switch i32 %[[COND:.*]], label %[[DEFAULT:.*]] [
// LLVM-DAG:  i32 3, label %[[CASE3:.*]]
// LLVM-DAG:  i32 4, label %[[CASE4:.*]]
// LLVM:   ]
// LLVM: [[CASE3]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[CASE4]]:
// LLVM:   br label %[[CASE4_CONT:.*]]
// LLVM: [[CASE4_CONT]]:
// LLVM:   br label %[[DEFAULT]]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[EXIT]]:
// LLVM:    br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw8i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// OGCG:     i32 3, label %[[SW3:.*]]
// OGCG:     i32 4, label %[[SW4:.*]]
// OGCG:   ]
// OGCG: [[SW3]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[SW4]]:
// OGCG:   br label %[[DEFAULT]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

void sw9(int a) {
  switch (a)
  {
  case 3:
    break;
  default:
  case 4:
    break;
  }
}

// CIR:    cir.func{{.*}} @_Z3sw9i
// CIR:    cir.switch(%[[A:.*]] : !s32i)
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(default, []) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<4> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z3sw9i
// LLVM:   switch i32 %[[COND:.*]], label %[[DEFAULT:.*]] [
// LLVM-DAG:     i32 3, label %[[CASE3:.*]]
// LLVM-DAG:     i32 4, label %[[CASE4:.*]]
// LLVM:   ]
// LLVM: [[CASE3]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[DEFAULT_CONT:.*]]
// LLVM: [[DEFAULT_CONT]]:
// LLVM:   br label %[[CASE4]]
// LLVM: [[CASE4]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z3sw9i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// OGCG:     i32 3, label %[[SW3:.*]]
// OGCG:     i32 4, label %[[SW4:.*]]
// OGCG:   ]
// OGCG: [[SW3]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[SW4]]
// OGCG: [[SW4]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

void sw10(int a) {
  switch (a)
  {
  case 3:
    break;
  case 4:
  default:
  case 5:
    break;
  }
}

// CIR:    cir.func{{.*}} @_Z4sw10i
// CIR:    cir.switch(%[[A:.*]] : !s32i)
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<4> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(default, []) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<5> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z4sw10i
// LLVM:   switch i32 %[[COND:.*]], label %[[DEFAULT:.*]] [
// LLVM-DAG:     i32 3, label %[[CASE_3:.*]]
// LLVM-DAG:     i32 4, label %[[CASE_4:.*]]
// LLVM-DAG:     i32 5, label %[[CASE_5:.*]]
// LLVM:   ]
// LLVM: [[CASE_3]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[CASE_4]]:
// LLVM:   br label %[[CASE4_CONT:.*]]
// LLVM: [[CASE4_CONT]]:
// LLVM:   br label %[[DEFAULT]]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[DEFAULT_CONT:.*]]
// LLVM: [[DEFAULT_CONT]]:
// LLVM:   br label %[[CASE_5]]
// LLVM: [[CASE_5]]:
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z4sw10i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// OGCG:     i32 3, label %[[BB3:.*]]
// OGCG:     i32 4, label %[[BB4:.*]]
// OGCG:     i32 5, label %[[BB5:.*]]
// OGCG:   ]
// OGCG: [[BB3]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[BB4]]:
// OGCG:   br label %[[DEFAULT]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[BB5]]
// OGCG: [[BB5]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

void sw11(int a) {
  switch (a)
  {
  case 3:
    break;
  case 4:
  case 5:
  default:
  case 6:
  case 7:
    break;
  }
}

// CIR:    cir.func{{.*}} @_Z4sw11i
// CIR:    cir.switch(%[[A:.*]] : !s32i)
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<4> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<5> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(default, []) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<6> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<7> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z4sw11i
// LLVM:   switch i32 %[[COND:.*]], label %[[DEFAULT:.*]] [
// LLVM-DAG:     i32 3, label %[[CASE_3:.*]]
// LLVM-DAG:     i32 4, label %[[CASE_4:.*]]
// LLVM-DAG:     i32 5, label %[[CASE_5:.*]]
// LLVM-DAG:     i32 6, label %[[CASE_6:.*]]
// LLVM-DAG:     i32 7, label %[[CASE_7:.*]]
// LLVM:   ]
// LLVM: [[CASE_3]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[CASE_4]]:
// LLVM:   br label %[[CASE4_CONT:.*]]
// LLVM: [[CASE4_CONT]]:
// LLVM:   br label %[[CASE_5]]
// LLVM: [[CASE_5]]:
// LLVM:   br label %[[CASE5_CONT:.*]]
// LLVM: [[CASE5_CONT]]:
// LLVM:   br label %[[DEFAULT]]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[DEFAULT_CONT:.*]]
// LLVM: [[DEFAULT_CONT]]:
// LLVM:   br label %[[CASE_6]]
// LLVM: [[CASE_6]]:
// LLVM:   br label %[[CASE6_CONT:.*]]
// LLVM: [[CASE6_CONT]]:
// LLVM:   br label %[[CASE_7]]
// LLVM: [[CASE_7]]:
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z4sw11i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[DEFAULT:.*]] [
// OGCG:     i32 3, label %[[BB3:.*]]
// OGCG:     i32 4, label %[[BB4:.*]]
// OGCG:     i32 5, label %[[BB4]]
// OGCG:     i32 6, label %[[BB6:.*]]
// OGCG:     i32 7, label %[[BB6]]
// OGCG:   ]
// OGCG: [[BB3]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[BB4]]:
// OGCG:   br label %[[DEFAULT]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[BB6]]
// OGCG: [[BB6]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

void sw12(int a) {
  switch (a)
  {
  case 3:
    return;
    break;
  }
}

//      CIR: cir.func{{.*}} @_Z4sw12i
//      CIR:   cir.scope {
//      CIR:     cir.switch
// CIR-NEXT:     cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:       cir.return
// CIR-NEXT:     ^bb1:  // no predecessors
// CIR-NEXT:       cir.break
// CIR-NEXT:     }

// LLVM: define{{.*}} void @_Z4sw12i
// LLVM:   switch i32 %[[COND:.*]], label %[[EXIT:.*]] [
// LLVM-DAG:     i32 3, label %[[CASE_3:.*]]
// LLVM:   ]
// LLVM: [[CASE_3]]:
// LLVM:   ret void
// LLVM: [[UNREACHABLE:.*]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z4sw12i
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[SW_DEFAULT:.*]] [
// OGCG:     i32 3, label %[[SW3:.*]]
// OGCG:   ]
// OGCG: [[SW3]]:
// OGCG:   br label %[[SW_DEFAULT]]
// OGCG: [[SW_DEFAULT]]:
// OGCG:   ret void

void sw13(int a, int b) {
  switch (a) {
  case 1:
    switch (b) {
    case 2:
      break;
    }
  }
}

//      CIR:  cir.func{{.*}} @_Z4sw13ii
//      CIR:    cir.scope {
//      CIR:      cir.switch
// CIR-NEXT:      cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT:        cir.scope {
//      CIR:          cir.switch
// CIR-NEXT:          cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR-NEXT:            cir.break
// CIR-NEXT:          }
// CIR-NEXT:          cir.yield
// CIR-NEXT:        }
// CIR-NEXT:      }
//      CIR:    cir.yield
//      CIR:    }
//      CIR:    cir.return

// LLVM: define{{.*}} void @_Z4sw13ii
// LLVM:   switch i32 %[[COND:.*]], label %[[OUTER_EXIT:.*]] [
// LLVM-DAG:     i32 1, label %[[CASE_A_1:.*]]
// LLVM:   ]
// LLVM: [[CASE_A_1]]:
// LLVM:   br label %[[LOAD_B:.*]]
// LLVM: [[LOAD_B]]:
// LLVM:   %[[B_VAL:.*]] = load i32, ptr %[[B_ADDR:.*]], align 4
// LLVM:   br label %[[INNER_SWITCH:.*]]
// LLVM: [[INNER_SWITCH]]:
// LLVM:   switch i32 %[[B_VAL]], label %[[INNER_EXIT:.*]] [
// LLVM-DAG:     i32 2, label %[[CASE_B_2:.*]]
// LLVM:   ]
// LLVM: [[CASE_B_2]]:
// LLVM:   br label %[[INNER_EXIT]]
// LLVM: [[INNER_EXIT]]:
// LLVM:   br label %[[INNER_EXIT_CONT:.*]]
// LLVM: [[INNER_EXIT_CONT]]:
// LLVM:   br label %[[MERGE:.*]]
// LLVM: [[MERGE]]:
// LLVM:   br label %[[OUTER_EXIT]]
// LLVM: [[OUTER_EXIT]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[EXIT]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z4sw13ii
// OGCG: entry:
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[B_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[EPILOG2:.*]] [
// OGCG:     i32 1, label %[[SW1:.*]]
// OGCG:   ]
// OGCG: [[SW1]]:
// OGCG:   %[[B_VAL:.*]] = load i32, ptr %[[B_ADDR]], align 4
// OGCG:   switch i32 %[[B_VAL]], label %[[EPILOG:.*]] [
// OGCG:     i32 2, label %[[SW12:.*]]
// OGCG:   ]
// OGCG: [[SW12]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   br label %[[EPILOG2]]
// OGCG: [[EPILOG2]]:
// OGCG:   ret void

void sw14(int x) {
  switch (x) {
    case 1:
    case 2:
    case 3 ... 6:
    case 7:
      break;
    default:
      break;
  }
}

// CIR:      cir.func{{.*}} @_Z4sw14i
// CIR:      cir.switch
// CIR-NEXT: cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(range, [#cir.int<3> : !s32i, #cir.int<6> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<7> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(default, []) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z4sw14i
// LLVM:   switch i32 %[[COND:.*]], label %[[DEFAULT:.*]] [
// LLVM-DAG:     i32 1, label %[[CASE1:.*]]
// LLVM-DAG:     i32 2, label %[[CASE2:.*]]
// LLVM-DAG:     i32 3, label %[[CASE3_TO_6:.*]]
// LLVM-DAG:     i32 4, label %[[CASE3_TO_6]]
// LLVM-DAG:     i32 5, label %[[CASE3_TO_6]]
// LLVM-DAG:     i32 6, label %[[CASE3_TO_6]]
// LLVM-DAG:     i32 7, label %[[CASE7:.*]]
// LLVM:   ]
// LLVM: [[CASE1]]:
// LLVM:   br label %[[AFTER1:.*]]
// LLVM: [[AFTER1]]:
// LLVM:   br label %[[CASE2]]
// LLVM: [[CASE2]]:
// LLVM:   br label %[[AFTER2:.*]]
// LLVM: [[AFTER2]]:
// LLVM:   br label %[[CASE3_TO_6]]
// LLVM: [[CASE3_TO_6]]:
// LLVM:   br label %[[AFTER3_6:.*]]
// LLVM: [[AFTER3_6]]:
// LLVM:   br label %[[CASE7]]
// LLVM: [[CASE7]]:
// LLVM:   br label %[[EXIT1:.*]]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[EXIT1]]
// LLVM: [[EXIT1]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z4sw14i
// OGCG: entry:
// OGCG:   %[[X_ADDR:.*]] = alloca i32, align 4
// OGCG:   store i32 %x, ptr %[[X_ADDR]], align 4
// OGCG:   %[[X_VAL:.*]] = load i32, ptr %[[X_ADDR]], align 4
// OGCG:   switch i32 %[[X_VAL]], label %[[DEFAULT:.*]] [
// OGCG-DAG:     i32 1, label %[[BB1:.*]]
// OGCG-DAG:     i32 2, label %[[BB1]]
// OGCG-DAG:     i32 3, label %[[BB2:.*]]
// OGCG-DAG:     i32 4, label %[[BB2]]
// OGCG-DAG:     i32 5, label %[[BB2]]
// OGCG-DAG:     i32 6, label %[[BB2]]
// OGCG-DAG:     i32 7, label %[[BB3:.*]]
// OGCG:   ]
// OGCG: [[BB1]]:
// OGCG:   br label %[[BB2]]
// OGCG: [[BB2]]:
// OGCG:   br label %[[BB3]]
// OGCG: [[BB3]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

void sw15(int x) {
  int y;
  switch (x) {
    case 1:
    case 2:
      y = 0;
    case 3:
      break;
    default:
      break;
  }
}

// CIR:      cir.func{{.*}} @_Z4sw15i
// CIR:      %[[Y:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["y"]
// CIR:      cir.switch
// CIR-NEXT: cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR-NEXT:   %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
// CIR-NEXT:   cir.store{{.*}} %[[ZERO]], %[[Y]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT:   cir.yield
// CIR-NEXT: }
// CIR-NEXT: cir.case(equal, [#cir.int<3> : !s32i]) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }
// CIR-NEXT: cir.case(default, []) {
// CIR-NEXT:   cir.break
// CIR-NEXT: }

// LLVM: define{{.*}} void @_Z4sw15i
// LLVM:   switch i32 %[[COND:.*]], label %[[DEFAULT:.*]] [
// LLVM-DAG:     i32 1, label %[[CASE1:.*]]
// LLVM-DAG:     i32 2, label %[[CASE2:.*]]
// LLVM-DAG:     i32 3, label %[[CASE3:.*]]
// LLVM:   ]
// LLVM: [[CASE1]]:
// LLVM:   br label %[[CASE1_CONT:.*]]
// LLVM: [[CASE1_CONT]]:
// LLVM:   br label %[[CASE2]]
// LLVM: [[CASE2]]:
// LLVM:   store i32 0, ptr %[[Y_ADDR:.*]], align 4
// LLVM:   br label %[[CASE2_CONT:.*]]
// LLVM: [[CASE2_CONT]]:
// LLVM:   br label %[[CASE3]]
// LLVM: [[CASE3]]:
// LLVM:   br label %[[EXIT:.*]]
// LLVM: [[DEFAULT]]:
// LLVM:   br label %[[EXIT]]
// LLVM: [[EXIT]]:
// LLVM:   br label %[[RET:.*]]
// LLVM: [[RET]]:
// LLVM:   ret void

// OGCG: define{{.*}} void @_Z4sw15i
// OGCG: entry:
// OGCG:   %[[X_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[Y:.*]] = alloca i32, align 4
// OGCG:   store i32 %x, ptr %[[X_ADDR]], align 4
// OGCG:   %[[X_VAL:.*]] = load i32, ptr %[[X_ADDR]], align 4
// OGCG:   switch i32 %[[X_VAL]], label %[[DEFAULT:.*]] [
// OGCG-DAG:     i32 1, label %[[BB0:.*]]
// OGCG-DAG:     i32 2, label %[[BB0]]
// OGCG-DAG:     i32 3, label %[[BB1:.*]]
// OGCG:   ]
// OGCG: [[BB0]]:
// OGCG:   store i32 0, ptr %[[Y]], align 4
// OGCG:   br label %[[BB1]]
// OGCG: [[BB1]]:
// OGCG:   br label %[[EPILOG:.*]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:
// OGCG:   ret void

int nested_switch(int a) {
  switch (int b = 1; a) {
  case 0:
    b = b + 1;
  case 1:
    return b;
  case 2: {
    b = b + 1;
    if (a > 1000) {
        case 9:
          b = a + b;
    }
    if (a > 500) {
        case 7:
          return a + b;
    }
    break;
  }
  }

  return 0;
}

// CIR: cir.switch(%[[COND:.*]] : !s32i) {
// CIR:   cir.case(equal, [#cir.int<0> : !s32i]) {
// CIR:     cir.yield
// CIR:   }
// CIR:   cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR:     cir.return
// CIR:   }
// CIR:   cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR:     cir.scope {
// CIR:     cir.scope {
// CIR:       cir.if
// CIR:         cir.case(equal, [#cir.int<9> : !s32i]) {
// CIR:         cir.yield
// CIR:     cir.scope {
// CIR:         cir.if
// CIR:           cir.case(equal, [#cir.int<7> : !s32i]) {
// CIR:           cir.return

// LLVM: define{{.*}} i32 @_Z13nested_switchi
// LLVM:   %[[B_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM:   %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM:   %[[RES_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM:   store i32 %[[ARG:.*]], ptr %[[A_ADDR]], align 4
// LLVM:   br label %[[ENTRY:.*]]
// LLVM: [[ENTRY]]:
// LLVM:   store i32 1, ptr %[[B_ADDR]], align 4
// LLVM:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// LLVM:   br label %[[SWITCH:.*]]
// LLVM: [[SWITCH]]:
// LLVM:   switch i32 %[[A_VAL]], label %[[EXIT:.*]] [
// LLVM-DAG:     i32 0, label %[[CASE0:.*]]
// LLVM-DAG:     i32 1, label %[[CASE1:.*]]
// LLVM-DAG:     i32 2, label %[[CASE2:.*]]
// LLVM-DAG:     i32 9, label %[[CASE9:.*]]
// LLVM-DAG:     i32 7, label %[[CASE7:.*]]
// LLVM:   ]
// LLVM: [[CASE0]]:
// LLVM:   %[[B0:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   %[[B1:.*]] = add nsw i32 %[[B0]], 1
// LLVM:   store i32 %[[B1]], ptr %[[B_ADDR]], align 4
// LLVM:   br label %[[CASE0_CONT:.*]]
// LLVM: [[CASE0_CONT]]:
// LLVM:   br label %[[CASE1]]
// LLVM: [[CASE1]]:
// LLVM:   %[[B1a:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   store i32 %[[B1a]], ptr %[[RES_ADDR]], align 4
// LLVM:   %[[RET1:.*]] = load i32, ptr %[[RES_ADDR]], align 4
// LLVM:   ret i32 %[[RET1]]
// LLVM: [[CASE2]]:
// LLVM:   br label %[[CASE2_BODY:.*]]
// LLVM: [[CASE2_BODY]]:
// LLVM:   %[[B2:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   %[[B3:.*]] = add nsw i32 %[[B2]], 1
// LLVM:   store i32 %[[B3]], ptr %[[B_ADDR]], align 4
// LLVM:   br label %[[CASE2_CONT:.*]]
// LLVM: [[CASE9]]:
// LLVM:   %[[A9:.*]] = load i32, ptr %[[A_ADDR]], align 4
// LLVM:   %[[B4:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   %[[SUM9:.*]] = add nsw i32 %[[A9]], %[[B4]]
// LLVM:   store i32 %[[SUM9]], ptr %[[B_ADDR]], align 4
// LLVM:   br label %[[CASE2_CONT1:.*]]
// LLVM: [[CASE7]]:
// LLVM:   %[[A7:.*]] = load i32, ptr %[[A_ADDR]], align 4
// LLVM:   %[[B5:.*]] = load i32, ptr %[[B_ADDR]], align 4
// LLVM:   %[[SUM7:.*]] = add nsw i32 %[[A7]], %[[B5]]
// LLVM:   store i32 %[[SUM7]], ptr %[[RES_ADDR]], align 4
// LLVM:   %[[RET7:.*]] = load i32, ptr %[[RES_ADDR]], align 4
// LLVM:   ret i32 %[[RET7]]
// LLVM: [[EXIT]]:
// LLVM:   store i32 0, ptr %[[RES_ADDR]], align 4
// LLVM:   %[[RET0:.*]] = load i32, ptr %[[RES_ADDR]], align 4
// LLVM:   ret i32 %[[RET0]]

// OGCG: define{{.*}} i32 @_Z13nested_switchi
// OGCG: entry:
// OGCG:   %[[RETVAL:.*]] = alloca i32, align 4
// OGCG:   %[[A_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[B:.*]] = alloca i32, align 4
// OGCG:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   switch i32 %[[A_VAL]], label %[[EPILOG:.*]] [
// OGCG:     i32 0, label %[[SW0:.*]]
// OGCG:     i32 1, label %[[SW1:.*]]
// OGCG:     i32 2, label %[[SW2:.*]]
// OGCG:     i32 9, label %[[SW4:.*]]
// OGCG:     i32 7, label %[[SW8:.*]]
// OGCG:   ]
// OGCG: [[SW0]]:
// OGCG:   %[[B_VAL0:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   %[[ADD0:.*]] = add nsw i32 %[[B_VAL0]], 1
// OGCG:   br label %[[SW1]]
// OGCG: [[SW1]]:
// OGCG:   %[[B_VAL1:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   br label %[[RETURN:.*]]
// OGCG: [[SW2]]:
// OGCG:   %[[B_VAL2:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   %[[ADD2:.*]] = add nsw i32 %[[B_VAL2]], 1
// OGCG:   %[[A_VAL2:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   %[[CMP1000:.*]] = icmp sgt i32 %[[A_VAL2]], 1000
// OGCG:   br i1 %[[CMP1000]], label %[[IFTHEN:.*]], label %[[IFEND:.*]]
// OGCG: [[IFTHEN]]:
// OGCG:   br label %[[SW4]]
// OGCG: [[SW4]]:
// OGCG:   %[[A_VAL4:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   %[[B_VAL4:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   %[[ADD4:.*]] = add nsw i32 %[[A_VAL4]], %[[B_VAL4]]
// OGCG:   br label %[[IFEND]]
// OGCG: [[IFEND]]:
// OGCG:   %[[A_VAL5:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   %[[CMP500:.*]] = icmp sgt i32 %[[A_VAL5]], 500
// OGCG:   br i1 %[[CMP500]], label %[[IFTHEN7:.*]], label %[[IFEND10:.*]]
// OGCG: [[IFTHEN7]]:
// OGCG:   br label %[[SW8]]
// OGCG: [[SW8]]:
// OGCG:   %[[A_VAL8:.*]] = load i32, ptr %[[A_ADDR]], align 4
// OGCG:   %[[B_VAL8:.*]] = load i32, ptr %[[B]], align 4
// OGCG:   %[[ADD8:.*]] = add nsw i32 %[[A_VAL8]], %[[B_VAL8]]
// OGCG:   br label %[[RETURN]]
// OGCG: [[IFEND10]]:
// OGCG:   br label %[[EPILOG]]
// OGCG: [[EPILOG]]:

int sw_return_multi_cases(int x) {
  switch (x) {
  case 0:
    return 0;
  case 1:
    return 1;
  case 2:
    return 2;
  default:
    return -1;
  }
}

// CIR-LABEL: cir.func{{.*}} @_Z21sw_return_multi_casesi
// CIR:       cir.switch(%{{.*}} : !s32i) {
// CIR-NEXT:  cir.case(equal, [#cir.int<0> : !s32i]) {
// CIR:         %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
// CIR:         cir.store{{.*}} %[[ZERO]], %{{.*}} : !s32i, !cir.ptr<!s32i>
// CIR:         %[[RET0:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:    cir.return %[[RET0]] : !s32i
// CIR-NEXT:  }
// CIR-NEXT:  cir.case(equal, [#cir.int<1> : !s32i]) {
// CIR:         %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
// CIR:         cir.store{{.*}} %[[ONE]], %{{.*}} : !s32i, !cir.ptr<!s32i>
// CIR:         %[[RET1:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:    cir.return %[[RET1]] : !s32i
// CIR-NEXT:  }
// CIR-NEXT:  cir.case(equal, [#cir.int<2> : !s32i]) {
// CIR:         %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
// CIR:         cir.store{{.*}} %[[TWO]], %{{.*}} : !s32i, !cir.ptr<!s32i>
// CIR:         %[[RET2:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:    cir.return %[[RET2]] : !s32i
// CIR-NEXT:  }
// CIR-NEXT:  cir.case(default, []) {
// CIR:         %[[MINUS_ONE:.*]] = cir.const #cir.int<-1> : !s32i
// CIR:         cir.store{{.*}} %[[MINUS_ONE]], %{{.*}} : !s32i, !cir.ptr<!s32i>
// CIR:         %[[RETDEF:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, !s32i
// CIR-NEXT:    cir.return %[[RETDEF]] : !s32i
// CIR-NEXT:  }
// CIR-NEXT:  cir.yield

// LLVM-LABEL: define{{.*}} i32 @_Z21sw_return_multi_casesi
// LLVM:   switch i32 %{{.*}}, label %[[DEFAULT:.*]] [
// LLVM-DAG:   i32 0, label %[[CASE0:.*]]
// LLVM-DAG:   i32 1, label %[[CASE1:.*]]
// LLVM-DAG:   i32 2, label %[[CASE2:.*]]
// LLVM:   ]
// LLVM: [[CASE0]]:
// LLVM:   store i32 0, ptr %{{.*}}, align 4
// LLVM:   %{{.*}} = load i32, ptr %{{.*}}, align 4
// LLVM:   ret i32 %{{.*}}
// LLVM: [[CASE1]]:
// LLVM:   store i32 1, ptr %{{.*}}, align 4
// LLVM:   %{{.*}} = load i32, ptr %{{.*}}, align 4
// LLVM:   ret i32 %{{.*}}
// LLVM: [[CASE2]]:
// LLVM:   store i32 2, ptr %{{.*}}, align 4
// LLVM:   %{{.*}} = load i32, ptr %{{.*}}, align 4
// LLVM:   ret i32 %{{.*}}
// LLVM: [[DEFAULT]]:
// LLVM:   store i32 -1, ptr %{{.*}}, align 4
// LLVM:   %{{.*}} = load i32, ptr %{{.*}}, align 4
// LLVM:   ret i32 %{{.*}}

// OGCG-LABEL: define{{.*}} i32 @_Z21sw_return_multi_casesi
// OGCG: entry:
// OGCG:   %[[RETVAL:.*]] = alloca i32, align 4
// OGCG:   %[[X_ADDR:.*]] = alloca i32, align 4
// OGCG:   %[[X_VAL:.*]] = load i32, ptr %[[X_ADDR]], align 4
// OGCG:   switch i32 %[[X_VAL]], label %[[DEFAULT:.*]] [
// OGCG-DAG:   i32 0, label %[[SW0:.*]]
// OGCG-DAG:   i32 1, label %[[SW1:.*]]
// OGCG-DAG:   i32 2, label %[[SW2:.*]]
// OGCG:   ]
// OGCG: [[SW0]]:
// OGCG:   br label %[[RETURN:.*]]
// OGCG: [[SW1]]:
// OGCG:   br label %[[RETURN]]
// OGCG: [[SW2]]:
// OGCG:   br label %[[RETURN]]
// OGCG: [[DEFAULT]]:
// OGCG:   br label %[[RETURN]]
// OGCG: [[RETURN]]:
// OGCG:   %[[RETVAL_LOAD:.*]] = load i32, ptr %[[RETVAL]], align 4
// OGCG:   ret i32 %[[RETVAL_LOAD]]

enum M {
 Six,
 Seven
};

void testSwitchCoverAllCase(M m) {
  switch (m) {
  case Six:case Seven:
    break;
  }
}
// CIR: cir.switch(%[[ARG:.*]] : !s32i) all_enum_cases_covered {

void testSwitchNotCoverAllCase(M m) {
  switch (m) {
  case Six:
  default:
    break;
  }
}
// CIR: cir.switch(%[[ARG:.*]] : !s32i) {
