[llvm] [X86] Avoid invalid ret for EH_RETURN with SHSTK (PR #219322)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 11:20:45 PDT 2026


https://github.com/linisha15 updated https://github.com/llvm/llvm-project/pull/219322

>From c2c6691e7420d5b988769a7edcc750902bc4ba16 Mon Sep 17 00:00:00 2001
From: linisha <linisha232 at gmail.com>
Date: Fri, 28 Aug 2026 04:19:59 +0530
Subject: [PATCH 1/4] [X86] Avoid invalid ret for EH_RETURN with SHSTK

---
 llvm/lib/Target/X86/X86ExpandPseudo.cpp  | 12 ++++++++++++
 llvm/test/CodeGen/X86/eh-return-shstk.ll | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/eh-return-shstk.ll

diff --git a/llvm/lib/Target/X86/X86ExpandPseudo.cpp b/llvm/lib/Target/X86/X86ExpandPseudo.cpp
index 612d90361a44e..b8195e9cefc98 100644
--- a/llvm/lib/Target/X86/X86ExpandPseudo.cpp
+++ b/llvm/lib/Target/X86/X86ExpandPseudo.cpp
@@ -402,6 +402,18 @@ bool X86ExpandPseudoImpl::expandMI(MachineBasicBlock &MBB,
     BuildMI(MBB, MBBI, DL,
             TII->get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr), StackPtr)
         .addReg(DestAddr.getReg());
+    if (STI->hasSHSTK()) {
+      unsigned PopOpcode = Uses64BitFramePtr ? X86::POP64r : X86::POP32r;
+      unsigned JumpOpcode = X86::JMP32r;
+      if (Uses64BitFramePtr)
+        JumpOpcode = STI->isTargetWin64() || STI->isTargetUEFI64()
+                         ? X86::JMP64r_REX
+                         : X86::JMP64r;
+      BuildMI(MBB, MBBI, DL, TII->get(PopOpcode))
+          .addReg(DestAddr.getReg(), RegState::Define);
+      BuildMI(MBB, MBBI, DL, TII->get(JumpOpcode)).addReg(DestAddr.getReg());
+      MBB.erase(MBBI);
+    }
     // The EH_RETURN pseudo is really removed during the MC Lowering.
     return true;
   }
diff --git a/llvm/test/CodeGen/X86/eh-return-shstk.ll b/llvm/test/CodeGen/X86/eh-return-shstk.ll
new file mode 100644
index 0000000000000..5f2c5d194824f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/eh-return-shstk.ll
@@ -0,0 +1,19 @@
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=RET
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+shstk -verify-machineinstrs < %s | FileCheck %s --check-prefix=SHSTK
+
+define void @test(i64 %offset, ptr %handler) {
+entry:
+  call void @llvm.eh.return.i64(i64 %offset, ptr %handler)
+  unreachable
+}
+
+; RET-LABEL: test:
+; RET:       movq %rcx, %rsp
+; RET-NEXT:  retq
+
+; SHSTK-LABEL: test:
+; SHSTK:      movq %rcx, %rsp
+; SHSTK-NEXT: popq %rcx
+; SHSTK-NEXT: jmpq *%rcx
+
+declare void @llvm.eh.return.i64(i64, ptr)

>From 504047b3a47f730de05010f7887dd95dc8816418 Mon Sep 17 00:00:00 2001
From: Linisha <linisha232 at gmail.com>
Date: Mon, 7 Sep 2026 23:07:18 +0530
Subject: [PATCH 2/4] Update llvm/lib/Target/X86/X86ExpandPseudo.cpp

Co-authored-by: Phoebe Wang <phoebe.wang at intel.com>
---
 llvm/lib/Target/X86/X86ExpandPseudo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86ExpandPseudo.cpp b/llvm/lib/Target/X86/X86ExpandPseudo.cpp
