summaryrefslogtreecommitdiff
path: root/test/Transforms
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2011-09-30 13:12:16 +0000
committerDuncan Sands <baldrick@free.fr>2011-09-30 13:12:16 +0000
commit0ad7b6e773b33f4c4fd3c82c8a5c10ac0597792c (patch)
tree9a2c787e5ebfc3eee5d54407b4a6722a80e51982 /test/Transforms
parentf16e2d4b2af0e5659a7523a3041175ce2a2f2338 (diff)
downloadllvm-0ad7b6e773b33f4c4fd3c82c8a5c10ac0597792c.tar.gz
llvm-0ad7b6e773b33f4c4fd3c82c8a5c10ac0597792c.tar.bz2
llvm-0ad7b6e773b33f4c4fd3c82c8a5c10ac0597792c.tar.xz
Inlining often produces landingpad instructions with repeated
catch or repeated filter clauses. Teach instcombine a bunch of tricks for simplifying landingpad clauses. Currently the code only recognizes the GNU C++ and Ada personality functions, but that doesn't stop it doing a bunch of "generic" transforms which are hopefully fine for any real-world personality function. If these "generic" transforms turn out not to be generic, they can always be conditioned on the personality function. Probably someone should add the ObjC++ personality function. I didn't as I don't know anything about it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140852 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/InstCombine/LandingPadClauses.ll157
1 files changed, 157 insertions, 0 deletions
diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll
new file mode 100644
index 0000000000..e96bf4c7f4
--- /dev/null
+++ b/test/Transforms/InstCombine/LandingPadClauses.ll
@@ -0,0 +1,157 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+@T1 = external constant i32
+@T2 = external constant i32
+@T3 = external constant i32
+
+declare i32 @generic_personality(i32, i64, i8*, i8*)
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+
+declare void @bar()
+
+define void @foo_generic() {
+; CHECK: @foo_generic
+ invoke void @bar()
+ to label %cont.a unwind label %lpad.a
+cont.a:
+ invoke void @bar()
+ to label %cont.b unwind label %lpad.b
+cont.b:
+ invoke void @bar()
+ to label %cont.c unwind label %lpad.c
+cont.c:
+ invoke void @bar()
+ to label %cont.d unwind label %lpad.d
+cont.d:
+ invoke void @bar()
+ to label %cont.e unwind label %lpad.e
+cont.e:
+ invoke void @bar()
+ to label %cont.f unwind label %lpad.f
+cont.f:
+ invoke void @bar()
+ to label %cont.g unwind label %lpad.g
+cont.g:
+ invoke void @bar()
+ to label %cont.h unwind label %lpad.h
+cont.h:
+ ret void
+
+lpad.a:
+ %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ catch i32* @T1
+ catch i32* @T2
+ catch i32* @T1
+ catch i32* @T2
+ unreachable
+; CHECK: %a = landingpad
+; CHECK-NEXT: @T1
+; CHECK-NEXT: @T2
+; CHECK-NEXT: unreachable
+
+lpad.b:
+ %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [0 x i32*] zeroinitializer
+ catch i32* @T1
+ unreachable
+; CHECK: %b = landingpad
+; CHECK-NEXT: filter
+; CHECK-NEXT: unreachable
+
+lpad.c:
+ %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ catch i32* @T1
+ filter [1 x i32*] [i32* @T1]
+ catch i32* @T2
+ unreachable
+; CHECK: %c = landingpad
+; CHECK-NEXT: @T1
+; CHECK-NEXT: filter [0 x i32*]
+; CHECK-NEXT: unreachable
+
+lpad.d:
+ %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [3 x i32*] zeroinitializer
+ unreachable
+; CHECK: %d = landingpad
+; CHECK-NEXT: filter [1 x i32*] zeroinitializer
+; CHECK-NEXT: unreachable
+
+lpad.e:
+ %e = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ catch i32* @T1
+ filter [3 x i32*] [i32* @T1, i32* @T2, i32* @T2]
+ unreachable
+; CHECK: %e = landingpad
+; CHECK-NEXT: @T1
+; CHECK-NEXT: filter [1 x i32*] [i32* @T2]
+; CHECK-NEXT: unreachable
+
+lpad.f:
+ %f = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [2 x i32*] [i32* @T2, i32* @T1]
+ filter [1 x i32*] [i32* @T1]
+ unreachable
+; CHECK: %f = landingpad
+; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
+; CHECK-NEXT: unreachable
+
+lpad.g:
+ %g = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [1 x i32*] [i32* @T1]
+ catch i32* @T3
+ filter [2 x i32*] [i32* @T2, i32* @T1]
+ unreachable
+; CHECK: %g = landingpad
+; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
+; CHECK-NEXT: catch i32* @T3
+; CHECK-NEXT: unreachable
+
+lpad.h:
+ %h = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [2 x i32*] [i32* @T1, i32* null]
+ filter [1 x i32*] zeroinitializer
+ unreachable
+; CHECK: %h = landingpad
+; CHECK-NEXT: filter [1 x i32*] zeroinitializer
+; CHECK-NEXT: unreachable
+}
+
+define void @foo_cxx() {
+; CHECK: @foo_cxx
+ invoke void @bar()
+ to label %cont.a unwind label %lpad.a
+cont.a:
+ invoke void @bar()
+ to label %cont.b unwind label %lpad.b
+cont.b:
+ invoke void @bar()
+ to label %cont.c unwind label %lpad.c
+cont.c:
+ ret void
+
+lpad.a:
+ %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ catch i32* null
+ catch i32* @T1
+ unreachable
+; CHECK: %a = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+
+lpad.b:
+ %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ filter [1 x i32*] zeroinitializer
+ unreachable
+; CHECK: %b = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+
+lpad.c:
+ %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ filter [2 x i32*] [i32* @T1, i32* null]
+ unreachable
+; CHECK: %c = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+}