Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
      2 
      3 // PR9322 and rdar://6970405
      4 
      5 // CHECK: @test1
      6 // CHECK-NOT: switch
      7 // CHECK-NOT: @dead
      8 // CHECK: add nsw i32 {{.*}}, 1
      9 // CHECK-NOT: switch
     10 // CHECK-NOT: @dead
     11 // CHECK: ret void
     12 int i;
     13 void dead();
     14 
     15 void test1() {
     16   switch (1)
     17     case 1:
     18       ++i;
     19 
     20   switch (0)
     21     case 1:
     22       dead();
     23 }
     24 
     25 
     26 // CHECK: @test2
     27 // CHECK-NOT: switch
     28 // CHECK-NOT: @dead
     29 // CHECK: add nsw i32 {{.*}}, 2
     30 // CHECK-NOT: switch
     31 // CHECK-NOT: @dead
     32 // CHECK: ret void
     33 void test2() {
     34   switch (4) {
     35   case 1:
     36     dead();
     37     break;
     38   case 4:
     39     i += 2;
     40     // Fall off the end of the switch.
     41   }
     42 }
     43 
     44 
     45 // CHECK: @test3
     46 // CHECK-NOT: switch
     47 // CHECK-NOT: @dead
     48 // CHECK: add nsw i32 {{.*}}, 2
     49 // CHECK-NOT: switch
     50 // CHECK-NOT: @dead
     51 // CHECK: ret void
     52 void test3() {
     53   switch (4) {
     54   case 1:
     55     dead();
     56     break;
     57   case 4: {
     58     i += 2;
     59     break;
     60   }
     61   }
     62 }
     63 
     64 // CHECK: @test4
     65 // CHECK-NOT: switch
     66 // CHECK-NOT: @dead
     67 // CHECK: add nsw i32 {{.*}}, 2
     68 // CHECK-NOT: switch
     69 // CHECK-NOT: @dead
     70 // CHECK: ret void
     71 void test4() {
     72   switch (4) {
     73     case 1:
     74       dead();
     75       break;
     76     default: {
     77       i += 2;
     78       break;
     79     }
     80   }
     81 }
     82 
     83 // This shouldn't crash codegen, but we don't have to optimize out the switch
     84 // in this case.
     85 void test5() {
     86   switch (1) {
     87     int x;  // eliding var decl?
     88     case 1:
     89       x = 4;
     90       i = x;
     91       break;
     92   }
     93 }
     94 
     95 // CHECK: @test6
     96 // CHECK-NOT: switch
     97 // CHECK-NOT: @dead
     98 // CHECK: ret void
     99 void test6() {
    100   // Neither case is reachable.
    101   switch (40) {
    102   case 1:
    103    dead();
    104     break;
    105   case 4: {
    106     dead();
    107     break;
    108   }
    109   }
    110 }
    111 
    112 // CHECK: @test7
    113 // CHECK-NOT: switch
    114 // CHECK-NOT: @dead
    115 // CHECK: add nsw i32
    116 // CHECK-NOT: switch
    117 // CHECK-NOT: @dead
    118 // CHECK: ret void
    119 void test7() {
    120   switch (4) {
    121   case 1:
    122       dead();
    123     break;
    124     {
    125       case 4:   // crazy brace scenario
    126         ++i;
    127     }
    128     break;
    129   }
    130 }
    131 
    132 // CHECK: @test8
    133 // CHECK-NOT: switch
    134 // CHECK-NOT: @dead
    135 // CHECK: add nsw i32
    136 // CHECK-NOT: switch
    137 // CHECK-NOT: @dead
    138 // CHECK: ret void
    139 void test8() {
    140   switch (4) {
    141   case 1:
    142     dead();
    143     break;
    144   case 4:
    145     ++i;
    146     // Fall off the end of the switch.
    147   }
    148 }
    149 
    150 // CHECK: @test9
    151 // CHECK-NOT: switch
    152 // CHECK-NOT: @dead
    153 // CHECK: add nsw i32
    154 // CHECK: add nsw i32
    155 // CHECK-NOT: switch
    156 // CHECK-NOT: @dead
    157 // CHECK: ret void
    158 void test9(int i) {
    159   switch (1) {
    160   case 5:
    161     dead();
    162   case 1:
    163     ++i;
    164     // Fall through is fine.
    165   case 4:
    166     ++i;
    167     break;
    168   }
    169 }
    170 
    171 // CHECK: @test10
    172 // CHECK-NOT: switch
    173 // CHECK: ret i32
    174 int test10(void) {
    175 	switch(8) {
    176 		case 8:
    177 			break;
    178 		case 4:
    179 			break;
    180 		default:
    181 			dead();
    182 	}
    183 
    184 	return 0;
    185 }
    186 
    187 // CHECK: @test11
    188 // CHECK-NOT: switch
    189 // CHECK: ret void
    190 void test11() {
    191   switch (1) {
    192     case 1:
    193       break;
    194     case 42: ;
    195       int x;  // eliding var decl?
    196       x = 4;
    197       break;
    198   }
    199 }
    200 
    201 // CHECK: @test12
    202 // CHECK-NOT: switch
    203 // CHECK: ret void
    204 void test12() {
    205   switch (1) {
    206   case 2: {
    207      int a;   // Ok to skip this vardecl.
    208      a = 42;
    209    }
    210   case 1:
    211     break;
    212   case 42: ;
    213     int x;  // eliding var decl?
    214     x = 4;
    215     break;
    216   }
    217 }
    218 
    219 // Verify that case 42 only calls test14 once.
    220 // CHECK: @test13
    221 // CHECK: call void @test13(i32 97)
    222 // CHECK-NEXT: br label %[[EPILOG2:[0-9.a-z]+]]
    223 // CHECK: [[EPILOG2]]
    224 // CHECK-NEXT: br label [[EPILOG:%[0-9.a-z]+]]
    225 // CHECK: call void @test13(i32 42)
    226 // CHECK-NEXT: br label [[EPILOG]]
    227 void test13(int x) {
    228   switch (x) {
    229     case 42: test13(97);  // fallthrough
    230     case 11: break;
    231     default: test13(42); break;
    232   }
    233 }
    234 
    235