Skip to content

Preserve wasm pointer allocas for shadow stack GC under -O2#1

Draft
Copilot wants to merge 3 commits intorelease/16.xfrom
copilot/retain-shadow-stack-functionality
Draft

Preserve wasm pointer allocas for shadow stack GC under -O2#1
Copilot wants to merge 3 commits intorelease/16.xfrom
copilot/retain-shadow-stack-functionality

Conversation

Copy link
Copy Markdown

Copilot AI commented Jan 26, 2026

Optimized WebAssembly codegen can drop shadow stack synchronization by promoting pointer allocas into locals, leaving GC roots invisible in linear memory.

  • Problem summary: O2 optimizations (e.g., mem2reg/localization) can eliminate stack writes for pointer roots, breaking shadow-stack style GC visibility.
  • Changes: Prevent mem2reg from promoting pointer allocas on wasm targets to keep roots in linear memory, and add a WebAssembly codegen test to ensure a store remains before a GC call.
Original prompt

目前我的研究发现,使用默认优化时,llvm会保留将local值写回C栈(或者在wasm的语义下叫作Shadow Stack, 即以__stack__pointer为栈底指针的linear memory区域)的功能(可能对于函数传参的情况不完整?我不确定);在O2优化之后,同步机制就被破坏了,这是由于llvm里的一些优化,如mem2reg,破坏了一些东西,导致: 1. 可能是维护shadow stack的llvm ir缺失了 2. 可能是最后wasm生成器,无法从优化后的llvm ir里识别到,某一处需要插一个维护shadow stack的操作 这些功能将Shadow Stack同步功能破坏掉,导致无法正确写回,进而导致boehm gc失效。我现在希望能够在O2优化下也保留这个功能。请为我实现这个功能,或者至少给我定位到导致同步失效的代码块及原因。
可以参考仓库:WebAssembly/binaryen仓库的SpillPointer.cpp。
目标仓库:PLUTOFX/llvm-project


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Enhance LLVM optimizations to preserve shadow stack functionality Investigate wasm shadow stack sync regression under -O2 Jan 26, 2026
Copilot AI requested a review from PLUTOFX January 26, 2026 08:45
@PLUTOFX
Copy link
Copy Markdown
Owner

PLUTOFX commented Jan 26, 2026

@copilot I got it. Then implement this fix and check this fix.

@PLUTOFX
Copy link
Copy Markdown
Owner

PLUTOFX commented Jan 26, 2026

@copilot 实际上我的问题是,一个变量通过堆分配拿到的指针,只存在local寄存器里,没往linear memory的shadow stack(即(__stack_pointer + n)的内存区域)里同步。并不是在local里寄存的__stack_pointer本身没有向global同步。举例:
对于函数cons:
// 链表节点结构体
typedef struct Node {
int value;
struct Node* next;
} Node;

// 创建新节点并添加到链表头部
Node* cons(int x, Node* xs) {
Node* n = GC_malloc(sizeof(Node));
n->value = x;
n->next = xs;
GC_gcollect();
return n;
}

下面是O0情况下的被编译成的wasm指令,可以看到新的node被存储到了__stack_pointer + n的区域
(func $cons (type 8) (param i32 i32) (result i32)
(local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32)
global.get $__stack_pointer
local.set 2
i32.const 16
local.set 3
local.get 2
local.get 3
i32.sub
local.set 4
local.get 4
global.set $__stack_pointer
local.get 4
local.get 0
i32.store offset=12
local.get 4
local.get 1
i32.store offset=8
i32.const 8
local.set 5
local.get 5
call $GC_malloc
local.set 6
local.get 4
local.get 6
i32.store offset=4
local.get 4
i32.load offset=12
local.set 7
local.get 4
i32.load offset=4
local.set 8
local.get 8
local.get 7
i32.store
local.get 4
i32.load offset=8
local.set 9
local.get 4
i32.load offset=4
local.set 10
local.get 10
local.get 9
i32.store offset=4
call $GC_gcollect
local.get 4
i32.load offset=4
local.set 11
i32.const 16
local.set 12
local.get 4
local.get 12
i32.add
local.set 13
local.get 13
global.set $__stack_pointer
local.get 11
return)
但是在O2优化下,分配的局部变量不会被同步到stack区域内,而只是存储在local里。
请结合我的新说明,再次进行研究。

@PLUTOFX
Copy link
Copy Markdown
Owner

PLUTOFX commented Jan 26, 2026

@copilot I got it. Then implement this fix and check this fix.

Copilot AI and others added 2 commits January 26, 2026 13:11
Co-authored-by: PLUTOFX <110596339+PLUTOFX@users.noreply.github.com>
Co-authored-by: PLUTOFX <110596339+PLUTOFX@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Jan 26, 2026

@copilot I got it. Then implement this fix and check this fix.

Implemented a fix to keep wasm pointer allocas from being promoted by mem2reg so values stay in linear memory for shadow-stack style GC, plus added a WebAssembly codegen test. Commit: 2dcd536. No UI changes to screenshot.

Copilot AI changed the title Investigate wasm shadow stack sync regression under -O2 Preserve wasm pointer allocas for shadow stack GC under -O2 Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants