x64 backend: fix to_amode with constant address (no registers). (#4239)
If an address expression is given to `to_amode` that is completely constant (no registers at all), then it will produce an `Amode` that has the resulting constant as an offset, and `(invalid_reg)` as the base. This is a side-effect of the way we build up the amode step-by-step -- we're waiting to see a register and plug it into the base field. If we never get a reg though, we need to generate a constant zero into a register and use that as the base. This PR adds a `finalize_amode` helper to do just that. Fixes #4234.
This commit is contained in:
@@ -981,7 +981,16 @@
|
|||||||
|
|
||||||
;; Finally, define the toplevel `to_amode`.
|
;; Finally, define the toplevel `to_amode`.
|
||||||
(rule (to_amode flags base offset)
|
(rule (to_amode flags base offset)
|
||||||
(amode_add (amode_initial flags offset) base))
|
(amode_finalize (amode_add (amode_initial flags offset) base)))
|
||||||
|
|
||||||
|
;; If an amode has no registers at all and only offsets (a constant
|
||||||
|
;; value), we need to "finalize" it by sticking in a zero'd reg in
|
||||||
|
;; place of the (invalid_reg) produced by (amode_initial).
|
||||||
|
(decl amode_finalize (Amode) Amode)
|
||||||
|
(rule 1 (amode_finalize (Amode.ImmReg off (invalid_reg) flags))
|
||||||
|
(Amode.ImmReg off (imm $I64 0) flags))
|
||||||
|
(rule 0 (amode_finalize amode)
|
||||||
|
amode)
|
||||||
|
|
||||||
;; Offsetting an Amode. Used when we need to do consecutive
|
;; Offsetting an Amode. Used when we need to do consecutive
|
||||||
;; loads/stores to adjacent addresses.
|
;; loads/stores to adjacent addresses.
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
;; See https://github.com/bytecodealliance/wasmtime/issues/4234.
|
||||||
|
;;
|
||||||
|
;; We just want to verify that this can be compiled successfully.
|
||||||
|
|
||||||
|
test compile
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
function u0:31() -> i32, i32 system_v {
|
||||||
|
block0:
|
||||||
|
v0 = iconst.i64 0
|
||||||
|
v1 = iconst.i32 0
|
||||||
|
v2 = iconst.i32 0
|
||||||
|
@0004 v28 = bconst.b1 false
|
||||||
|
@0005 brnz v28, block25
|
||||||
|
jump block1
|
||||||
|
|
||||||
|
block1:
|
||||||
|
@0005 trap unreachable
|
||||||
|
|
||||||
|
block25:
|
||||||
|
@0035 v85 = atomic_cas.i32 v0, v1, v2
|
||||||
|
@0036 trap user0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user