// 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, ["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, ["yolo", init] // CIR-NEXT: %[[FOMO:.*]] = cir.alloca !s32i, !cir.ptr, ["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 // 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 // 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 // CIR-NEXT: %[[RET3:.*]] = cir.load{{.*}} %[[RETVAL]] : !cir.ptr, !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 // CIR-NEXT: %[[RET2:.*]] = cir.load{{.*}} %[[RETVAL]] : !cir.ptr, !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, ["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, ["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 // 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]]: