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