First tiny step to implementing PR9322: build infrastructure for only emitting the
live case of a switch statement when switching on a constant. This is terribly
limited, but enough to handle the trivial example included. Before we would
emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
switch i32 1, label %sw.epilog [
i32 1, label %sw.bb
]
sw.bb: ; preds = %entry
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.bb, %entry
switch i32 0, label %sw.epilog3 [
i32 1, label %sw.bb1
]
sw.bb1: ; preds = %sw.epilog
%tmp2 = load i32* %i.addr, align 4
%add = add nsw i32 %tmp2, 2
store i32 %add, i32* %i.addr, align 4
br label %sw.epilog3
sw.epilog3: ; preds = %sw.bb1, %sw.epilog
ret void
}
now we emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
ret void
}
This improves -O0 compile time (less IR to generate and shove through the code
generator) and the clever linux kernel people found a way to fail to build if we
don't do this optimization. This step isn't enough to handle the kernel case
though.
llvm-svn: 126597
2011-02-28 08:22:07 +08:00
|
|
|
// RUN: %clang_cc1 -triple i386-unknown-unknown -O0 %s -emit-llvm -o - | FileCheck %s
|
|
|
|
|
2011-02-28 09:02:29 +08:00
|
|
|
// PR9322 and rdar://6970405
|
|
|
|
|
First tiny step to implementing PR9322: build infrastructure for only emitting the
live case of a switch statement when switching on a constant. This is terribly
limited, but enough to handle the trivial example included. Before we would
emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
switch i32 1, label %sw.epilog [
i32 1, label %sw.bb
]
sw.bb: ; preds = %entry
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.bb, %entry
switch i32 0, label %sw.epilog3 [
i32 1, label %sw.bb1
]
sw.bb1: ; preds = %sw.epilog
%tmp2 = load i32* %i.addr, align 4
%add = add nsw i32 %tmp2, 2
store i32 %add, i32* %i.addr, align 4
br label %sw.epilog3
sw.epilog3: ; preds = %sw.bb1, %sw.epilog
ret void
}
now we emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
ret void
}
This improves -O0 compile time (less IR to generate and shove through the code
generator) and the clever linux kernel people found a way to fail to build if we
don't do this optimization. This step isn't enough to handle the kernel case
though.
llvm-svn: 126597
2011-02-28 08:22:07 +08:00
|
|
|
// CHECK: @test1
|
|
|
|
// CHECK-NOT: switch
|
2011-02-28 09:02:29 +08:00
|
|
|
// CHECK-NOT: @dead
|
First tiny step to implementing PR9322: build infrastructure for only emitting the
live case of a switch statement when switching on a constant. This is terribly
limited, but enough to handle the trivial example included. Before we would
emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
switch i32 1, label %sw.epilog [
i32 1, label %sw.bb
]
sw.bb: ; preds = %entry
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.bb, %entry
switch i32 0, label %sw.epilog3 [
i32 1, label %sw.bb1
]
sw.bb1: ; preds = %sw.epilog
%tmp2 = load i32* %i.addr, align 4
%add = add nsw i32 %tmp2, 2
store i32 %add, i32* %i.addr, align 4
br label %sw.epilog3
sw.epilog3: ; preds = %sw.bb1, %sw.epilog
ret void
}
now we emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
ret void
}
This improves -O0 compile time (less IR to generate and shove through the code
generator) and the clever linux kernel people found a way to fail to build if we
don't do this optimization. This step isn't enough to handle the kernel case
though.
llvm-svn: 126597
2011-02-28 08:22:07 +08:00
|
|
|
// CHECK: add nsw i32 {{.*}}, 1
|
|
|
|
// CHECK-NOT: switch
|
2011-02-28 09:02:29 +08:00
|
|
|
// CHECK-NOT: @dead
|
First tiny step to implementing PR9322: build infrastructure for only emitting the
live case of a switch statement when switching on a constant. This is terribly
limited, but enough to handle the trivial example included. Before we would
emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
switch i32 1, label %sw.epilog [
i32 1, label %sw.bb
]
sw.bb: ; preds = %entry
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.bb, %entry
switch i32 0, label %sw.epilog3 [
i32 1, label %sw.bb1
]
sw.bb1: ; preds = %sw.epilog
%tmp2 = load i32* %i.addr, align 4
%add = add nsw i32 %tmp2, 2
store i32 %add, i32* %i.addr, align 4
br label %sw.epilog3
sw.epilog3: ; preds = %sw.bb1, %sw.epilog
ret void
}
now we emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
ret void
}
This improves -O0 compile time (less IR to generate and shove through the code
generator) and the clever linux kernel people found a way to fail to build if we
don't do this optimization. This step isn't enough to handle the kernel case
though.
llvm-svn: 126597
2011-02-28 08:22:07 +08:00
|
|
|
// CHECK: ret void
|
2011-02-28 09:02:29 +08:00
|
|
|
int i;
|
|
|
|
void dead();
|
|
|
|
|
First tiny step to implementing PR9322: build infrastructure for only emitting the
live case of a switch statement when switching on a constant. This is terribly
limited, but enough to handle the trivial example included. Before we would
emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
switch i32 1, label %sw.epilog [
i32 1, label %sw.bb
]
sw.bb: ; preds = %entry
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.bb, %entry
switch i32 0, label %sw.epilog3 [
i32 1, label %sw.bb1
]
sw.bb1: ; preds = %sw.epilog
%tmp2 = load i32* %i.addr, align 4
%add = add nsw i32 %tmp2, 2
store i32 %add, i32* %i.addr, align 4
br label %sw.epilog3
sw.epilog3: ; preds = %sw.bb1, %sw.epilog
ret void
}
now we emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
ret void
}
This improves -O0 compile time (less IR to generate and shove through the code
generator) and the clever linux kernel people found a way to fail to build if we
don't do this optimization. This step isn't enough to handle the kernel case
though.
llvm-svn: 126597
2011-02-28 08:22:07 +08:00
|
|
|
void test1() {
|
|
|
|
switch (1)
|
|
|
|
case 1:
|
|
|
|
++i;
|
|
|
|
|
|
|
|
switch (0)
|
|
|
|
case 1:
|
2011-02-28 09:02:29 +08:00
|
|
|
dead();
|
First tiny step to implementing PR9322: build infrastructure for only emitting the
live case of a switch statement when switching on a constant. This is terribly
limited, but enough to handle the trivial example included. Before we would
emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
switch i32 1, label %sw.epilog [
i32 1, label %sw.bb
]
sw.bb: ; preds = %entry
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
br label %sw.epilog
sw.epilog: ; preds = %sw.bb, %entry
switch i32 0, label %sw.epilog3 [
i32 1, label %sw.bb1
]
sw.bb1: ; preds = %sw.epilog
%tmp2 = load i32* %i.addr, align 4
%add = add nsw i32 %tmp2, 2
store i32 %add, i32* %i.addr, align 4
br label %sw.epilog3
sw.epilog3: ; preds = %sw.bb1, %sw.epilog
ret void
}
now we emit:
define void @test1(i32 %i) nounwind {
entry:
%i.addr = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4
%tmp = load i32* %i.addr, align 4
%inc = add nsw i32 %tmp, 1
store i32 %inc, i32* %i.addr, align 4
ret void
}
This improves -O0 compile time (less IR to generate and shove through the code
generator) and the clever linux kernel people found a way to fail to build if we
don't do this optimization. This step isn't enough to handle the kernel case
though.
llvm-svn: 126597
2011-02-28 08:22:07 +08:00
|
|
|
}
|
2011-02-28 09:02:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
// CHECK: @test2
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: add nsw i32 {{.*}}, 2
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test2() {
|
|
|
|
switch (4) {
|
|
|
|
case 1:
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
i += 2;
|
|
|
|
// Fall off the end of the switch.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CHECK: @test3
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: add nsw i32 {{.*}}, 2
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test3() {
|
|
|
|
switch (4) {
|
|
|
|
case 1:
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
case 4: {
|
|
|
|
i += 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: @test4
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: add nsw i32 {{.*}}, 2
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test4() {
|
|
|
|
switch (4) {
|
|
|
|
case 1:
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
default: {
|
|
|
|
i += 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This shouldn't crash codegen, but we don't have to optimize out the switch
|
|
|
|
// in this case.
|
|
|
|
void test5() {
|
|
|
|
switch (1) {
|
|
|
|
int x; // eliding var decl?
|
|
|
|
case 1:
|
|
|
|
x = 4;
|
2011-02-28 15:22:44 +08:00
|
|
|
i = x;
|
2011-02-28 09:02:29 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: @test6
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test6() {
|
|
|
|
// Neither case is reachable.
|
|
|
|
switch (40) {
|
|
|
|
case 1:
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
case 4: {
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: @test7
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: add nsw i32
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test7() {
|
|
|
|
switch (4) {
|
|
|
|
case 1:
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
{
|
|
|
|
case 4: // crazy brace scenario
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: @test8
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: add nsw i32
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test8() {
|
|
|
|
switch (4) {
|
|
|
|
case 1:
|
|
|
|
dead();
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
++i;
|
|
|
|
// Fall off the end of the switch.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: @test9
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: add nsw i32
|
|
|
|
// CHECK: add nsw i32
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK-NOT: @dead
|
|
|
|
// CHECK: ret void
|
|
|
|
void test9(int i) {
|
|
|
|
switch (1) {
|
|
|
|
case 5:
|
|
|
|
dead();
|
|
|
|
case 1:
|
|
|
|
++i;
|
|
|
|
// Fall through is fine.
|
|
|
|
case 4:
|
|
|
|
++i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-28 15:16:14 +08:00
|
|
|
// CHECK: @test10
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK: ret i32
|
2011-02-28 09:06:02 +08:00
|
|
|
int test10(void) {
|
|
|
|
switch(8) {
|
|
|
|
case 8:
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dead();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2011-02-28 15:16:14 +08:00
|
|
|
|
|
|
|
// CHECK: @test11
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK: ret void
|
|
|
|
void test11() {
|
|
|
|
switch (1) {
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 42: ;
|
|
|
|
int x; // eliding var decl?
|
|
|
|
x = 4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-02-28 15:22:44 +08:00
|
|
|
|
|
|
|
// CHECK: @test12
|
|
|
|
// CHECK-NOT: switch
|
|
|
|
// CHECK: ret void
|
|
|
|
void test12() {
|
|
|
|
switch (1) {
|
|
|
|
case 2: {
|
|
|
|
int a; // Ok to skip this vardecl.
|
|
|
|
a = 42;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 42: ;
|
|
|
|
int x; // eliding var decl?
|
|
|
|
x = 4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-11 02:20:19 +08:00
|
|
|
// Verify that case 42 only calls test14 once.
|
2011-04-17 08:54:30 +08:00
|
|
|
// CHECK: @test13
|
2012-04-11 02:20:19 +08:00
|
|
|
// CHECK: call void @test13(i32 97)
|
|
|
|
// CHECK-NEXT: br label %[[EPILOG2:[0-9.a-z]+]]
|
|
|
|
// CHECK: [[EPILOG2]]
|
|
|
|
// CHECK-NEXT: br label [[EPILOG:%[0-9.a-z]+]]
|
|
|
|
// CHECK: call void @test13(i32 42)
|
|
|
|
// CHECK-NEXT: br label [[EPILOG]]
|
2011-04-17 08:54:30 +08:00
|
|
|
void test13(int x) {
|
|
|
|
switch (x) {
|
2012-04-11 02:20:19 +08:00
|
|
|
case 42: test13(97); // fallthrough
|
2011-04-18 07:21:26 +08:00
|
|
|
case 11: break;
|
2012-04-11 02:20:19 +08:00
|
|
|
default: test13(42); break;
|
2011-04-18 07:21:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|