Files
wasmtime/cranelift/filetests/filetests/isa/s390x/atomic_store-little.clif
Ulrich Weigand a916788ab4 Fix mis-aligned access issues with s390x (#4702)
This fixes two problems: minimum symbol alignment for the LARL
instruction, and alignment requirements for LRL/LGRL etc.

The first problem is that the LARL instruction used to load a
symbol address (PC relative) requires that the target symbol
is at least 2-byte aligned.  This is always guaranteed for code
symbols (all instructions must be 2-aligned anyway), but not
necessarily for data symbols.

Other s390x compilers fix this problem by ensuring that all
global symbols are always emitted with a minimum 2-byte
alignment.  This patch introduces an equivalent mechanism
for cranelift:
- Add a symbol_alignment routine to TargetIsa, similar to the
  existing code_section_alignment routine.
- Respect symbol_alignment as minimum alignment for all symbols
  emitted in the object backend (code and data).

The second problem is that PC-relative instructions that
directly *access* data (like LRL/LGRL, STRL/STGRL etc.)
not only have the 2-byte requirement like LARL, but actually
require that their memory operand is *naturally* aligned
(i.e. alignment is at least the size of the access).

This property (natural alignment for memory accesses) is
supposed to be provided by the "aligned" flag in MemFlags;
however, this is not implemented correctly at the moment.

To fix this, this patch:
- Only emits PC-relative memory access instructions if the
  "aligned" flag is set in the associated MemFlags.
- Fixes a bug in emit_small_memory_copy and emit_small_memset
  which currently set the aligned flag unconditionally, ignoring
  the actual alignment info passed by their caller.

Tested with wasmtime and cg_clif.
2022-08-16 12:39:42 -07:00

137 lines
2.2 KiB
Plaintext

test compile precise-output
target s390x
function %atomic_store_i64(i64, i64) {
block0(v0: i64, v1: i64):
atomic_store.i64 little v0, v1
return
}
; block0:
; strvg %r2, 0(%r3)
; bcr 14, 0
; br %r14
function %atomic_store_i64_sym(i64) {
gv0 = symbol colocated %sym
block0(v0: i64):
v1 = symbol_value.i64 gv0
atomic_store.i64 aligned little v0, v1
return
}
; block0:
; larl %r1, %sym + 0 ; strvg %r2, 0(%r1)
; bcr 14, 0
; br %r14
function %atomic_store_imm_i64(i64) {
block0(v0: i64):
v1 = iconst.i64 12345
atomic_store.i64 little v1, v0
return
}
; block0:
; lghi %r4, 12345
; strvg %r4, 0(%r2)
; bcr 14, 0
; br %r14
function %atomic_store_i32(i32, i64) {
block0(v0: i32, v1: i64):
atomic_store.i32 little v0, v1
return
}
; block0:
; strv %r2, 0(%r3)
; bcr 14, 0
; br %r14
function %atomic_store_i32_sym(i32) {
gv0 = symbol colocated %sym
block0(v0: i32):
v1 = symbol_value.i64 gv0
atomic_store.i32 aligned little v0, v1
return
}
; block0:
; larl %r1, %sym + 0 ; strv %r2, 0(%r1)
; bcr 14, 0
; br %r14
function %atomic_store_imm_i32(i64) {
block0(v0: i64):
v1 = iconst.i32 12345
atomic_store.i32 little v1, v0
return
}
; block0:
; lhi %r4, 12345
; strv %r4, 0(%r2)
; bcr 14, 0
; br %r14
function %atomic_store_i16(i16, i64) {
block0(v0: i16, v1: i64):
atomic_store.i16 little v0, v1
return
}
; block0:
; strvh %r2, 0(%r3)
; bcr 14, 0
; br %r14
function %atomic_store_i16_sym(i16) {
gv0 = symbol colocated %sym
block0(v0: i16):
v1 = symbol_value.i64 gv0
atomic_store.i16 aligned little v0, v1
return
}
; block0:
; larl %r1, %sym + 0 ; strvh %r2, 0(%r1)
; bcr 14, 0
; br %r14
function %atomic_store_imm_i16(i64) {
block0(v0: i64):
v1 = iconst.i16 12345
atomic_store.i16 little v1, v0
return
}
; block0:
; mvhhi 0(%r2), 14640
; bcr 14, 0
; br %r14
function %atomic_store_i8(i8, i64) {
block0(v0: i8, v1: i64):
atomic_store.i8 little v0, v1
return
}
; block0:
; stc %r2, 0(%r3)
; bcr 14, 0
; br %r14
function %atomic_store_imm_i8(i64) {
block0(v0: i64):
v1 = iconst.i8 123
atomic_store.i8 little v1, v0
return
}
; block0:
; mvi 0(%r2), 123
; bcr 14, 0
; br %r14