This reverts commit d618f1c3b12effd0c2bdb7d02108d3551f389d3d. This commit wasn't reviewed ahead of time and significant concerns were raised immediately after it landed. According to our developer policy this warrants immediate revert of the commit. https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy Differential Revision: https://reviews.llvm.org/D155509
235 lines
3.5 KiB
C
235 lines
3.5 KiB
C
// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
|
|
|
|
// PR9322 and rdar://6970405
|
|
|
|
// CHECK: @test1
|
|
// CHECK-NOT: switch
|
|
// CHECK-NOT: @dead
|
|
// CHECK: add nsw i32 {{.*}}, 1
|
|
// CHECK-NOT: switch
|
|
// CHECK-NOT: @dead
|
|
// CHECK: ret void
|
|
int i;
|
|
void dead(void);
|
|
|
|
void test1(void) {
|
|
switch (1)
|
|
case 1:
|
|
++i;
|
|
|
|
switch (0)
|
|
case 1:
|
|
dead();
|
|
}
|
|
|
|
|
|
// CHECK: @test2
|
|
// CHECK-NOT: switch
|
|
// CHECK-NOT: @dead
|
|
// CHECK: add nsw i32 {{.*}}, 2
|
|
// CHECK-NOT: switch
|
|
// CHECK-NOT: @dead
|
|
// CHECK: ret void
|
|
void test2(void) {
|
|
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(void) {
|
|
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(void) {
|
|
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(void) {
|
|
switch (1) {
|
|
int x; // eliding var decl?
|
|
case 1:
|
|
x = 4;
|
|
i = x;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// CHECK: @test6
|
|
// CHECK-NOT: switch
|
|
// CHECK-NOT: @dead
|
|
// CHECK: ret void
|
|
void test6(void) {
|
|
// 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(void) {
|
|
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(void) {
|
|
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;
|
|
}
|
|
}
|
|
|
|
// CHECK: @test10
|
|
// CHECK-NOT: switch
|
|
// CHECK: ret i32
|
|
int test10(void) {
|
|
switch(8) {
|
|
case 8:
|
|
break;
|
|
case 4:
|
|
break;
|
|
default:
|
|
dead();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// CHECK: @test11
|
|
// CHECK-NOT: switch
|
|
// CHECK: ret void
|
|
void test11(void) {
|
|
switch (1) {
|
|
case 1:
|
|
break;
|
|
case 42: ;
|
|
int x; // eliding var decl?
|
|
x = 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// CHECK: @test12
|
|
// CHECK-NOT: switch
|
|
// CHECK: ret void
|
|
void test12(void) {
|
|
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;
|
|
}
|
|
}
|
|
|
|
// Verify that case 42 only calls test14 once.
|
|
// CHECK: @test13
|
|
// CHECK: call void @test13(i32 noundef 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 noundef 42)
|
|
// CHECK-NEXT: br label [[EPILOG]]
|
|
void test13(int x) {
|
|
switch (x) {
|
|
case 42: test13(97); // fallthrough
|
|
case 11: break;
|
|
default: test13(42); break;
|
|
}
|
|
}
|
|
|