[wasm-simd][liftoff] Fix i64x2.shr_s overwriting scratch

x64's implementation of i64x2.shr_s was overwriting the scratch
register. kScratchRegister is used to hold the extracted lane of the
SIMD register, but in certain cases [0], is also used to back up the
value of rcx. When this happens, the supposed backed-up rcx was
overwritten (definitely) by each extract lane, so we end up restoring
an incorrect value of rcx, leading to an eventual crash in certain
benchmarks, when this extracted lane was used as a memory operand (see
linked bugs).

[0] when register holding the shift value is not rcx, which sarq_cl
relies on

Bug: v8:10752
Bug: chromium:1111522
Change-Id: Iaf3264e16f94e78bad4290783757f0b722d40411
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2334354
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69208}
This commit is contained in:
Ng Zhi An 2020-08-03 10:46:00 -07:00 committed by Commit Bot
parent 799421d55b
commit d5c58d9d29

View File

@ -2177,10 +2177,11 @@ void EmitI64x2ShrS(LiftoffAssembler* assm, LiftoffRegister dst,
LiftoffRegister lhs, ShiftOperand rhs,
bool shift_is_rcx = false) {
bool restore_rcx = false;
Register backup = kScratchRegister2;
if (!shift_is_rcx) {
if (assm->cache_state()->is_used(LiftoffRegister(rcx))) {
restore_rcx = true;
assm->movq(kScratchRegister, rcx);
assm->movq(backup, rcx);
}
assm->movl(rcx, rhs);
}
@ -2197,7 +2198,7 @@ void EmitI64x2ShrS(LiftoffAssembler* assm, LiftoffRegister dst,
// restore rcx.
if (restore_rcx) {
assm->movq(rcx, kScratchRegister);
assm->movq(rcx, backup);
}
}