Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s
      2 
      3 int foo(int i) {
      4   int j = 0;
      5   switch (i) {
      6   case -1:
      7     j = 1; break;
      8   case 1 :
      9     j = 2; break;
     10   case 2:
     11     j = 3; break;
     12   default:
     13     j = 42; break;
     14   }
     15   j = j + 1;
     16   return j;
     17 }
     18 
     19 int foo2(int i) {
     20   int j = 0;
     21   switch (i) {
     22   case 1 :
     23     j = 2; break;
     24   case 2 ... 10:
     25     j = 3; break;
     26   default:
     27     j = 42; break;
     28   }
     29   j = j + 1;
     30   return j;
     31 }
     32 
     33 int foo3(int i) {
     34   int j = 0;
     35   switch (i) {
     36   default:
     37     j = 42; break;
     38   case 111:
     39     j = 111; break;
     40   case 0 ... 100:
     41     j = 1; break;
     42   case 222:
     43     j = 222; break;
     44   }
     45   return j;
     46 }
     47 
     48 
     49 static int foo4(int i) {
     50   int j = 0;
     51   switch (i) {
     52   case 111:
     53     j = 111; break;
     54   case 0 ... 100:
     55     j = 1; break;
     56   case 222:
     57     j = 222; break;
     58   default:
     59     j = 42; break;
     60   case 501 ... 600:
     61     j = 5; break;
     62   }
     63   return j;
     64 }
     65 
     66 // CHECK-LABEL: define i32 @foo4t()
     67 // CHECK: ret i32 376
     68 // CHECK: }
     69 int foo4t() {
     70   // 111 + 1 + 222 + 42 = 376
     71   return foo4(111) + foo4(99) + foo4(222) + foo4(601);
     72 }
     73 
     74 // CHECK-LABEL: define void @foo5()
     75 // CHECK-NOT: switch
     76 // CHECK: }
     77 void foo5(){
     78     switch(0){
     79     default:
     80         if (0) {
     81 
     82         }
     83     }
     84 }
     85 
     86 // CHECK-LABEL: define void @foo6()
     87 // CHECK-NOT: switch
     88 // CHECK: }
     89 void foo6(){
     90     switch(0){
     91     }
     92 }
     93 
     94 // CHECK-LABEL: define void @foo7()
     95 // CHECK-NOT: switch
     96 // CHECK: }
     97 void foo7(){
     98     switch(0){
     99       foo7();
    100     }
    101 }
    102 
    103 
    104 // CHECK-LABEL: define i32 @f8(
    105 // CHECK: ret i32 3
    106 // CHECK: }
    107 int f8(unsigned x) {
    108   switch(x) {
    109   default:
    110     return 3;
    111   case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
    112     return 0;
    113   }
    114 }
    115 
    116 // Ensure that default after a case range is not ignored.
    117 //
    118 // CHECK-LABEL: define i32 @f9()
    119 // CHECK: ret i32 10
    120 // CHECK: }
    121 static int f9_0(unsigned x) {
    122   switch(x) {
    123   case 10 ... 0xFFFFFFFF:
    124     return 0;
    125   default:
    126     return 10;
    127   }
    128 }
    129 int f9() {
    130   return f9_0(2);
    131 }
    132 
    133 // Ensure that this doesn't compile to infinite loop in g() due to
    134 // miscompilation of fallthrough from default to a (tested) case
    135 // range.
    136 //
    137 // CHECK-LABEL: define i32 @f10()
    138 // CHECK: ret i32 10
    139 // CHECK: }
    140 static int f10_0(unsigned x) {
    141   switch(x) {
    142   default:
    143     x += 1;
    144   case 10 ... 0xFFFFFFFF:
    145     return 0;
    146   }
    147 }
    148 
    149 int f10() {
    150   f10_0(1);
    151   return 10;
    152 }
    153 
    154 // This generated incorrect code because of poor switch chaining.
    155 //
    156 // CHECK-LABEL: define i32 @f11(
    157 // CHECK: ret i32 3
    158 // CHECK: }
    159 int f11(int x) {
    160   switch(x) {
    161   default:
    162     return 3;
    163   case 10 ... 0xFFFFFFFF:
    164     return 0;
    165   }
    166 }
    167 
    168 // This just asserted because of the way case ranges were calculated.
    169 //
    170 // CHECK-LABEL: define i32 @f12(
    171 // CHECK: ret i32 3
    172 // CHECK: }
    173 int f12(int x) {
    174   switch (x) {
    175   default:
    176     return 3;
    177   case 10 ... -1:
    178     return 0;
    179   }
    180 }
    181 
    182 // Make sure return is not constant (if empty range is skipped or miscompiled)
    183 //
    184 // CHECK-LABEL: define i32 @f13(
    185 // CHECK: ret i32 %
    186 // CHECK: }
    187 int f13(unsigned x) {
    188   switch(x) {
    189   case 2:
    190     // fallthrough empty range
    191   case 10 ... 9:
    192     return 10;
    193   default:
    194     return 0;
    195   }
    196 }
    197 
    198 // Don't delete a basic block that we want to introduce later references to.
    199 // This isn't really specific to switches, but it's easy to show with them.
    200 // rdar://problem/8837067
    201 int f14(int x) {
    202   switch (x) {
    203 
    204   // case range so that the case block has no predecessors
    205   case 0 ... 15:
    206     // any expression which doesn't introduce a new block
    207     (void) 0;
    208     // kaboom
    209 
    210   default:
    211     return x;
    212   }
    213 }
    214