Fix XLS spill slot alignment for SIMD registers
If XLS spills a SIMD register, we need the spill slot to be 16-byte aligned. Also the checkShuffle() assertions weren't quite right when spilling/loading SIMD registers. Reviewed By: @jdelong Differential Revision: D1144168
Esse commit está contido em:
@@ -275,19 +275,20 @@ bool checkShuffle(const IRInstruction& inst, const RegAllocInfo& regs) {
|
||||
assert(n == inst.extra<Shuffle>()->size);
|
||||
RegSet destRegs;
|
||||
std::bitset<NumPreAllocatedSpillLocs> destSlots;
|
||||
std::bitset<NumPreAllocatedSpillLocs> srcSlots;
|
||||
for (uint32_t i = 0; i < n; ++i) {
|
||||
DEBUG_ONLY auto& rs = regs[inst][inst.src(i)];
|
||||
DEBUG_ONLY auto& rd = inst.extra<Shuffle>()->dests[i];
|
||||
if (rd.numAllocated() == 0) continue; // dest was unused; ignore.
|
||||
// rs could have less assigned registers/slots than rd, in these cases:
|
||||
// - when rs is empty, because the source is a constant.
|
||||
// - when rd needs 2 and rs needs 0 or 1, and the source is either constant
|
||||
// or hasKnownType() without being constant, and the dest type is more
|
||||
// general than the src type due to a control-flow join.
|
||||
assert(rs.numAllocated() <= rd.numAllocated());
|
||||
assert(!rs.spilled() || !rd.spilled());
|
||||
assert(rs.isFullSIMD() == rd.isFullSIMD());
|
||||
if (rd.spilled()) {
|
||||
assert(!rs.spilled()); // no mem-mem copies
|
||||
} else {
|
||||
// rs could have less assigned registers/slots than rd, in these cases:
|
||||
// - when rs is empty, because the source is a constant.
|
||||
// - when rs has 1 register because it's untagged but rd needs 2 because
|
||||
// it's a more general (tagged) type, because of a phi.
|
||||
assert(rs.numWords() <= rd.numWords());
|
||||
assert(rs.spilled() || rs.isFullSIMD() == rd.isFullSIMD());
|
||||
}
|
||||
for (int j = 0; j < rd.numAllocated(); ++j) {
|
||||
if (rd.spilled()) {
|
||||
assert(!destSlots.test(rd.slot(j)));
|
||||
@@ -297,8 +298,6 @@ bool checkShuffle(const IRInstruction& inst, const RegAllocInfo& regs) {
|
||||
destRegs.add(rd.reg(j));
|
||||
}
|
||||
}
|
||||
// don't let any spill slot appear on both sides of the copy.
|
||||
assert((srcSlots & destSlots).none());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
}
|
||||
|
||||
/*
|
||||
* return true if the offset of this index is 16-byte aligned
|
||||
* return true if the offset of this slot is 16-byte aligned
|
||||
*/
|
||||
static bool isAligned(uint32_t slot) {
|
||||
return slot % 2 == 1;
|
||||
|
||||
@@ -583,8 +583,13 @@ void XLS::spill(Interval* ivl) {
|
||||
assert(ivl->need == 1 || ivl->need == 2);
|
||||
auto leader = ivl->leader();
|
||||
if (!leader->spill.spilled()) {
|
||||
leader->spill.setSlot(0, m_nextSpill++);
|
||||
if (ivl->need == 2) leader->spill.setSlot(1, m_nextSpill++);
|
||||
if (ivl->need == 1) {
|
||||
leader->spill.setSlot(0, m_nextSpill++);
|
||||
} else {
|
||||
if (!PhysLoc::isAligned(m_nextSpill)) m_nextSpill++;
|
||||
leader->spill.setSlot(0, m_nextSpill++);
|
||||
leader->spill.setSlot(1, m_nextSpill++);
|
||||
}
|
||||
if (m_nextSpill > NumPreAllocatedSpillLocs) {
|
||||
PUNT(LinearScan_TooManySpills);
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário