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