Zero newly allocated registers whose immediate use depends on content not being NaN

An intermittent failure during SIMD spectests is described in #2432. This patch
corrects code written in a way that assumes comparing fp equality of a register with itself will
always return true. This is not true when the register value is NaN as NaN. In this case, and
with all ordered comparisons involving NaN, the comparisons will always return false.
This patch corrects that assumption for SIMD Fabs and Fneg which seem to be the only
instructions generating the failure with #2432.
This commit is contained in:
Johnnie Birch
2021-01-13 16:50:28 -08:00
parent 2b2f369bbb
commit d17815a239

View File

@@ -3138,8 +3138,11 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
ctx.emit(Inst::gen_move(dst, src, output_ty)); ctx.emit(Inst::gen_move(dst, src, output_ty));
// Generate an all 1s constant in an XMM register. This uses CMPPS but could // Generate an all 1s constant in an XMM register. This uses CMPPS but could
// have used CMPPD with the same effect. // have used CMPPD with the same effect. Note, we zero the temp we allocate
// because if not, there is a chance that the register we use could be initialized
// with NaN .. in which case the CMPPS would fail since NaN != NaN.
let tmp = ctx.alloc_tmp(output_ty).only_reg().unwrap(); let tmp = ctx.alloc_tmp(output_ty).only_reg().unwrap();
ctx.emit(Inst::xmm_rm_r(SseOpcode::Xorps, RegMem::from(tmp), tmp));
let cond = FcmpImm::from(FloatCC::Equal); let cond = FcmpImm::from(FloatCC::Equal);
let cmpps = Inst::xmm_rm_r_imm( let cmpps = Inst::xmm_rm_r_imm(
SseOpcode::Cmpps, SseOpcode::Cmpps,