diff options
author | John McCall <rjmccall@apple.com> | 2010-07-23 21:56:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-23 21:56:41 +0000 |
commit | ad5d61e227c9879227c5bf9a6c82bbb5fdd5a7b0 (patch) | |
tree | 29d8194fe3b19f712530cae4fe382ddcb6aba541 /clang/test | |
parent | 946274471da40720baae5e510d2df90854973c01 (diff) | |
download | bcm5719-llvm-ad5d61e227c9879227c5bf9a6c82bbb5fdd5a7b0.tar.gz bcm5719-llvm-ad5d61e227c9879227c5bf9a6c82bbb5fdd5a7b0.zip |
Revise cleanup IR generation to fix a major bug with cleanups (PR7686)
as well as some significant asymptotic inefficiencies with threading
multiple jumps through deep cleanups.
llvm-svn: 109274
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGenCXX/condition.cpp | 16 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/eh.cpp | 71 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/gnu-exceptions.m | 8 |
3 files changed, 85 insertions, 10 deletions
diff --git a/clang/test/CodeGenCXX/condition.cpp b/clang/test/CodeGenCXX/condition.cpp index 652e7c89c15..cc2eaf5bd6a 100644 --- a/clang/test/CodeGenCXX/condition.cpp +++ b/clang/test/CodeGenCXX/condition.cpp @@ -105,12 +105,12 @@ void while_destruct(int z) { // CHECK-NEXT: br i1 [[COND]] // Loop-exit staging block. - // CHECK: store i32 1, i32* [[CLEANUPDEST]] + // CHECK: store i32 3, i32* [[CLEANUPDEST]] // CHECK-NEXT: br // While body. // CHECK: store i32 21, i32* [[Z]] - // CHECK: store i32 2, i32* [[CLEANUPDEST]] + // CHECK: store i32 0, i32* [[CLEANUPDEST]] // CHECK-NEXT: br z = 21; @@ -138,7 +138,7 @@ void while_destruct(int z) { // CHECK: define void @_Z12for_destructi( void for_destruct(int z) { // CHECK: [[Z:%.*]] = alloca i32 - // CHECK: [[XDEST:%.*]] = alloca i32 + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 // CHECK: [[I:%.*]] = alloca i32 // CHECK: call void @_ZN1YC1Ev // CHECK-NEXT: br @@ -152,7 +152,7 @@ void for_destruct(int z) { // -> %for.body, %for.cond.cleanup // %for.cond.cleanup: Exit cleanup staging. - // CHECK: store i32 1, i32* [[XDEST]] + // CHECK: store i32 2, i32* [[CLEANUPDEST]] // CHECK-NEXT: br // -> %cleanup @@ -166,21 +166,21 @@ void for_destruct(int z) { // CHECK: [[TMP:%.*]] = load i32* [[Z]] // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 // CHECK-NEXT: store i32 [[INC]], i32* [[Z]] - // CHECK-NEXT: store i32 2, i32* [[XDEST]] + // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]] // CHECK-NEXT: br // -> %cleanup // %cleanup: Destroys X. // CHECK: call void @_ZN1XD1Ev - // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[XDEST]] + // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]] // CHECK-NEXT: switch i32 [[YDESTTMP]] - // 1 -> %cleanup4, 2 -> %cleanup.cont + // 0 -> %cleanup.cont, default -> %cleanup1 // %cleanup.cont: (eliminable) // CHECK: br // -> %for.cond - // %cleanup4: Destroys Y. + // %cleanup1: Destroys Y. // CHECK: call void @_ZN1YD1Ev( // CHECK-NEXT: br // -> %for.end diff --git a/clang/test/CodeGenCXX/eh.cpp b/clang/test/CodeGenCXX/eh.cpp index 1cf3d123896..e22063a4c12 100644 --- a/clang/test/CodeGenCXX/eh.cpp +++ b/clang/test/CodeGenCXX/eh.cpp @@ -39,6 +39,7 @@ void test2() { // CHECK: [[FREEVAR:%.*]] = alloca i1 // CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8* // CHECK-NEXT: [[EXNSLOTVAR:%.*]] = alloca i8* +// CHECK-NEXT: [[CLEANUPDESTVAR:%.*]] = alloca i32 // CHECK-NEXT: store i1 false, i1* [[FREEVAR]] // CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16) // CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]] @@ -124,6 +125,7 @@ namespace test7 { // CHECK-NEXT: [[EXNALLOCVAR:%.*]] = alloca i8* // CHECK-NEXT: [[CAUGHTEXNVAR:%.*]] = alloca i8* // CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32 +// CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32 // CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]] try { try { @@ -153,6 +155,7 @@ namespace test7 { // CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] // CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) +// CHECK-NEXT: store i32 1, i32* [[EHCLEANUPDESTVAR]] // CHECK-NEXT: call void @__cxa_end_catch() // CHECK-NEXT: br label // CHECK: load i8** [[CAUGHTEXNVAR]] @@ -290,3 +293,71 @@ namespace test11 { } } } + +// PR7686 +namespace test12 { + struct A { ~A(); }; + bool opaque(const A&); + + // CHECK: define void @_ZN6test124testEv() + void test() { + // CHECK: [[X:%.*]] = alloca [[A:%.*]], + // CHECK: [[EHCLEANUPDEST:%.*]] = alloca i32 + // CHECK: [[Y:%.*]] = alloca [[A]] + // CHECK: [[Z:%.*]] = alloca [[A]] + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 + + A x; + // CHECK: invoke zeroext i1 @_ZN6test126opaqueERKNS_1AE( + if (opaque(x)) { + A y; + A z; + + // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Z]]) + // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Y]]) + + // It'd be great if something eliminated this switch. + // CHECK: load i32* [[CLEANUPDEST]] + // CHECK-NEXT: switch i32 + goto success; + } + + success: + bool _ = true; + + // CHECK: call void @_ZN6test121AD1Ev([[A]]* [[X]]) + // CHECK-NEXT: ret void + } +} + +// Reduced from some TableGen code that was causing a self-host crash. +namespace test13 { + struct A { ~A(); }; + + void test0(int x) { + try { + switch (x) { + case 0: + break; + case 1:{ + A a; + break; + } + default: + return; + } + return; + } catch (int x) { + } + return; + } + + void test1(int x) { + A y; + try { + switch (x) { + default: break; + } + } catch (int x) {} + } +} diff --git a/clang/test/CodeGenObjC/gnu-exceptions.m b/clang/test/CodeGenObjC/gnu-exceptions.m index 190a2b8d4e4..6790a299375 100644 --- a/clang/test/CodeGenObjC/gnu-exceptions.m +++ b/clang/test/CodeGenObjC/gnu-exceptions.m @@ -10,16 +10,20 @@ void test0() { @try { // CHECK: invoke void @opaque() opaque(); + + // CHECK: call void @log(i32 1) + } @catch (C *c) { // CHECK: call i8* @llvm.eh.exception() // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gnu_objc_personality_v0 // CHECK: br i1 - // CHECK: call void @objc_exception_throw // CHECK: call void @log(i32 0) + + // CHECK: call void @objc_exception_throw + log(0); } - // CHECK: call void @log(i32 1) log(1); } |