RegisterAllocationPass: optimize long divsion

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig committed 2025-06-24 16:10:29 -04:00
1 parent 3f3b6ad337
commit cda15ce9ea
2 files changed
+27

No files matched your search

@@ -382,6 +382,19 @@ inline bool KillMove(IROp_Header* LastOp, IROp_Header* IROp, Ref LastNode, Ref C
return LastOp->Op == OP_STOREREGISTER;
}
inline bool IsSignext(const IROp_Header* IROp, OrderedNodeWrapper Src, OpSize Size) {
if (IROp->Op == OP_SBFE) {
auto Sbfe = IROp->C<IR::IROp_Sbfe>();
return Sbfe->Width == 1 && Sbfe->lsb == (IR::OpSizeAsBits(Size) - 1) && Sbfe->Src == Src;
} else {
return false;
}
}
inline bool IsZero(const IROp_Header* IROp) {
return IROp->Op == OP_CONSTANT && IROp->C<IROp_Constant>()->Constant == 0;
}
bool ConstrainedRAPass::TryPostRAMerge(Ref LastNode, Ref CodeNode, IROp_Header* IROp) {
auto LastOp = IR->GetOp<IROp_Header>(LastNode);
@@ -408,6 +421,15 @@ bool ConstrainedRAPass::TryPostRAMerge(Ref LastNode, Ref CodeNode, IROp_Header*
IREmit->RemovePostRA(CodeNode);
return true;
}
} else if ((IROp->Op == OP_DIV || IROp->Op == OP_UDIV) && IROp->Size >= OpSize::i32Bit) {
// If Upper came from a sign/zero extension, we only need a 64-bit division.
auto Op = IROp->CW<IR::IROp_Div>();
if (!Op->Upper.IsInvalid() && PhysicalRegister(Op->Upper) == PhysicalRegister(LastNode)) {
if (IROp->Op == OP_DIV ? IsSignext(LastOp, Op->Lower, IROp->Size) : IsZero(LastOp)) {
Op->Upper.SetInvalid();
return PhysicalRegister(LastNode) == PhysicalRegister(Op->OutRemainder);
}
}
}
// Merge moves that are immediately consumed.