Mercurial > hg > CbC > CbC_llvm
diff clang/test/CodeGen/switch.c @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 2e18cbf3894f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clang/test/CodeGen/switch.c Thu Feb 13 15:10:13 2020 +0900 @@ -0,0 +1,213 @@ +// 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; + } +}