[all-commits] [llvm/llvm-project] 837a4e: [X86] Avoid invalid ret for EH_RETURN with SHSTK (...

Linisha via All-commits all-commits at lists.llvm.org
Wed Sep 9 06:55:07 PDT 2026


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 837a4eab85a2f4e638034a254a2bc74b1986b2ac
      https://github.com/llvm/llvm-project/commit/837a4eab85a2f4e638034a254a2bc74b1986b2ac
  Author: Linisha <linisha232 at gmail.com>
  Date:   2026-09-09 (Wed, 09 Sep 2026)

  Changed paths:
    M llvm/lib/Target/X86/X86ExpandPseudo.cpp
    A llvm/test/CodeGen/X86/eh-return-shstk-32.ll
    A llvm/test/CodeGen/X86/eh-return-shstk.ll

  Log Message:
  -----------
  [X86] Avoid invalid ret for EH_RETURN with SHSTK (#219322)

## Summary

Fixes #215298

When lowering `llvm.eh.return` on x86, LLVM rewrites the normal stack
return
address and then emits `ret`. This is incompatible with CET shadow
stacks:
the shadow stack still contains the original return address, so `ret`
raises
a control-protection fault.

This affects code using `__builtin_eh_return` with: -mshstk
-fcf-protection=full


## What changed

When SHSTK is enabled, the x86 `EH_RETURN` pseudo-instruction now
expands to:

```asm
movq %rcx, %rsp
popq %rcx
jmpq *%rcx
```

- The `pop` consumes the rewritten return target and advances the stack
pointer.
- `llvm.eh.return` performs a non-local control transfer to an
  explicitly supplied handler address, which was never pushed by a
  matching `call`. It therefore cannot satisfy `ret`'s architectural
  shadow-stack matching requirement regardless of implementation, so
  an indirect `jmp` is used instead.
- The existing `mov %rcx, %rsp; ret` sequence is preserved for targets
  without SHSTK support.
- The expansion handles 32-bit and 64-bit targets, including the
existing
  Windows/UEFI x64 indirect-jump variant.

## Testing

Added: `eh-return-shstk.ll`

The test verifies that:
- non-SHSTK targets continue to emit `ret`
- SHSTK targets emit `pop` followed by an indirect `jmp`
- machine instruction verification succeeds in both configurations

Validation performed:

```bash
ninja -C build llc FileCheck llvm-config count not
build/bin/llvm-lit -sv llvm/test/CodeGen/X86/eh-return-shstk.ll
```

Passed: 1 (100.00%)


The original C reproducer was also compiled with the rebuilt Clang. Its
`pop_frame` function now emits:

```asm
movq %rcx, %rsp
popq %rcx
jmpq *%rcx
```

Runtime execution of the reproducer could not be fully validated because
the
available environment is WSL2 without usable CET shadow-stack support.
The
compiler output and LLVM regression test both pass, but this does not
confirm the control-protection fault is resolved on real CET-enabled
hardware, only that the expected instruction sequence is now emitted.

---------

Co-authored-by: Phoebe Wang <phoebe.wang at intel.com>



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list