invoke-combine-clauses.ll 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. ; RUN: opt %s -inline -S | FileCheck %s
  2. declare void @external_func()
  3. declare void @abort()
  4. @exception_inner = external global i8
  5. @exception_outer = external global i8
  6. @condition = external global i1
  7. ; Check for a bug in which multiple "resume" instructions in the
  8. ; inlined function caused "catch i8* @exception_outer" to appear
  9. ; multiple times in the resulting landingpad.
  10. define internal void @inner_multiple_resume() personality i8* null {
  11. invoke void @external_func()
  12. to label %cont unwind label %lpad
  13. cont:
  14. ret void
  15. lpad:
  16. %lp = landingpad i32
  17. catch i8* @exception_inner
  18. %cond = load i1, i1* @condition
  19. br i1 %cond, label %resume1, label %resume2
  20. resume1:
  21. resume i32 1
  22. resume2:
  23. resume i32 2
  24. }
  25. define void @outer_multiple_resume() personality i8* null {
  26. invoke void @inner_multiple_resume()
  27. to label %cont unwind label %lpad
  28. cont:
  29. ret void
  30. lpad:
  31. %lp = landingpad i32
  32. catch i8* @exception_outer
  33. resume i32 %lp
  34. }
  35. ; CHECK: define void @outer_multiple_resume()
  36. ; CHECK: %lp.i = landingpad
  37. ; CHECK-NEXT: catch i8* @exception_inner
  38. ; CHECK-NEXT: catch i8* @exception_outer
  39. ; Check that there isn't another "catch" clause:
  40. ; CHECK-NEXT: load
  41. ; Check for a bug in which having a "resume" and a "call" in the
  42. ; inlined function caused "catch i8* @exception_outer" to appear
  43. ; multiple times in the resulting landingpad.
  44. define internal void @inner_resume_and_call() personality i8* null {
  45. call void @external_func()
  46. invoke void @external_func()
  47. to label %cont unwind label %lpad
  48. cont:
  49. ret void
  50. lpad:
  51. %lp = landingpad i32
  52. catch i8* @exception_inner
  53. resume i32 %lp
  54. }
  55. define void @outer_resume_and_call() personality i8* null {
  56. invoke void @inner_resume_and_call()
  57. to label %cont unwind label %lpad
  58. cont:
  59. ret void
  60. lpad:
  61. %lp = landingpad i32
  62. catch i8* @exception_outer
  63. resume i32 %lp
  64. }
  65. ; CHECK: define void @outer_resume_and_call()
  66. ; CHECK: %lp.i = landingpad
  67. ; CHECK-NEXT: catch i8* @exception_inner
  68. ; CHECK-NEXT: catch i8* @exception_outer
  69. ; Check that there isn't another "catch" clause:
  70. ; CHECK-NEXT: br
  71. ; Check what happens if the inlined function contains an "invoke" but
  72. ; no "resume". In this case, the inlined landingpad does not need to
  73. ; include the "catch i8* @exception_outer" clause from the outer
  74. ; function (since the outer function's landingpad will not be
  75. ; reachable), but it's OK to include this clause.
  76. define internal void @inner_no_resume_or_call() personality i8* null {
  77. invoke void @external_func()
  78. to label %cont unwind label %lpad
  79. cont:
  80. ret void
  81. lpad:
  82. %lp = landingpad i32
  83. catch i8* @exception_inner
  84. ; A landingpad might have no "resume" if a C++ destructor aborts.
  85. call void @abort() noreturn nounwind
  86. unreachable
  87. }
  88. define void @outer_no_resume_or_call() personality i8* null {
  89. invoke void @inner_no_resume_or_call()
  90. to label %cont unwind label %lpad
  91. cont:
  92. ret void
  93. lpad:
  94. %lp = landingpad i32
  95. catch i8* @exception_outer
  96. resume i32 %lp
  97. }
  98. ; CHECK: define void @outer_no_resume_or_call()
  99. ; CHECK: %lp.i = landingpad
  100. ; CHECK-NEXT: catch i8* @exception_inner
  101. ; CHECK-NEXT: catch i8* @exception_outer
  102. ; Check that there isn't another "catch" clause:
  103. ; CHECK-NEXT: call void @abort()