Compare commits

...
Author SHA1 Message Date
Ryan Houdek 93c428ae53 Docs: Update for release FEX-2508.1 2025-08-05 19:51:54 -07:00
Alyssa Rosenzweig 5836309525 unittests: add blake3 test
this provokes RA spilling and hit an assertion fail on main.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-08-05 19:50:53 -07:00
Alyssa Rosenzweig 43092ce48b RegisterAllocationPass: fix SRA spilling corner
I hate this.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-08-05 19:50:48 -07:00
Alyssa Rosenzweig e5d51a20b2 RegisterAllocationPass: simplify next-use logic
I doubt this will fix the regression but it might make it easier to identify.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-08-05 19:50:43 -07:00
3 changed files with 102 additions and 49 deletions

No files matched your search

@@ -149,8 +149,20 @@ private:
bool HasSource(IROp_Header* I, PhysicalRegister Reg) {
for (auto s = 0; s < IR::GetRAArgs(I->Op); ++s) {
if (I->Args[s].IsImmediate() && PhysicalRegister(I->Args[s]) == Reg) {
return true;
if (I->Args[s].IsImmediate()) {
// When spilling for a destination, we'll see register sources
if (PhysicalRegister(I->Args[s]) == Reg) {
return true;
}
} else {
// When spilling for SRA correctness, we'll see SSA sources. This is
// pretty obscure.
auto V = I->Args[s];
V.ClearKill();
if (IsValidArg(V) && SSAToReg[V.ID().Value] == Reg) {
return true;
}
}
}
@@ -230,11 +242,11 @@ private:
const uint8_t NumArgs = IR::GetRAArgs(IROp->Op);
for (int i = NumArgs - 1; i >= 0; --i) {
auto& Arg = IROp->Args[i];
Arg.ClearKill();
auto V = IROp->Args[i];
V.ClearKill();
if (!Arg.IsInvalid()) {
const uint32_t Index = Arg.ID().Value;
if (IsValidArg(V)) {
const uint32_t Index = V.ID().Value;
SourcesNextUses.push_back(NextUses[Index]);
NextUses[Index] = IP;
@@ -684,13 +696,22 @@ void ConstrainedRAPass::Run(IREmitter* IREmit_) {
//
// This happens before freeing killed sources, since we need all sources in
// the register file simultaneously.
//
// Also update next-use info, again only relevant if we've spilled.
if (AnySpilledBeforeThisInstruction) {
for (auto s = 0; s < IR::GetRAArgs(IROp->Op); ++s) {
if (!IsValidArg(IROp->Args[s])) {
auto V = IROp->Args[s];
V.ClearKill();
if (!IsValidArg(V)) {
continue;
}
Ref Old = IR->GetNode(IROp->Args[s]);
Ref Old = IR->GetNode(V);
SourceIndex--;
LOGMAN_THROW_A_FMT(SourceIndex >= 0, "Consistent source count");
NextUses[V.ID().Value] = SourcesNextUses[SourceIndex];
if (!IsInRegisterFile(Old)) {
IREmit->SetWriteCursorBefore(CodeNode);
@@ -702,50 +723,26 @@ void ConstrainedRAPass::Run(IREmitter* IREmit_) {
RemapReg(Old, PhysicalRegister(Fill));
}
}
}
for (auto s = 0; s < IR::GetRAArgs(IROp->Op); ++s) {
if (IROp->Args[s].IsInvalid()) {
continue;
}
Ref Node = IR->GetNode(IROp->Args[s]);
auto ID = IR->GetID(Node).Value;
auto Reg = SSAToReg[ID];
SourceIndex--;
LOGMAN_THROW_A_FMT(SourceIndex >= 0, "Consistent source count");
if (!Reg.IsInvalid()) {
IROp->Args[s].SetImmediate(Reg.Raw);
if (!SourcesNextUses[SourceIndex]) {
LOGMAN_THROW_A_FMT(IsInRegisterFile(Node), "sources in file");
FreeReg(Reg);
}
}
NextUses[ID] = SourcesNextUses[SourceIndex];
for (auto s = 0; s < IR::GetRAArgs(IROp->Op); ++s) {
if (IROp->Args[s].IsInvalid()) {
continue;
}
} else {
for (auto s = 0; s < IR::GetRAArgs(IROp->Op); ++s) {
if (IROp->Args[s].IsInvalid()) {
continue;
bool Kill = IROp->Args[s].HasKill();
IROp->Args[s].ClearKill();
Ref Node = IR->GetNode(IROp->Args[s]);
auto ID = IR->GetID(Node).Value;
auto Reg = SSAToReg[ID];
if (!Reg.IsInvalid()) {
if (Kill) {
LOGMAN_THROW_A_FMT(IsInRegisterFile(Node), "sources in file");
FreeReg(Reg);
}
bool Kill = IROp->Args[s].HasKill();
IROp->Args[s].ClearKill();
Ref Node = IR->GetNode(IROp->Args[s]);
auto ID = IR->GetID(Node).Value;
auto Reg = SSAToReg[ID];
if (!Reg.IsInvalid()) {
if (Kill) {
LOGMAN_THROW_A_FMT(IsInRegisterFile(Node), "sources in file");
FreeReg(Reg);
}
IROp->Args[s].SetImmediate(Reg.Raw);
}
IROp->Args[s].SetImmediate(Reg.Raw);
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
# FEX-2508
# FEX-2508.1
## FEXCore
See [FEXCore/Readme.md](../FEXCore/Readme.md) for more details
+56
View File
@@ -0,0 +1,56 @@
%ifdef CONFIG
{
}
%endif
vblendps ymm3, ymm12, ymm9, 0xcc
vperm2f128 ymm12, ymm1, ymm2, 0x20
vmovups [rel .data_result + 0], ymm12
vunpckhps ymm14, ymm4, ymm5
vblendps ymm4, ymm8, ymm0, 0xcc
vunpckhps ymm15, ymm6, ymm7
vperm2f128 ymm7, ymm3, ymm4, 0x20
vmovups [rel .data_result + 32], ymm7
vshufps ymm5, ymm10, ymm13, 0x4e
vblendps ymm6, ymm5, ymm13, 0xcc
vshufps ymm13, ymm14, ymm15, 0x4e
vblendps ymm10, ymm10, ymm5, 0xcc
vblendps ymm14, ymm14, ymm13, 0xcc
vperm2f128 ymm8, ymm10, ymm14, 0x20
vmovups [rel .data_result + (32 * 2)], ymm8
vblendps ymm15, ymm13, ymm15, 0xcc
vperm2f128 ymm13, ymm6, ymm15, 0x20
vmovups [rel .data_result + (32 * 3)], ymm13
vperm2f128 ymm9, ymm1, ymm2, 0x31
vperm2f128 ymm11, ymm3, ymm4, 0x31
vmovups [rel .data_result + (32 * 4)], ymm9
vperm2f128 ymm14, ymm10, ymm14, 0x31
vperm2f128 ymm15, ymm6, ymm15, 0x31
vmovups [rel .data_result + (32 * 5)], ymm11
vmovups [rel .data_result + (32 * 6)], ymm14
vmovups [rel .data_result + (32 * 7)], ymm15
vmovdqa ymm0, [rel .data_stack + (32 * 0)]
vpaddd ymm1, ymm0, [rel .data_stack + (32 * 1)]
vmovdqa [rel .data_stack + (32 * 1)], ymm1
vpxor ymm0, ymm0, [rel .data]
vpxor ymm2, ymm1, [rel .data + 32]
hlt
align 4096
.data:
dq 0, 0, 0, 0, 0, 0
dq 0, 0, 0, 0, 0, 0
.data_stack:
dq 0, 0, 0, 0
dq 0, 0, 0, 0
.data_result:
dq 0, 0, 0, 0
dq 0, 0, 0, 0
dq 0, 0, 0, 0
dq 0, 0, 0, 0
dq 0, 0, 0, 0
dq 0, 0, 0, 0
dq 0, 0, 0, 0