Skip to content

[WebAssembly] Split separate component LiveIntervals for TEEs #131561

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,11 @@ static unsigned getTeeOpcode(const TargetRegisterClass *RC) {

// Shrink LI to its uses, cleaning up LI.
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS) {
if (LIS.shrinkToUses(&LI)) {
SmallVector<LiveInterval *, 4> SplitLIs;
LIS.splitSeparateComponents(LI, SplitLIs);
}
LIS.shrinkToUses(&LI);
// In case the register's live interval now has multiple unconnected
// components, split them into multiple registers.
SmallVector<LiveInterval *, 4> SplitLIs;
LIS.splitSeparateComponents(LI, SplitLIs);
}

/// A single-use def in the same block with no intervening memory or register
Expand Down
41 changes: 41 additions & 0 deletions llvm/test/CodeGen/WebAssembly/tee-live-intervals.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-reg-stackify -verify-machineinstrs %s -o -

# TEE generation in RegStackify can create virtual registers with LiveIntervals
# with multiple disconnected segments, which is invalid in MachineVerifier. In
# this test, '%0 = CALL @foo' will become a CALL and a TEE, which creates
# unconnected split segments. This should be later split into multiple
# registers. This test should not crash with -verify-machineinstrs, which checks
# whether all segments within a register is connected. See ??? for the detailed
# explanation.

--- |
target triple = "wasm32-unknown-unknown"

declare ptr @foo(ptr returned)
define void @tee_live_intervals_test() {
ret void
}
...
---
name: tee_live_intervals_test
liveins:
- { reg: '$arguments' }
tracksRegLiveness: true
body: |
bb.0:
liveins: $arguments
successors: %bb.1, %bb.2
%0:i32 = ARGUMENT_i32 0, implicit $arguments
%1:i32 = CONST_I32 0, implicit-def dead $arguments
BR_IF %bb.2, %1:i32, implicit-def dead $arguments

bb.1:
; predecessors: %bb.0
%0:i32 = CALL @foo, %0:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
STORE8_I32_A32 0, 0, %0:i32, %1:i32, implicit-def dead $arguments
RETURN %0:i32, implicit-def dead $arguments

bb.2:
; predecessors: %bb.0
%2:i32 = CONST_I32 0, implicit-def dead $arguments
RETURN %2:i32, implicit-def dead $arguments