Skip to content

[WebAssembly] Incorrect lowering of extending and mismatching loads for addrspace(1) globals #155880

@QuantumSegfault

Description

@QuantumSegfault

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions