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