index b8195e9cefc98..bb7b7092fd8bf 100644
--- a/llvm/lib/Target/X86/X86ExpandPseudo.cpp
+++ b/llvm/lib/Target/X86/X86ExpandPseudo.cpp
@@ -403,7 +403,7 @@ bool X86ExpandPseudoImpl::expandMI(MachineBasicBlock &MBB,
             TII->get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr), StackPtr)
         .addReg(DestAddr.getReg());
     if (STI->hasSHSTK()) {
-      unsigned PopOpcode = Uses64BitFramePtr ? X86::POP64r : X86::POP32r;
+      unsigned PopOpcode = STI->is64Bit() ? X86::POP64r : X86::POP32r;
       unsigned JumpOpcode = X86::JMP32r;
       if (Uses64BitFramePtr)
         JumpOpcode = STI->isTargetWin64() || STI->isTargetUEFI64()

>From 5aaf37a12788a1d059a6f359f0649578a899c6b4 Mon Sep 17 00:00:00 2001
From: linisha <linisha232 at gmail.com>
Date: Mon, 7 Sep 2026 23:33:35 +0530
Subject: [PATCH 3/4] [X86] Add EH_RETURN SHSTK target tests

---
 llvm/test/CodeGen/X86/eh-return-shstk.ll | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/test/CodeGen/X86/eh-return-shstk.ll b/llvm/test/CodeGen/X86/eh-return-shstk.ll
index 5f2c5d194824f..7281085ee9c72 100644
--- a/llvm/test/CodeGen/X86/eh-return-shstk.ll
+++ b/llvm/test/CodeGen/X86/eh-return-shstk.ll
@@ -1,5 +1,7 @@
 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=RET
 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+shstk -verify-machineinstrs < %s | FileCheck %s --check-prefix=SHSTK
+; RUN: llc -mtriple=x86_64-pc-windows-msvc -mattr=+shstk -verify-machineinstrs < %s | FileCheck %s --check-prefix=WIN64
+; RUN: llc -mtriple=x86_64-uefi -mattr=+shstk -verify-machineinstrs < %s | FileCheck %s --check-prefix=UEFI64
 
 define void @test(i64 %offset, ptr %handler) {
 entry:
@@ -16,4 +18,14 @@ entry:
 ; SHSTK-NEXT: popq %rcx
 ; SHSTK-NEXT: jmpq *%rcx
 
+; WIN64-LABEL: test:
+; WIN64:       movq %rcx, %rsp
+; WIN64-NEXT:  popq %rcx
+; WIN64-NEXT:  rex64 jmpq *%rcx
+
+; UEFI64-LABEL: test:
+; UEFI64:       movq %rcx, %rsp
+; UEFI64-NEXT:  popq %rcx
+; UEFI64-NEXT:  rex64 jmpq *%rcx
+
 declare void @llvm.eh.return.i64(i64, ptr)

>From fcaeb0bbc101565cdf5c4cf9a6d4158e3118e64e Mon Sep 17 00:00:00 2001
From: linisha <linisha232 at gmail.com>
Date: Mon, 7 Sep 2026 23:49:58 +0530
Subject: [PATCH 4/4] [X86] Add 32-bit EH_return-shstk test

---
 llvm/test/CodeGen/X86/eh-return-shstk-32.ll | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/eh-return-shstk-32.ll

diff --git a/llvm/test/CodeGen/X86/eh-return-shstk-32.ll b/llvm/test/CodeGen/X86/eh-return-shstk-32.ll
new file mode 100644
index 0000000000000..5f9e65669424c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/eh-return-shstk-32.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=i386-pc-linux -mattr=+shstk -verify-machineinstrs < %s | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
+target triple = "i386-pc-linux"
+
+define void @test(i32 %offset, ptr %handler) {
+entry:
+  call void @llvm.eh.return.i32(i32 %offset, ptr %handler)
+  unreachable
+}
+
+; CHECK-LABEL: test:
+; CHECK:       movl %ecx, %esp
+; CHECK-NEXT:  popl %ecx
+; CHECK-NEXT:  jmpl *%ecx
+
+declare void @llvm.eh.return.i32(i32, ptr)
\ No newline at end of file



More information about the llvm-commits mailing list