x64 backend: fix cmpxchg (don't return RealReg as result). (#4243)
The current lowering helper for `cmpxchg` returns the literal RealReg `rax` as its result. However, this breaks a number of invariants, and eventually causes a regalloc panic if used as a blockparam arg (pinned vregs cannot be used in this way). In general we have to return regular vregs, not a RealReg, as results of instructions during lowering. However #4223 added a helper for `x64_cmpxchg` that returns a literal `rax`. Fortunately we can do the right thing here by just giving a fresh vreg to the instruction; the regalloc constraints mean that this vreg is constrained to `rax` at the instruction (at its def/late point), so the generator of the instruction need not worry about `rax` here.
This commit is contained in:
@@ -1067,11 +1067,6 @@
|
||||
(decl encode_fcmp_imm (FcmpImm) u8)
|
||||
(extern constructor encode_fcmp_imm encode_fcmp_imm)
|
||||
|
||||
;;;; Registers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(decl rax () WritableGpr)
|
||||
(extern constructor rax rax)
|
||||
|
||||
;;;; Newtypes for Different Register Classes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(type Gpr (primitive Gpr))
|
||||
@@ -2906,8 +2901,9 @@
|
||||
|
||||
(decl x64_cmpxchg (Type Gpr Gpr SyntheticAmode) Gpr)
|
||||
(rule (x64_cmpxchg ty expected replacement addr)
|
||||
(let ((_ Unit (emit (MInst.LockCmpxchg ty replacement expected addr (rax)))))
|
||||
(rax)))
|
||||
(let ((dst WritableGpr (temp_writable_gpr))
|
||||
(_ Unit (emit (MInst.LockCmpxchg ty replacement expected addr dst))))
|
||||
dst))
|
||||
|
||||
;;;; Automatic conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
@@ -547,12 +547,6 @@ where
|
||||
fn zero_offset(&mut self) -> Offset32 {
|
||||
Offset32::new(0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rax(&mut self) -> WritableGpr {
|
||||
let gpr = Gpr::new(regs::rax()).unwrap();
|
||||
WritableGpr::from_reg(gpr)
|
||||
}
|
||||
}
|
||||
|
||||
// Since x64 doesn't have 8x16 shifts and we must use a 16x8 shift instead, we
|
||||
|
||||
Reference in New Issue
Block a user