FEXCore: Fixes bug in vector ZextAndMaskingElimination pass

With the previous RCLSE pass optimization that fixes store->load
forwarding, this pass started optimizing harder.

This hit a bug with this vmov removal that previously didn't get hit.
In particular this would eliminate vmov IR operations even if they were
zero extending a vector.
Since we have dramatically cleaned up the amount of vmov IR operations
we are generating, remove this optimization entirely. In the games I
tested, the only game that hit this "optimization" was Ender Lilies and
it started generating broken code for the single block of instructions
that did.

Adds a unit test for this case just in-case it comes back in the future
for some reason.

Fixes an issue where Ender Lilies would flash the screen to black every
time an enemy hit the player character.
This commit is contained in:
Ryan Houdek committed 2023-10-21 21:21:14 -07:00
1 parent 8f8f37684a
commit 06ef012fb2
2 files changed
+24 -21

No files matched your search

@@ -494,27 +494,6 @@ bool ConstProp::ZextAndMaskingElimination(IREmitter *IREmit, const IRListView& C
break;
}
case OP_VFADD:
case OP_VFSUB:
case OP_VFMUL:
case OP_VFDIV:
case OP_FCMP: {
auto flopSize = IROp->Size;
for (int i = 0; i < IR::GetArgs(IROp->Op); i++) {
auto argHeader = IREmit->GetOpHeader(IROp->Args[i]);
if (argHeader->Op == OP_VMOV) {
auto source = argHeader->Args[0];
auto sourceHeader = IREmit->GetOpHeader(source);
if (sourceHeader->Size >= flopSize) {
IREmit->ReplaceNodeArgument(CodeNode, i, IREmit->UnwrapNode(source));
//printf("VMOV bypassed\n");
}
}
}
break;
}
case OP_VMOV: {
// elim from load mem
auto source = IROp->Args[0];
@@ -0,0 +1,24 @@
%ifdef CONFIG
{
"RegData": {
"XMM0": ["0x408000003f800000", "0"],
"XMM1": ["0x400000003f800000", "0x4080000040400000"]
}
}
%endif
; This bug was encountered in Ender Lilies, when an enemy attacked the player character there was a chance for a black screen flash.
; This was due to a bug in FEX's `ZextAndMaskingElimination` pass which tries to remove useless vmov IR operations.
; It incorrectly removed vmov IR operations that were explicitly zero extending vectors.
; This vmov IR operation was generated by the movq instruction because the upper bits must be zero.
; When vmov was removed, it would no longer zero the upper 64-bits, which left data in the register.
; This results in a bad calculation.
movaps xmm1, [rel .data_1]
movq xmm0, xmm1
mulps xmm0, [rel .data_1]
hlt
align 16
.data_1:
dd 1.0, 2.0, 3.0, 4.0