-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Open
Description
LLVM version 20.1.8
When performing extending loads on addrspace(1) globals (i.e. what become WASM globals), the WASM codegen incorrectly lowers certain loads from them.
For extending loads, it incorrectly produces the optimized linear memory extending loads (e.g. i32.load8_u) instead of global.get + and
For mismatching loads (load i32 from i64 global or i64 from i32 global), it generates global.get, but fails to promote/demote the result to the correct type, resulting in an invalid WASM binary.
Reproduction:
target triple = "wasm32-unknown-unknown"
declare void @put_i32(i32)
declare void @put_i64(i64)
@globalI32 = local_unnamed_addr addrspace(1) global i32 undef
@globalI64 = local_unnamed_addr addrspace(1) global i64 undef
define void @myFunc() unnamed_addr {
%loadi32 = load i32, ptr addrspace(1) @globalI32
%loadi32.trunc = trunc i32 %loadi32 to i8
%loadi32.zext = zext i8 %loadi32.trunc to i32
call void @put_i32(i32 %loadi32.zext)
%loadi64fromi64 = load i32, ptr addrspace(1) @globalI64
call void @put_i32(i32 %loadi64fromi64)
%loadi64fromi32 = load i64, ptr addrspace(1) @globalI32
call void @put_i64(i64 %loadi64fromi32)
ret void
}
Running it through llc
(.ll file, no additional switches) yields
.file "test.ll"
.functype put_i32 (i32) -> ()
.functype put_i64 (i64) -> ()
.functype myFunc () -> ()
.section .text.myFunc,"",@
.globl myFunc # -- Begin function myFunc
.type myFunc,@function
myFunc: # @myFunc
.functype myFunc () -> ()
# %bb.0:
i32.const 0
i32.load8_u globalI32
call put_i32
global.get globalI64
call put_i32
global.get globalI32
call put_i64
# fallthrough-return
end_function
# -- End function
.globaltype globalI32, i32
.globl globalI32
globalI32:
.globaltype globalI64, i64
.globl globalI64
globalI64:
.section .custom_section.target_features,"",@
However, myFunc
should have been
myFunc: # @myFunc
.functype myFunc () -> ()
# %bb.0:
global.get globalI32
i32.const 255
i32.and
call put_i32
global.get globalI64
i32.wrap_i64
call put_i32
global.get globalI32
i64.extend_i32_u
call put_i64
# fallthrough-return
end_function