[llvm] [Verifier] Add LandingPad type checks (PR #87198)

via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 31 11:34:02 PDT 2024


https://github.com/AlexDenisov created https://github.com/llvm/llvm-project/pull/87198

During lowering GlobalISel and SelectionDAG expect LandingPad type to have two elements, specifying wrong type leads to asssertion in debug builds and to a crash in release builds.

Verification attempts to prevent these crashes at an earlier stage thus helping with debugging.

Additional notes:

 - verification here only checks for the number of values in the LP type and not the exact types of the underlying values
 - verification allows more types than expected by GlobalISel: GlobalISel only allows StructType, but the CodeGen setup is not known at verification time. Proper behaviour would require fixing GlobalISel to follow the same logic as SelectionDAG
 - tests are updated to use a proper LP type, the updates include compatibility tests, which had the same type-related logic at least as of ~8 years ago[0]

[0] https://github.com/llvm/llvm-project/commit/a029531e1075997bb1a6480d0b942350b7b875fc

>From 548770efca366d81e32f28a2bfd13d71a3670f47 Mon Sep 17 00:00:00 2001
From: AlexDenisov <alex at lowlevelbits.org>
Date: Sun, 31 Mar 2024 20:18:05 +0200
Subject: [PATCH] [Verifier] Add LandingPad type checks

During lowering GlobalISel and SelectionDAG expect LandingPad type to
have two elements, specifying wrong type leads to asssertion in debug
builds and to a crash in release builds.

Verification attempts to prevent these crashes at an earlier stage thus
helping with debugging.

Additional notes:

 - verification here only checks for the number of values in the LP type
   and not the exact types of the underlying values
 - verification allows more types than expected by GlobalISel:
   GlobalISel only allows StructType, but the CodeGen setup is not known
   at verification time. Proper behaviour would require fixing
   GlobalISel to follow the same logic as SelectionDAG
 - tests are updated to use a proper LP type, the updates include
   compatibility tests, which had the same type-related logic at least
   as of ~8 years ago[0]

[0] https://github.com/llvm/llvm-project/commit/a029531e1075997bb1a6480d0b942350b7b875fc
---
 llvm/lib/IR/Verifier.cpp                      | 30 ++++++++++++
 .../CallGraph/do-nothing-intrinsic.ll         |  2 +-
 llvm/test/Assembler/opaque-ptr.ll             |  2 +-
 llvm/test/Bitcode/compatibility.ll            | 46 +++++++++----------
 llvm/test/Bitcode/operand-bundles.ll          | 14 +++---
 llvm/test/Bitcode/use-list-order2.ll          |  4 +-
 .../test/Feature/OperandBundles/merge-func.ll |  4 +-
 llvm/test/Linker/drop-attribute.ll            |  2 +-
 llvm/test/Transforms/HotColdSplit/eh-pads.ll  |  6 +--
 llvm/test/Transforms/HotColdSplit/unwind.ll   |  4 +-
 .../Transforms/IROutliner/illegal-invoke.ll   |  8 ++--
 .../IROutliner/illegal-landingpad.ll          |  8 ++--
 .../IndVarSimplify/AArch64/widen-loop-comp.ll |  4 +-
 llvm/test/Transforms/Inline/deopt-bundles.ll  |  6 +--
 .../Transforms/Inline/deoptimize-intrinsic.ll |  2 +-
 .../test/Transforms/Inline/guard-intrinsic.ll |  2 +-
 .../Transforms/Inline/inline_returns_twice.ll |  8 ++--
 llvm/test/Transforms/Inline/invoke-cleanup.ll |  8 ++--
 .../Inline/invoke-combine-clauses.ll          | 24 +++++-----
 llvm/test/Transforms/InstCombine/freeze.ll    | 16 +++----
 llvm/test/Transforms/InstSimplify/freeze.ll   | 16 ++++---
 .../InstSimplify/known-never-nan.ll           |  8 ++--
 .../LowerInvoke/2003-12-10-Crash.ll           |  2 +-
 llvm/test/Transforms/MemCpyOpt/stack-move.ll  |  8 ++--
 llvm/test/Transforms/SCCP/landingpad.ll       |  4 +-
 .../SimplifyCFG/UnreachableEliminate.ll       |  2 +-
 llvm/test/Transforms/SimplifyCFG/pr39807.ll   |  2 +-
 .../uniform-retval-invoke.ll                  |  2 +-
 llvm/test/Verifier/landingpad-types.ll        | 16 +++++++
 29 files changed, 154 insertions(+), 106 deletions(-)
 create mode 100644 llvm/test/Verifier/landingpad-types.ll

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 33f358440a312d..65c5f85419acd9 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4378,6 +4378,29 @@ void Verifier::visitEHPadPredecessors(Instruction &I) {
   }
 }
 
+// Recursively extract types from the LandingPad type
+// Based on ComputeValueVTs
+static void linearizeLandingPadTypes(Type *Ty,
+                                     SmallVectorImpl<Type *> &LPITypes) {
+  if (StructType *STy = dyn_cast<StructType>(Ty)) {
+    for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
+      linearizeLandingPadTypes(STy->getElementType(I), LPITypes);
+    }
+    return;
+  }
+  // Given an array type, recursively traverse the elements.
+  if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+    Type *EltTy = ATy->getElementType();
+    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
+      linearizeLandingPadTypes(EltTy, LPITypes);
+    return;
+  }
+  // Interpret void as zero return values.
+  if (Ty->isVoidTy())
+    return;
+  LPITypes.push_back(Ty);
+}
+
 void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
   // The landingpad instruction is ill-formed if it doesn't have any clauses and
   // isn't a cleanup.
@@ -4394,6 +4417,13 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
           "inside a function.",
           &LPI);
 
+  if (!LandingPadResultTy->isTokenTy()) {
+    SmallVector<Type *, 4> linearizedLPITypes;
+    linearizeLandingPadTypes(LandingPadResultTy, linearizedLPITypes);
+    Check(linearizedLPITypes.size() == 2,
+          "Only two-valued landingpads are supported.", &LPI);
+  }
+
   Function *F = LPI.getParent()->getParent();
   Check(F->hasPersonalityFn(),
         "LandingPadInst needs to be in a function with a personality.", &LPI);
diff --git a/llvm/test/Analysis/CallGraph/do-nothing-intrinsic.ll b/llvm/test/Analysis/CallGraph/do-nothing-intrinsic.ll
index fc2c541736e7b3..8d8f98a35d62e6 100644
--- a/llvm/test/Analysis/CallGraph/do-nothing-intrinsic.ll
+++ b/llvm/test/Analysis/CallGraph/do-nothing-intrinsic.ll
@@ -5,7 +5,7 @@ define void @main() personality i8 0 {
   invoke void @llvm.donothing()
           to label %ret unwind label %unw
 unw:
-  %tmp = landingpad i8 cleanup
+  %tmp = landingpad { ptr, i8 } cleanup
   br label %ret
 ret:
   ret void
diff --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
index 236a64904bc957..7e1f792d201681 100644
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -157,7 +157,7 @@ continue:
   ret void
 
 cleanup:
-  landingpad {}
+  landingpad { ptr, i8 }
     cleanup
   ret void
 }
diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll
index b374924516d665..f8002fd12a273b 100644
--- a/llvm/test/Bitcode/compatibility.ll
+++ b/llvm/test/Bitcode/compatibility.ll
@@ -726,7 +726,7 @@ define void @f.no_personality() personality i8 3 {
 ; CHECK: define void @f.no_personality() personality i8 3
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -738,7 +738,7 @@ define void @f.personality() personality ptr @f.personality_handler {
 ; CHECK: define void @f.personality() personality ptr @f.personality_handler
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i32 cleanup
+  %cleanup = landingpad { ptr, i32 } cleanup
   br label %normal
 normal:
   ret void
@@ -1173,12 +1173,12 @@ defaultdest.2:
          to label %defaultdest unwind label %exc
          ; CHECK: to label %defaultdest unwind label %exc
 exc:
-  %cleanup = landingpad i32 cleanup
+  %cleanup = landingpad { ptr, i32 } cleanup
 
-  resume i32 undef
-  ; CHECK: resume i32 undef
-  resume i32 poison
-  ; CHECK: resume i32 poison
+  resume { ptr, i32 } undef
+  ; CHECK: resume { ptr, i32 } undef
+  resume { ptr, i32 } poison
+  ; CHECK: resume { ptr, i32 } poison
   unreachable
   ; CHECK: unreachable
 
@@ -1601,15 +1601,15 @@ define void @instructions.landingpad() personality i32 -2 {
   invoke void @llvm.donothing() to label %proceed unwind label %catch4
 
 catch1:
-  landingpad i32
-  ; CHECK: landingpad i32
+  landingpad { ptr, i32 }
+  ; CHECK: landingpad { ptr, i32 }
              cleanup
              ; CHECK: cleanup
   br label %proceed
 
 catch2:
-  landingpad i32
-  ; CHECK: landingpad i32
+  landingpad { ptr, i32 }
+  ; CHECK: landingpad { ptr, i32 }
              cleanup
              ; CHECK: cleanup
              catch ptr null
@@ -1617,8 +1617,8 @@ catch2:
   br label %proceed
 
 catch3:
-  landingpad i32
-  ; CHECK: landingpad i32
+  landingpad { ptr, i32 }
+  ; CHECK: landingpad { ptr, i32 }
              cleanup
              ; CHECK: cleanup
              catch ptr null
@@ -1628,8 +1628,8 @@ catch3:
   br label %proceed
 
 catch4:
-  landingpad i32
-  ; CHECK: landingpad i32
+  landingpad { ptr, i32 }
+  ; CHECK: landingpad { ptr, i32 }
              filter [2 x i32] zeroinitializer
              ; CHECK: filter [2 x i32] zeroinitializer
   br label %proceed
@@ -1831,7 +1831,7 @@ define void @invoke_with_operand_bundle0(ptr %ptr) personality i8 3 {
 ; CHECK: invoke void @op_bundle_callee_0() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float  0.000000e+00, i64 100, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -1847,7 +1847,7 @@ define void @invoke_with_operand_bundle1(ptr %ptr) personality i8 3 {
 ; CHECK: invoke void @op_bundle_callee_0(){{$}}
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 
 normal:
@@ -1855,7 +1855,7 @@ normal:
 ; CHECK: invoke void @op_bundle_callee_0() [ "foo"() ]
 
 exception1:
-  %cleanup1 = landingpad i8 cleanup
+  %cleanup1 = landingpad { ptr, i8 } cleanup
   br label %normal1
 
 normal1:
@@ -1863,7 +1863,7 @@ normal1:
 ; CHECK: invoke void @op_bundle_callee_0() [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception2:
-  %cleanup2 = landingpad i8 cleanup
+  %cleanup2 = landingpad { ptr, i8 } cleanup
   br label %normal2
 
 normal2:
@@ -1877,7 +1877,7 @@ define void @invoke_with_operand_bundle2(ptr %ptr) personality i8 3 {
 ; CHECK: invoke void @op_bundle_callee_0() [ "foo"() ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -1892,7 +1892,7 @@ define void @invoke_with_operand_bundle3(ptr %ptr) personality i8 3 {
 ; CHECK: invoke void @op_bundle_callee_0() [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -1908,7 +1908,7 @@ define void @invoke_with_operand_bundle4(ptr %ptr) personality i8 3 {
 ; CHECK: invoke void @op_bundle_callee_1(i32 10, i32 %x) [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -1925,7 +1925,7 @@ define void @invoke_with_operand_bundle_vaarg(ptr %ptr) personality i8 3 {
 ; CHECK: invoke void (...) @vaargs_func(i32 10, i32 %x) [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
diff --git a/llvm/test/Bitcode/operand-bundles.ll b/llvm/test/Bitcode/operand-bundles.ll
index ab28cffd84aa29..9f3fcd907910c8 100644
--- a/llvm/test/Bitcode/operand-bundles.ll
+++ b/llvm/test/Bitcode/operand-bundles.ll
@@ -68,7 +68,7 @@ define void @g0(i32* %ptr) personality i8 3 {
 ; CHECK: invoke void @callee0() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float  0.000000e+00, i64 100, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -84,7 +84,7 @@ define void @g1(i32* %ptr) personality i8 3 {
 ; CHECK: invoke void @callee0(){{$}}
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 
 normal:
@@ -92,7 +92,7 @@ normal:
 ; CHECK: invoke void @callee0() [ "foo"() ]
 
 exception1:
-  %cleanup1 = landingpad i8 cleanup
+  %cleanup1 = landingpad { ptr, i8 } cleanup
   br label %normal1
 
 normal1:
@@ -100,7 +100,7 @@ normal1:
 ; CHECK: invoke void @callee0() [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception2:
-  %cleanup2 = landingpad i8 cleanup
+  %cleanup2 = landingpad { ptr, i8 } cleanup
   br label %normal2
 
 normal2:
@@ -114,7 +114,7 @@ define void @g2(i32* %ptr) personality i8 3 {
 ; CHECK: invoke void @callee0() [ "foo"() ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -129,7 +129,7 @@ define void @g3(i32* %ptr) personality i8 3 {
 ; CHECK: invoke void @callee0() [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -145,7 +145,7 @@ define void @g4(i32* %ptr) personality i8 3 {
 ; CHECK: invoke void @callee1(i32 10, i32 %x) [ "foo"(i32 42, i64 100, i32 %x), "foo"(i32 42, float  0.000000e+00, i32 %l) ]
 
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
diff --git a/llvm/test/Bitcode/use-list-order2.ll b/llvm/test/Bitcode/use-list-order2.ll
index aafa3d552bbee6..41bc80619216c1 100644
--- a/llvm/test/Bitcode/use-list-order2.ll
+++ b/llvm/test/Bitcode/use-list-order2.ll
@@ -8,7 +8,7 @@ declare void @llvm.donothing() nounwind readnone
 define void @f.no_personality1() personality i8 0 {
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -21,7 +21,7 @@ normal:
 define void @f.no_personality2() personality i8 -1 {
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
diff --git a/llvm/test/Feature/OperandBundles/merge-func.ll b/llvm/test/Feature/OperandBundles/merge-func.ll
index 772cd774c8e537..16e1564fe63ad1 100644
--- a/llvm/test/Feature/OperandBundles/merge-func.ll
+++ b/llvm/test/Feature/OperandBundles/merge-func.ll
@@ -44,7 +44,7 @@ define i32 @f.invoke() personality i8 3 {
   ret i32 %v0
 
  exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   ret i32 0
 }
 
@@ -59,6 +59,6 @@ define i32 @g.invoke() personality i8 3 {
   ret i32 %v0
 
  exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   ret i32 0
 }
diff --git a/llvm/test/Linker/drop-attribute.ll b/llvm/test/Linker/drop-attribute.ll
index 9be95a89109b4e..69bcff5c4239c6 100644
--- a/llvm/test/Linker/drop-attribute.ll
+++ b/llvm/test/Linker/drop-attribute.ll
@@ -22,7 +22,7 @@ entry:
   invoke void @test_nocallback_call_site() nocallback
           to label %ret unwind label %unw
 unw:
-  %tmp = landingpad i8 cleanup
+  %tmp = landingpad { ptr, i8 } cleanup
   br label %ret
 ret:
   ret i32 0
diff --git a/llvm/test/Transforms/HotColdSplit/eh-pads.ll b/llvm/test/Transforms/HotColdSplit/eh-pads.ll
index ad7baf97f68d0c..11c20628044d00 100644
--- a/llvm/test/Transforms/HotColdSplit/eh-pads.ll
+++ b/llvm/test/Transforms/HotColdSplit/eh-pads.ll
@@ -12,7 +12,7 @@ entry:
 
 exception:
   ; Note: EH pads are not candidates for region entry points.
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %continue_exception
 
 continue_exception:
@@ -42,7 +42,7 @@ continue:
 
 exception:
   ; Note: EH pads are not candidates for region entry points.
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %trivial-eh-handler
 
 trivial-eh-handler:
@@ -75,7 +75,7 @@ cold3:
   ret void
 
 cold4:
-  landingpad i8 cleanup
+  landingpad { ptr, i8 } cleanup
   ret void
 }
 
diff --git a/llvm/test/Transforms/HotColdSplit/unwind.ll b/llvm/test/Transforms/HotColdSplit/unwind.ll
index 058fb32f319ab2..c8ea4ba07908b9 100644
--- a/llvm/test/Transforms/HotColdSplit/unwind.ll
+++ b/llvm/test/Transforms/HotColdSplit/unwind.ll
@@ -16,7 +16,7 @@ entry:
   invoke void @llvm.donothing() to label %normal unwind label %exception
 
 exception:
-  %cleanup = landingpad i32 cleanup
+  %cleanup = landingpad { ptr, i32 } cleanup
   br i1 undef, label %normal, label %continue_exception
 
 continue_exception:
@@ -25,7 +25,7 @@ continue_exception:
   br label %resume-eh
 
 resume-eh:
-  resume i32 undef
+  resume { ptr, i32 } undef
 
 normal:
   br i1 undef, label %continue_exception, label %exit
diff --git a/llvm/test/Transforms/IROutliner/illegal-invoke.ll b/llvm/test/Transforms/IROutliner/illegal-invoke.ll
index 82d62b928a3f83..7d7d59d37eec9f 100644
--- a/llvm/test/Transforms/IROutliner/illegal-invoke.ll
+++ b/llvm/test/Transforms/IROutliner/illegal-invoke.ll
@@ -16,7 +16,7 @@ define void @function1() personality i8 3 {
 ; CHECK-NEXT:    invoke void @llvm.donothing()
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
+; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:    cleanup
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
@@ -29,7 +29,7 @@ entry:
   store i32 3, ptr %b, align 4
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
@@ -44,7 +44,7 @@ define void @function2() personality i8 3 {
 ; CHECK-NEXT:    invoke void @llvm.donothing()
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
+; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:    cleanup
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
@@ -57,7 +57,7 @@ entry:
   store i32 3, ptr %b, align 4
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   br label %normal
 normal:
   ret void
diff --git a/llvm/test/Transforms/IROutliner/illegal-landingpad.ll b/llvm/test/Transforms/IROutliner/illegal-landingpad.ll
index 5d70d55ab6e4e8..f966adc05d3661 100644
--- a/llvm/test/Transforms/IROutliner/illegal-landingpad.ll
+++ b/llvm/test/Transforms/IROutliner/illegal-landingpad.ll
@@ -15,7 +15,7 @@ define void @function1() personality i8 3 {
 ; CHECK-NEXT:    invoke void @llvm.donothing()
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
+; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:    cleanup
 ; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
@@ -27,7 +27,7 @@ entry:
   %b = alloca i32, align 4
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   store i32 2, ptr %a, align 4
   store i32 3, ptr %b, align 4
   br label %normal
@@ -43,7 +43,7 @@ define void @function2() personality i8 3 {
 ; CHECK-NEXT:    invoke void @llvm.donothing()
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
+; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:    cleanup
 ; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
@@ -55,7 +55,7 @@ entry:
   %b = alloca i32, align 4
   invoke void @llvm.donothing() to label %normal unwind label %exception
 exception:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   store i32 2, ptr %a, align 4
   store i32 3, ptr %b, align 4
   br label %normal
diff --git a/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll b/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
index 6f659a88da2e2b..9ec677471f6024 100644
--- a/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
+++ b/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
@@ -760,7 +760,7 @@ define i32 @test14a(i32 %start, ptr %p, ptr %q, i1 %c) personality i1 1 {
 ; CHECK-NEXT:    ret i32 [[TMP2]]
 ; CHECK:       exception:
 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
-; CHECK-NEXT:    [[TMP3:%.*]] = landingpad i1
+; CHECK-NEXT:    [[TMP3:%.*]] = landingpad { ptr, i1 }
 ; CHECK-NEXT:            cleanup
 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
 ; CHECK-NEXT:    ret i32 [[TMP4]]
@@ -788,7 +788,7 @@ exit:
   ret i32 %foo
 
 exception:
-  landingpad i1
+  landingpad { ptr, i1 }
   cleanup
   ret i32 %foo
 }
diff --git a/llvm/test/Transforms/Inline/deopt-bundles.ll b/llvm/test/Transforms/Inline/deopt-bundles.ll
index 57175fabf0df4e..2017e8b34d9b85 100644
--- a/llvm/test/Transforms/Inline/deopt-bundles.ll
+++ b/llvm/test/Transforms/Inline/deopt-bundles.ll
@@ -73,7 +73,7 @@ define i32 @caller_3() personality i8 3 {
   ret i32 %x
 
  unwind:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   ret i32 101
 }
 
@@ -85,7 +85,7 @@ define i32 @callee_4() alwaysinline personality i8 3 {
   ret i32 %v
 
  unwind:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   ret i32 100
 }
 
@@ -105,7 +105,7 @@ define i32 @callee_5() alwaysinline personality i8 3 {
   ret i32 %v
 
  unwind:
-  %cleanup = landingpad i8 cleanup
+  %cleanup = landingpad { ptr, i8 } cleanup
   ret i32 100
 }
 
diff --git a/llvm/test/Transforms/Inline/deoptimize-intrinsic.ll b/llvm/test/Transforms/Inline/deoptimize-intrinsic.ll
index 1cc327ada7ee33..482bd7fa0a7517 100644
--- a/llvm/test/Transforms/Inline/deoptimize-intrinsic.ll
+++ b/llvm/test/Transforms/Inline/deoptimize-intrinsic.ll
@@ -82,7 +82,7 @@ entry:
 ; CHECK-NEXT:  ret i32 42
 
 unwind:
-  %lp = landingpad i32 cleanup
+  %lp = landingpad { ptr, i32 } cleanup
   ret i32 43
 
 normal:
diff --git a/llvm/test/Transforms/Inline/guard-intrinsic.ll b/llvm/test/Transforms/Inline/guard-intrinsic.ll
index 4e2bdfb196a404..e05b0e5d89ed92 100644
--- a/llvm/test/Transforms/Inline/guard-intrinsic.ll
+++ b/llvm/test/Transforms/Inline/guard-intrinsic.ll
@@ -30,7 +30,7 @@ entry:
        unwind label %unwind
 
 unwind:
-  %lp = landingpad i32 cleanup
+  %lp = landingpad { ptr, i32 } cleanup
   ret i32 43
 
 normal:
diff --git a/llvm/test/Transforms/Inline/inline_returns_twice.ll b/llvm/test/Transforms/Inline/inline_returns_twice.ll
index cacedc0e0bcf0a..ee7717e909000e 100644
--- a/llvm/test/Transforms/Inline/inline_returns_twice.ll
+++ b/llvm/test/Transforms/Inline/inline_returns_twice.ll
@@ -48,8 +48,8 @@ cont:
   ret i32 %add
 
 lpad:
-  %lp = landingpad i32 cleanup
-  resume i32 %lp
+  %lp = landingpad { ptr, i32 } cleanup
+  resume {ptr, i32} %lp
 }
 
 define i32 @outer3() {
@@ -71,8 +71,8 @@ cont:
   ret i32 %add
 
 lpad:
-  %lp = landingpad i32 cleanup
-  resume i32 %lp
+  %lp = landingpad { ptr, i32 } cleanup
+  resume {ptr, i32} %lp
 }
 
 define i32 @outer4() {
diff --git a/llvm/test/Transforms/Inline/invoke-cleanup.ll b/llvm/test/Transforms/Inline/invoke-cleanup.ll
index 9e0344b5b08a4b..f7bc2e33bd3e8e 100644
--- a/llvm/test/Transforms/Inline/invoke-cleanup.ll
+++ b/llvm/test/Transforms/Inline/invoke-cleanup.ll
@@ -14,9 +14,9 @@ define internal void @inner() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_type1
-  resume i32 %lp
+  resume {ptr, i32} %lp
 }
 
 ; Test that the "cleanup" clause is kept when inlining @inner() into
@@ -29,10 +29,10 @@ define void @outer() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       cleanup
       catch ptr @exception_type2
-  resume i32 %lp
+  resume {ptr, i32} %lp
 }
 ; CHECK: define void @outer
 ; CHECK: landingpad
diff --git a/llvm/test/Transforms/Inline/invoke-combine-clauses.ll b/llvm/test/Transforms/Inline/invoke-combine-clauses.ll
index ec1dafe8b68a66..552747cfdd757f 100644
--- a/llvm/test/Transforms/Inline/invoke-combine-clauses.ll
+++ b/llvm/test/Transforms/Inline/invoke-combine-clauses.ll
@@ -19,14 +19,14 @@ define internal void @inner_multiple_resume() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_inner
   %cond = load i1, ptr @condition
   br i1 %cond, label %resume1, label %resume2
 resume1:
-  resume i32 1
+  resume { ptr, i32 } { ptr null, i32 1 }
 resume2:
-  resume i32 2
+  resume { ptr, i32 } { ptr null, i32 2 }
 }
 
 define void @outer_multiple_resume() personality ptr null {
@@ -35,9 +35,9 @@ define void @outer_multiple_resume() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_outer
-  resume i32 %lp
+  resume { ptr, i32 } %lp
 }
 ; CHECK: define void @outer_multiple_resume()
 ; CHECK: %lp.i = landingpad
@@ -58,9 +58,9 @@ define internal void @inner_resume_and_call() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_inner
-  resume i32 %lp
+  resume {i8*, i32} %lp
 }
 
 define void @outer_resume_and_call() personality ptr null {
@@ -69,9 +69,9 @@ define void @outer_resume_and_call() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_outer
-  resume i32 %lp
+  resume {i8*, i32} %lp
 }
 ; CHECK: define void @outer_resume_and_call()
 ; CHECK: %lp.i = landingpad
@@ -93,7 +93,7 @@ define internal void @inner_no_resume_or_call() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_inner
   ; A landingpad might have no "resume" if a C++ destructor aborts.
   call void @abort() noreturn nounwind
@@ -106,9 +106,9 @@ define void @outer_no_resume_or_call() personality ptr null {
 cont:
   ret void
 lpad:
-  %lp = landingpad i32
+  %lp = landingpad { ptr, i32 }
       catch ptr @exception_outer
-  resume i32 %lp
+  resume { ptr, i32 } %lp
 }
 ; CHECK: define void @outer_no_resume_or_call()
 ; CHECK: %lp.i = landingpad
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index e8105b6287d0c5..28d04d51d34857 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -392,7 +392,7 @@ define i32 @freeze_invoke_use_in_phi(i1 %c) personality ptr undef {
 ; CHECK-NEXT:    call void @use_i32(i32 [[PHI]])
 ; CHECK-NEXT:    br label [[INVOKE_CONT]]
 ; CHECK:       invoke.unwind:
-; CHECK-NEXT:    [[TMP0:%.*]] = landingpad i8
+; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:            cleanup
 ; CHECK-NEXT:    unreachable
 ;
@@ -408,7 +408,7 @@ invoke.cont:
   br label %invoke.cont
 
 invoke.unwind:
-  landingpad i8 cleanup
+  landingpad { ptr, i8 } cleanup
   unreachable
 }
 
@@ -425,7 +425,7 @@ define i32 @freeze_invoke_use_after_phi(i1 %c) personality ptr undef {
 ; CHECK-NEXT:    call void @use_i32(i32 [[PHI]])
 ; CHECK-NEXT:    br label [[INVOKE_CONT]]
 ; CHECK:       invoke.unwind:
-; CHECK-NEXT:    [[TMP0:%.*]] = landingpad i8
+; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:            cleanup
 ; CHECK-NEXT:    unreachable
 ;
@@ -442,7 +442,7 @@ invoke.cont:
   br label %invoke.cont
 
 invoke.unwind:
-  landingpad i8 cleanup
+  landingpad { ptr, i8 } cleanup
   unreachable
 }
 
@@ -986,7 +986,7 @@ define void @fold_phi_invoke_start_value(i32 %n) personality ptr undef {
 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       unwind:
-; CHECK-NEXT:    [[TMP0:%.*]] = landingpad i8
+; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:            cleanup
 ; CHECK-NEXT:    unreachable
 ; CHECK:       exit:
@@ -1004,7 +1004,7 @@ loop:
   br i1 %cond, label %loop, label %exit
 
 unwind:
-  landingpad i8 cleanup
+  landingpad { ptr, i8 } cleanup
   unreachable
 
 exit:
@@ -1022,7 +1022,7 @@ define void @fold_phi_invoke_noundef_start_value(i32 %n) personality ptr undef {
 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       unwind:
-; CHECK-NEXT:    [[TMP0:%.*]] = landingpad i8
+; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:            cleanup
 ; CHECK-NEXT:    unreachable
 ; CHECK:       exit:
@@ -1040,7 +1040,7 @@ loop:
   br i1 %cond, label %loop, label %exit
 
 unwind:
-  landingpad i8 cleanup
+  landingpad { ptr, i8 } cleanup
   unreachable
 
 exit:
diff --git a/llvm/test/Transforms/InstSimplify/freeze.ll b/llvm/test/Transforms/InstSimplify/freeze.ll
index 6c4b16076e724e..ee40592cb5bc0d 100644
--- a/llvm/test/Transforms/InstSimplify/freeze.ll
+++ b/llvm/test/Transforms/InstSimplify/freeze.ll
@@ -269,21 +269,23 @@ define ptr @call_noundef_ptr(ptr %ptr) {
 define ptr @invoke_noundef_ptr(ptr %ptr) personality i8 1 {
 ; CHECK-LABEL: @invoke_noundef_ptr(
 ; CHECK-NEXT:    invoke void @f3(ptr noundef [[PTR:%.*]])
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[UNWIND:%.*]]
+; CHECK-NEXT:            to label [[NORMAL:%.*]] unwind label [[UNWIND:%.*]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret ptr [[PTR]]
 ; CHECK:       unwind:
-; CHECK-NEXT:    [[TMP1:%.*]] = landingpad ptr
-; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    resume ptr [[PTR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT:            cleanup
+; CHECK-NEXT:    [[SPTR:%.*]] = insertvalue { ptr, i32 } { ptr undef, i32 1 }, ptr [[PTR]], 0
+; CHECK-NEXT:    resume { ptr, i32 } [[SPTR]]
 ;
   %q = freeze ptr %ptr
   invoke void @f3(ptr noundef %ptr) to label %normal unwind label %unwind
 normal:
   ret ptr %q
 unwind:
-  landingpad ptr cleanup
-  resume ptr %q
+  landingpad { ptr, i32 } cleanup
+  %sptr = insertvalue { ptr, i32 } { ptr undef, i32 1 }, ptr %q, 0
+  resume { ptr, i32 } %sptr
 }
 
 define ptr @cmpxchg_ptr(ptr %ptr) {
@@ -443,7 +445,7 @@ EXIT:
 define i32 @brcond_switch(i32 %x) {
 ; CHECK-LABEL: @brcond_switch(
 ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[EXIT:%.*]] [
-; CHECK-NEXT:    i32 0, label [[A:%.*]]
+; CHECK-NEXT:      i32 0, label [[A:%.*]]
 ; CHECK-NEXT:    ]
 ; CHECK:       A:
 ; CHECK-NEXT:    ret i32 [[X]]
diff --git a/llvm/test/Transforms/InstSimplify/known-never-nan.ll b/llvm/test/Transforms/InstSimplify/known-never-nan.ll
index 49a48ae42d0645..792bb5277425b5 100644
--- a/llvm/test/Transforms/InstSimplify/known-never-nan.ll
+++ b/llvm/test/Transforms/InstSimplify/known-never-nan.ll
@@ -541,9 +541,9 @@ define i1 @isKnownNeverNaN_invoke_callsite(ptr %ptr) personality i8 1 {
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret i1 true
 ; CHECK:       unwind:
-; CHECK-NEXT:    [[TMP1:%.*]] = landingpad ptr
+; CHECK-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i8 }
 ; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    resume ptr null
+; CHECK-NEXT:    resume { ptr, i8 } %cleanup
 ;
   %invoke = invoke nofpclass(nan) float %ptr() to label %normal unwind label %unwind
 
@@ -552,8 +552,8 @@ normal:
   ret i1 %ord
 
 unwind:
-  landingpad ptr cleanup
-  resume ptr null
+  %cleanup = landingpad { ptr, i8 } cleanup
+  resume { ptr, i8 } %cleanup
 }
 
 ; This should not fold to false because fmul 0 * inf = nan
diff --git a/llvm/test/Transforms/LowerInvoke/2003-12-10-Crash.ll b/llvm/test/Transforms/LowerInvoke/2003-12-10-Crash.ll
index d28107257e26d5..d02cfa4cb968aa 100644
--- a/llvm/test/Transforms/LowerInvoke/2003-12-10-Crash.ll
+++ b/llvm/test/Transforms/LowerInvoke/2003-12-10-Crash.ll
@@ -15,7 +15,7 @@ invoke_cont.0:		; preds = %then
 			to label %try_exit unwind label %try_catch
 try_catch:		; preds = %invoke_cont.0, %then
 	%__tmp.0 = phi ptr [ null, %invoke_cont.0 ], [ null, %then ]		; <ptr> [#uses=0]
-  %res = landingpad { ptr }
+  %res = landingpad { ptr, i8 }
           cleanup
 	ret void
 try_exit:		; preds = %invoke_cont.0
diff --git a/llvm/test/Transforms/MemCpyOpt/stack-move.ll b/llvm/test/Transforms/MemCpyOpt/stack-move.ll
index 6089c0a4d7cf50..f41af57f51c218 100644
--- a/llvm/test/Transforms/MemCpyOpt/stack-move.ll
+++ b/llvm/test/Transforms/MemCpyOpt/stack-move.ll
@@ -401,9 +401,9 @@ define void @terminator_lastuse() personality i32 0 {
 ; CHECK-NEXT:    [[RV:%.*]] = invoke i32 @use_nocapture(ptr [[SRC]])
 ; CHECK-NEXT:    to label [[SUC:%.*]] unwind label [[UNW:%.*]]
 ; CHECK:       unw:
-; CHECK-NEXT:    [[LP:%.*]] = landingpad i32
+; CHECK-NEXT:    [[LP:%.*]] = landingpad { ptr, i32 }
 ; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    resume i32 0
+; CHECK-NEXT:    resume { ptr, i32 } zeroinitializer
 ; CHECK:       suc:
 ; CHECK-NEXT:    ret void
 ;
@@ -420,8 +420,8 @@ define void @terminator_lastuse() personality i32 0 {
   %rv = invoke i32 @use_nocapture(ptr %dest)
   to label %suc unwind label %unw
 unw:
-  %lp = landingpad i32 cleanup
-  resume i32 0
+  %lp = landingpad { ptr, i32 } cleanup
+  resume { ptr, i32 } {ptr null, i32 0}
 suc:
   ret void
 }
diff --git a/llvm/test/Transforms/SCCP/landingpad.ll b/llvm/test/Transforms/SCCP/landingpad.ll
index 507a972334b985..0259228a99603d 100644
--- a/llvm/test/Transforms/SCCP/landingpad.ll
+++ b/llvm/test/Transforms/SCCP/landingpad.ll
@@ -12,7 +12,7 @@ define void @test() personality ptr null {
 ; CHECK:       success:
 ; CHECK-NEXT:    ret void
 ; CHECK:       failure:
-; CHECK-NEXT:    [[PAD:%.*]] = landingpad {}
+; CHECK-NEXT:    [[PAD:%.*]] = landingpad { ptr, i32 }
 ; CHECK-NEXT:    cleanup
 ; CHECK-NEXT:    unreachable
 ;
@@ -23,7 +23,7 @@ success:
   ret void
 
 failure:
-  %pad = landingpad {}
+  %pad = landingpad { ptr, i32 }
   cleanup
   unreachable
 }
diff --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index 757340527ec030..9c83f0b85ef8cd 100644
--- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -27,7 +27,7 @@ entry:
   invoke void @test2( )
   to label %N unwind label %U
 U:
-  %res = landingpad { ptr }
+  %res = landingpad { ptr, i32 }
   cleanup
   unreachable
 N:
diff --git a/llvm/test/Transforms/SimplifyCFG/pr39807.ll b/llvm/test/Transforms/SimplifyCFG/pr39807.ll
index c150c1b54cb8d2..2403fb4dbd9e42 100644
--- a/llvm/test/Transforms/SimplifyCFG/pr39807.ll
+++ b/llvm/test/Transforms/SimplifyCFG/pr39807.ll
@@ -19,7 +19,7 @@ success:
     ret void
 
 failure:
-    landingpad {}
+    landingpad { ptr, i32 }
         cleanup
     ret void
 }
diff --git a/llvm/test/Transforms/WholeProgramDevirt/uniform-retval-invoke.ll b/llvm/test/Transforms/WholeProgramDevirt/uniform-retval-invoke.ll
index 88d539294777e1..52daf4693924b5 100644
--- a/llvm/test/Transforms/WholeProgramDevirt/uniform-retval-invoke.ll
+++ b/llvm/test/Transforms/WholeProgramDevirt/uniform-retval-invoke.ll
@@ -24,7 +24,7 @@ define i32 @call(ptr %obj) personality ptr undef {
   %result = invoke i32 %fptr(ptr %obj) to label %ret unwind label %unwind
 
 unwind:
-  %x = landingpad i32 cleanup
+  %x = landingpad { ptr, i32 } cleanup
   unreachable
 
 ret:
diff --git a/llvm/test/Verifier/landingpad-types.ll b/llvm/test/Verifier/landingpad-types.ll
new file mode 100644
index 00000000000000..310695a6869e8d
--- /dev/null
+++ b/llvm/test/Verifier/landingpad-types.ll
@@ -0,0 +1,16 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+declare i32 @pers(...)
+declare void @f()
+
+define void @f1() personality ptr @pers {
+  invoke void @f() to label %normal unwind label %lp
+
+normal:
+  ret void
+
+lp:
+; CHECK:Only two-valued landingpads are supported
+  landingpad {ptr} cleanup
+  ret void
+}



More information about the llvm-commits mailing list