|  | // RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s | 
|  |  | 
|  | int foo(int i) { | 
|  | int j = 0; | 
|  | switch (i) { | 
|  | case -1: | 
|  | j = 1; break; | 
|  | case 1 : | 
|  | j = 2; break; | 
|  | case 2: | 
|  | j = 3; break; | 
|  | default: | 
|  | j = 42; break; | 
|  | } | 
|  | j = j + 1; | 
|  | return j; | 
|  | } | 
|  |  | 
|  | int foo2(int i) { | 
|  | int j = 0; | 
|  | switch (i) { | 
|  | case 1 : | 
|  | j = 2; break; | 
|  | case 2 ... 10: | 
|  | j = 3; break; | 
|  | default: | 
|  | j = 42; break; | 
|  | } | 
|  | j = j + 1; | 
|  | return j; | 
|  | } | 
|  |  | 
|  | int foo3(int i) { | 
|  | int j = 0; | 
|  | switch (i) { | 
|  | default: | 
|  | j = 42; break; | 
|  | case 111: | 
|  | j = 111; break; | 
|  | case 0 ... 100: | 
|  | j = 1; break; | 
|  | case 222: | 
|  | j = 222; break; | 
|  | } | 
|  | return j; | 
|  | } | 
|  |  | 
|  |  | 
|  | static int foo4(int i) { | 
|  | int j = 0; | 
|  | switch (i) { | 
|  | case 111: | 
|  | j = 111; break; | 
|  | case 0 ... 100: | 
|  | j = 1; break; | 
|  | case 222: | 
|  | j = 222; break; | 
|  | default: | 
|  | j = 42; break; | 
|  | case 501 ... 600: | 
|  | j = 5; break; | 
|  | } | 
|  | return j; | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: define i32 @foo4t() | 
|  | // CHECK: ret i32 376 | 
|  | // CHECK: } | 
|  | int foo4t() { | 
|  | // 111 + 1 + 222 + 42 = 376 | 
|  | return foo4(111) + foo4(99) + foo4(222) + foo4(601); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: define void @foo5() | 
|  | // CHECK-NOT: switch | 
|  | // CHECK: } | 
|  | void foo5(){ | 
|  | switch(0){ | 
|  | default: | 
|  | if (0) { | 
|  |  | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: define void @foo6() | 
|  | // CHECK-NOT: switch | 
|  | // CHECK: } | 
|  | void foo6(){ | 
|  | switch(0){ | 
|  | } | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: define void @foo7() | 
|  | // CHECK-NOT: switch | 
|  | // CHECK: } | 
|  | void foo7(){ | 
|  | switch(0){ | 
|  | foo7(); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | // CHECK-LABEL: define i32 @f8( | 
|  | // CHECK: ret i32 3 | 
|  | // CHECK: } | 
|  | int f8(unsigned x) { | 
|  | switch(x) { | 
|  | default: | 
|  | return 3; | 
|  | case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned. | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Ensure that default after a case range is not ignored. | 
|  | // | 
|  | // CHECK-LABEL: define i32 @f9() | 
|  | // CHECK: ret i32 10 | 
|  | // CHECK: } | 
|  | static int f9_0(unsigned x) { | 
|  | switch(x) { | 
|  | case 10 ... 0xFFFFFFFF: | 
|  | return 0; | 
|  | default: | 
|  | return 10; | 
|  | } | 
|  | } | 
|  | int f9() { | 
|  | return f9_0(2); | 
|  | } | 
|  |  | 
|  | // Ensure that this doesn't compile to infinite loop in g() due to | 
|  | // miscompilation of fallthrough from default to a (tested) case | 
|  | // range. | 
|  | // | 
|  | // CHECK-LABEL: define i32 @f10() | 
|  | // CHECK: ret i32 10 | 
|  | // CHECK: } | 
|  | static int f10_0(unsigned x) { | 
|  | switch(x) { | 
|  | default: | 
|  | x += 1; | 
|  | case 10 ... 0xFFFFFFFF: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | int f10() { | 
|  | f10_0(1); | 
|  | return 10; | 
|  | } | 
|  |  | 
|  | // This generated incorrect code because of poor switch chaining. | 
|  | // | 
|  | // CHECK-LABEL: define i32 @f11( | 
|  | // CHECK: ret i32 3 | 
|  | // CHECK: } | 
|  | int f11(int x) { | 
|  | switch(x) { | 
|  | default: | 
|  | return 3; | 
|  | case 10 ... 0xFFFFFFFF: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | // This just asserted because of the way case ranges were calculated. | 
|  | // | 
|  | // CHECK-LABEL: define i32 @f12( | 
|  | // CHECK: ret i32 3 | 
|  | // CHECK: } | 
|  | int f12(int x) { | 
|  | switch (x) { | 
|  | default: | 
|  | return 3; | 
|  | case 10 ... -1: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Make sure return is not constant (if empty range is skipped or miscompiled) | 
|  | // | 
|  | // CHECK-LABEL: define i32 @f13( | 
|  | // CHECK: ret i32 % | 
|  | // CHECK: } | 
|  | int f13(unsigned x) { | 
|  | switch(x) { | 
|  | case 2: | 
|  | // fallthrough empty range | 
|  | case 10 ... 9: | 
|  | return 10; | 
|  | default: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Don't delete a basic block that we want to introduce later references to. | 
|  | // This isn't really specific to switches, but it's easy to show with them. | 
|  | // rdar://problem/8837067 | 
|  | int f14(int x) { | 
|  | switch (x) { | 
|  |  | 
|  | // case range so that the case block has no predecessors | 
|  | case 0 ... 15: | 
|  | // any expression which doesn't introduce a new block | 
|  | (void) 0; | 
|  | // kaboom | 
|  |  | 
|  | default: | 
|  | return x; | 
|  | } | 
|  | } |