[llvm] [WinEH] Fix asm in catchpad being turned into unreachable (PR #138392)

via llvm-commits llvm-commits at lists.llvm.org
Sat May 3 03:44:38 PDT 2025


https://github.com/Ralender created https://github.com/llvm/llvm-project/pull/138392

None

>From 354b324319959ecdb0e1665da341e7cbcf2d02ff Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Sat, 3 May 2025 12:33:44 +0200
Subject: [PATCH 1/2] [WinEH] Add test showing bug

---
 llvm/test/CodeGen/WinEH/wineh-asm2.ll | 45 +++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 llvm/test/CodeGen/WinEH/wineh-asm2.ll

diff --git a/llvm/test/CodeGen/WinEH/wineh-asm2.ll b/llvm/test/CodeGen/WinEH/wineh-asm2.ll
new file mode 100644
index 0000000000000..30c720cf0b8a6
--- /dev/null
+++ b/llvm/test/CodeGen/WinEH/wineh-asm2.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=win-eh-prepare -S | FileCheck %s
+
+target triple = "x86_64-unknown-windows-msvc"
+
+%rtti.TypeDescriptor2 = type { ptr, ptr, [3 x i8] }
+
+$"??_R0H at 8" = comdat any
+
+@"??_7type_info@@6B@" = external constant ptr
+@"??_R0H at 8" = linkonce_odr global %rtti.TypeDescriptor2 { ptr @"??_7type_info@@6B@", ptr null, [3 x i8] c".H\00" }, comdat
+
+declare dso_local i32 @test0(i32) local_unnamed_addr
+
+define dso_local i32 @test1(i32 %argc) local_unnamed_addr personality ptr @__CxxFrameHandler3 {
+; CHECK-LABEL: define dso_local i32 @test1(
+; CHECK-SAME: i32 [[ARGC:%.*]]) local_unnamed_addr personality ptr @__CxxFrameHandler3 {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CALL:%.*]] = invoke i32 @test0(i32 [[ARGC]])
+; CHECK-NEXT:            to label %[[RETURN:.*]] unwind label %[[CATCH_DISPATCH:.*]]
+; CHECK:       [[CATCH_DISPATCH]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = catchswitch within none [label %catch] unwind to caller
+; CHECK:       [[CATCH:.*:]]
+; CHECK-NEXT:    [[TMP1:%.*]] = catchpad within [[TMP0]] [ptr @"??_R0H at 8", i32 0, ptr null]
+; CHECK-NEXT:    unreachable
+; CHECK:       [[RETURN]]:
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %call = invoke i32 @test0(i32 %argc)
+  to label %return unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %catch] unwind to caller
+
+catch:                                            ; preds = %catch.dispatch
+  %1 = catchpad within %0 [ptr @"??_R0H at 8", i32 0, ptr null]
+  call void asm "", ""()
+  catchret from %1 to label %return
+
+return:                                           ; preds = %catch, %entry
+  ret i32 0
+}
+
+declare dso_local i32 @__CxxFrameHandler3(...)

>From 7d4c57970c112a83331d69c066748d905d03af00 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Sat, 3 May 2025 12:35:27 +0200
Subject: [PATCH 2/2] [WinEH] fix issue where asm was turned into unreachable

---
 llvm/lib/CodeGen/WinEHPrepare.cpp     | 4 ++--
 llvm/test/CodeGen/WinEH/wineh-asm2.ll | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 74cef6c134736..43dd651a686b9 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -1135,8 +1135,8 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
         // Skip call sites which are nounwind intrinsics or inline asm.
         auto *CalledFn =
             dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
-        if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
-                         CB->isInlineAsm()))
+        if (CB->isInlineAsm() ||
+            (CalledFn && CalledFn->isIntrinsic() && CB->doesNotThrow()))
           continue;
 
         // This call site was not part of this funclet, remove it.
diff --git a/llvm/test/CodeGen/WinEH/wineh-asm2.ll b/llvm/test/CodeGen/WinEH/wineh-asm2.ll
index 30c720cf0b8a6..2c424536dca09 100644
--- a/llvm/test/CodeGen/WinEH/wineh-asm2.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-asm2.ll
@@ -22,7 +22,8 @@ define dso_local i32 @test1(i32 %argc) local_unnamed_addr personality ptr @__Cxx
 ; CHECK-NEXT:    [[TMP0:%.*]] = catchswitch within none [label %catch] unwind to caller
 ; CHECK:       [[CATCH:.*:]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = catchpad within [[TMP0]] [ptr @"??_R0H at 8", i32 0, ptr null]
-; CHECK-NEXT:    unreachable
+; CHECK-NEXT:    call void asm "", ""()
+; CHECK-NEXT:    catchret from [[TMP1]] to label %[[RETURN]]
 ; CHECK:       [[RETURN]]:
 ; CHECK-NEXT:    ret i32 0
 ;



More information about the llvm-commits mailing list