[llvm] [CodeGen] Diagnose unsupported landingpad result types instead of asserting (PR #223205)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 12 23:09:27 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

Fixes #<!-- -->220959

`SelectionDAGBuilder::visitLandingPad` reads the exception pointer and the selector out of two registers, so it assumed the landingpad's result type always decomposes into exactly two values and asserted otherwise. LangRef doesn't promise that shape: it says how the personality function's results are represented is target specific, the verifier only checks that every landingpad in a function agrees on a type, and `landingpad token` is already accepted. So `landingpad {}` (or `landingpad i32`) is well-formed IR that the backend just can't lower, and it took the whole compiler down with it.

Replaced the assertion with a `DiagnosticInfoUnsupported` error, the same mechanism the type-test intrinsics use in that file, and lowered the result to poison so compilation can carry on and report anything else. GlobalISel's `translateLandingPad` had the same assertion behind an unchecked `cast<StructType>`; it now fails the translation cleanly and falls back to SelectionDAG, which emits the diagnostic. Added `llvm/test/CodeGen/X86/pr220959.ll` with the empty struct from the report plus a scalar and a three-element struct, run at `-O2` and at `-O0` where FastISel hands the landingpad back to SelectionDAG.

---
Full diff: https://github.com/llvm/llvm-project/pull/223205.diff


4 Files Affected:

- (modified) llvm/docs/ReleaseNotes.md (+5) 
- (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+6-2) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+14-1) 
- (added) llvm/test/CodeGen/X86/pr220959.ll (+46) 


``````````diff
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 4718d47bf8c10..f68c7d2875443 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -269,6 +269,11 @@ Makes programs 10x faster by doing Special New Thing.
   compiling a function containing a static alloca of `(size_t)-1` bytes, whose
   size collided with the sentinel value MachineFrameInfo used to mark dead
   stack objects.
+* Fixed a crash
+  ([#220959](https://github.com/llvm/llvm-project/issues/220959)) when
+  compiling a `landingpad` whose result type does not consist of an exception
+  pointer and a selector (for example `{}`). Such a landingpad is now rejected
+  with a clean "unsupported" diagnostic instead of an assertion failure.
 
 ### Changes to the Metadata Info
 
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index a1fe689685258..e3694a83ccba8 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3951,6 +3951,11 @@ bool IRTranslatorImpl::translateLandingPad(const User &U,
   if (LP.getType()->isTokenTy())
     return true;
 
+  // Only the two-valued (exception pointer, selector) form can be translated.
+  auto *LPTy = dyn_cast<StructType>(LP.getType());
+  if (!LPTy || LPTy->getNumElements() != 2)
+    return false;
+
   // Add a label to mark the beginning of the landing pad.  Deletion of the
   // landing pad can thus be detected via the MachineModuleInfo.
   MIRBuilder.buildInstr(TargetOpcode::EH_LABEL)
@@ -3967,9 +3972,8 @@ bool IRTranslatorImpl::translateLandingPad(const User &U,
   MIRBuilder.buildUndef(Undef);
 
   SmallVector<LLT, 2> Tys;
-  for (Type *Ty : cast<StructType>(LP.getType())->elements())
+  for (Type *Ty : LPTy->elements())
     Tys.push_back(getLLTForType(*Ty, *DL));
-  assert(Tys.size() == 2 && "Only two-valued landingpads are supported");
 
   // Mark exception register as live in.
   Register ExceptionReg = TLI->getExceptionPointerRegister(
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 794a4e6e1b537..e1b844bfce71e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3655,7 +3655,20 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
   SmallVector<EVT, 2> ValueVTs;
   SDLoc dl = getCurSDLoc();
   ComputeValueVTs(TLI, DAG.getDataLayout(), LP.getType(), ValueVTs);
-  assert(ValueVTs.size() == 2 && "Only two-valued landingpads are supported");
+
+  // Only the two-valued (exception pointer, selector) form can be lowered.
+  // LangRef leaves the result type target-specific, so diagnose other shapes
+  // instead of asserting.
+  if (ValueVTs.size() != 2) {
+    DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
+        *LP.getFunction(),
+        "landingpad result type must consist of exactly two values, the "
+        "exception pointer and the selector",
+        dl.getDebugLoc()));
+    if (!ValueVTs.empty())
+      setValueToPoison(&LP, dl);
+    return;
+  }
 
   // Get the two live-in registers as SDValues. The physregs have already been
   // copied into virtual registers.
diff --git a/llvm/test/CodeGen/X86/pr220959.ll b/llvm/test/CodeGen/X86/pr220959.ll
new file mode 100644
index 0000000000000..ef03c662e9a59
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr220959.ll
@@ -0,0 +1,46 @@
+; RUN: not llc %s -mtriple=x86_64-unknown-linux-gnu -filetype=null 2>&1 | FileCheck %s
+; RUN: not llc %s -mtriple=x86_64-unknown-linux-gnu -O0 -filetype=null 2>&1 | FileCheck %s
+
+; A landingpad whose result type is not (exception pointer, selector) used to
+; trip an assertion in SelectionDAGBuilder::visitLandingPad. Expect a clean
+; diagnostic instead.
+
+; CHECK: error: {{.*}}in function main{{.*}}landingpad result type must consist of exactly two values, the exception pointer and the selector
+define i32 @main() personality ptr @__gxx_personality_v0 {
+  invoke void @g()
+          to label %cont unwind label %cleanup
+cont:
+  ret i32 0
+cleanup:
+  %lp = landingpad {}
+          cleanup
+  ret i32 1
+}
+
+; CHECK: error: {{.*}}in function scalar{{.*}}landingpad result type must consist of exactly two values, the exception pointer and the selector
+define i32 @scalar() personality ptr @__gxx_personality_v0 {
+  invoke void @g()
+          to label %cont unwind label %cleanup
+cont:
+  ret i32 0
+cleanup:
+  %lp = landingpad i32
+          cleanup
+  ret i32 %lp
+}
+
+; CHECK: error: {{.*}}in function three_values{{.*}}landingpad result type must consist of exactly two values, the exception pointer and the selector
+define i32 @three_values() personality ptr @__gxx_personality_v0 {
+  invoke void @g()
+          to label %cont unwind label %cleanup
+cont:
+  ret i32 0
+cleanup:
+  %lp = landingpad { ptr, i32, i32 }
+          cleanup
+  %sel = extractvalue { ptr, i32, i32 } %lp, 2
+  ret i32 %sel
+}
+
+declare void @g()
+declare i32 @__gxx_personality_v0(...)

``````````

</details>


https://github.com/llvm/llvm-project/pull/223205


More information about the llvm-commits mailing list