forked from OSchip/llvm-project
[Hexagon] Fix vector spill expansion to use proper alignment
1. Add pseudos PS_vloadrv_ai and PS_vstorerv_ai: those are now used for single vector registers in loadRegFromStackSlot (and store...). 2. Remove pseudos PS_vloadrwu_ai and PS_vstorerwu_ai. The alignment is now checked when expanding spill pseudos (both in frame lowering and in expand-post-ra-pseudos), and a proper instruction is generated. 3. Update MachineMemOperands when dealigning vector spill slots. 4. Return vector predicate registers in getCallerSavedRegs.
This commit is contained in:
parent
e3eb10c541
commit
592dd45924
|
@ -36,6 +36,7 @@
|
|||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachinePostDominators.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
|
@ -1362,6 +1363,7 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
|
|||
if (!HasAlloca || !NeedsAlign)
|
||||
return;
|
||||
|
||||
SmallSet<int, 4> DealignSlots;
|
||||
unsigned LFS = MFI.getLocalFrameSize();
|
||||
for (int i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
|
||||
if (!MFI.isSpillSlotObjectIndex(i) || MFI.isDeadObjectIndex(i))
|
||||
|
@ -1373,6 +1375,7 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
|
|||
MFI.setObjectAlignment(i, 8);
|
||||
LFS = alignTo(LFS+S, A);
|
||||
MFI.mapLocalFrameObject(i, -static_cast<int64_t>(LFS));
|
||||
DealignSlots.insert(i);
|
||||
}
|
||||
|
||||
MFI.setLocalFrameSize(LFS);
|
||||
|
@ -1382,6 +1385,38 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
|
|||
MFI.setLocalFrameMaxAlign(Align(8));
|
||||
MFI.setUseLocalStackAllocationBlock(true);
|
||||
|
||||
// Go over all MachineMemOperands in the code, and change the ones that
|
||||
// refer to the dealigned stack slots to reflect the new alignment.
|
||||
if (!DealignSlots.empty()) {
|
||||
for (MachineBasicBlock &BB : MF) {
|
||||
for (MachineInstr &MI : BB) {
|
||||
bool KeepOld = true;
|
||||
ArrayRef<MachineMemOperand*> memops = MI.memoperands();
|
||||
SmallVector<MachineMemOperand*,1> new_memops;
|
||||
for (MachineMemOperand *MMO : memops) {
|
||||
auto *PV = MMO->getPseudoValue();
|
||||
if (auto *FS = dyn_cast_or_null<FixedStackPseudoSourceValue>(PV)) {
|
||||
int FI = FS->getFrameIndex();
|
||||
if (DealignSlots.count(FI)) {
|
||||
unsigned A = MFI.getObjectAlignment(FI);
|
||||
auto *NewMMO = MF.getMachineMemOperand(MMO->getPointerInfo(),
|
||||
MMO->getFlags(), MMO->getSize(), A,
|
||||
MMO->getAAInfo(), MMO->getRanges(),
|
||||
MMO->getSyncScopeID(), MMO->getOrdering(),
|
||||
MMO->getFailureOrdering());
|
||||
new_memops.push_back(NewMMO);
|
||||
KeepOld = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
new_memops.push_back(MMO);
|
||||
}
|
||||
if (!KeepOld)
|
||||
MI.setMemRefs(MF, new_memops);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the physical aligned-stack base address register.
|
||||
unsigned AP = 0;
|
||||
if (const MachineInstr *AI = getAlignaInstr(MF))
|
||||
|
@ -1749,16 +1784,21 @@ bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
|
|||
Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
|
||||
bool IsKill = MI->getOperand(2).isKill();
|
||||
int FI = MI->getOperand(0).getIndex();
|
||||
bool NeedsAligna = needsAligna(MF);
|
||||
|
||||
unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned HasAlign = MFI.getObjectAlignment(FI);
|
||||
unsigned StoreOpc;
|
||||
|
||||
auto UseAligned = [&] (unsigned NeedAlign, unsigned HasAlign) {
|
||||
return !NeedsAligna && (NeedAlign <= HasAlign);
|
||||
};
|
||||
|
||||
// Store low part.
|
||||
if (LPR.contains(SrcLo)) {
|
||||
StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
StoreOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
BuildMI(B, It, DL, HII.get(StoreOpc))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0)
|
||||
|
@ -1768,8 +1808,8 @@ bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
|
|||
|
||||
// Store high part.
|
||||
if (LPR.contains(SrcHi)) {
|
||||
StoreOpc = NeedAlign <= MinAlign(HasAlign, Size) ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
StoreOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
BuildMI(B, It, DL, HII.get(StoreOpc))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(Size)
|
||||
|
@ -1796,23 +1836,28 @@ bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B,
|
|||
Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
|
||||
Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
|
||||
int FI = MI->getOperand(1).getIndex();
|
||||
bool NeedsAligna = needsAligna(MF);
|
||||
|
||||
unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned HasAlign = MFI.getObjectAlignment(FI);
|
||||
unsigned LoadOpc;
|
||||
|
||||
auto UseAligned = [&] (unsigned NeedAlign, unsigned HasAlign) {
|
||||
return !NeedsAligna && (NeedAlign <= HasAlign);
|
||||
};
|
||||
|
||||
// Load low part.
|
||||
LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
LoadOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
BuildMI(B, It, DL, HII.get(LoadOpc), DstLo)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0)
|
||||
.cloneMemRefs(*MI);
|
||||
|
||||
// Load high part.
|
||||
LoadOpc = NeedAlign <= MinAlign(HasAlign, Size) ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
LoadOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
BuildMI(B, It, DL, HII.get(LoadOpc), DstHi)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(Size)
|
||||
|
@ -1831,6 +1876,7 @@ bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B,
|
|||
if (!MI->getOperand(0).isFI())
|
||||
return false;
|
||||
|
||||
bool NeedsAligna = needsAligna(MF);
|
||||
auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
Register SrcR = MI->getOperand(2).getReg();
|
||||
|
@ -1839,8 +1885,9 @@ bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B,
|
|||
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned HasAlign = MFI.getObjectAlignment(FI);
|
||||
unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
bool UseAligned = !NeedsAligna && (NeedAlign <= HasAlign);
|
||||
unsigned StoreOpc = UseAligned ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
BuildMI(B, It, DL, HII.get(StoreOpc))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0)
|
||||
|
@ -1860,6 +1907,7 @@ bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B,
|
|||
if (!MI->getOperand(1).isFI())
|
||||
return false;
|
||||
|
||||
bool NeedsAligna = needsAligna(MF);
|
||||
auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
Register DstR = MI->getOperand(0).getReg();
|
||||
|
@ -1867,8 +1915,9 @@ bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B,
|
|||
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned HasAlign = MFI.getObjectAlignment(FI);
|
||||
unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
bool UseAligned = !NeedsAligna && (NeedAlign <= HasAlign);
|
||||
unsigned LoadOpc = UseAligned ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
BuildMI(B, It, DL, HII.get(LoadOpc), DstR)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0)
|
||||
|
@ -1911,11 +1960,9 @@ bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
|
|||
Changed |= expandLoadVecPred(B, I, MRI, HII, NewRegs);
|
||||
break;
|
||||
case Hexagon::PS_vloadrw_ai:
|
||||
case Hexagon::PS_vloadrwu_ai:
|
||||
Changed |= expandLoadVec2(B, I, MRI, HII, NewRegs);
|
||||
break;
|
||||
case Hexagon::PS_vstorerw_ai:
|
||||
case Hexagon::PS_vstorerwu_ai:
|
||||
Changed |= expandStoreVec2(B, I, MRI, HII, NewRegs);
|
||||
break;
|
||||
}
|
||||
|
@ -1960,7 +2007,15 @@ void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|||
for (auto *RC : SpillRCs) {
|
||||
if (!needToReserveScavengingSpillSlots(MF, HRI, RC))
|
||||
continue;
|
||||
unsigned Num = RC == &Hexagon::IntRegsRegClass ? NumberScavengerSlots : 1;
|
||||
unsigned Num = 1;
|
||||
switch (RC->getID()) {
|
||||
case Hexagon::IntRegsRegClassID:
|
||||
Num = NumberScavengerSlots;
|
||||
break;
|
||||
case Hexagon::HvxQRRegClassID:
|
||||
Num = 2; // Vector predicate spills also need a vector register.
|
||||
break;
|
||||
}
|
||||
unsigned S = HRI.getSpillSize(*RC), A = HRI.getSpillAlignment(*RC);
|
||||
for (unsigned i = 0; i < Num; i++) {
|
||||
int NewFI = MFI.CreateSpillStackObject(S, A);
|
||||
|
|
|
@ -888,10 +888,7 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||
MachineFunction &MF = *MBB.getParent();
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
unsigned SlotAlign = MFI.getObjectAlignment(FI);
|
||||
unsigned RegAlign = TRI->getSpillAlignment(*RC);
|
||||
unsigned KillFlag = getKillRegState(isKill);
|
||||
bool HasAlloca = MFI.hasVarSizedObjects();
|
||||
const HexagonFrameLowering &HFI = *Subtarget.getFrameLowering();
|
||||
|
||||
MachineMemOperand *MMO = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
|
||||
|
@ -918,29 +915,13 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||
.addFrameIndex(FI).addImm(0)
|
||||
.addReg(SrcReg, KillFlag).addMemOperand(MMO);
|
||||
} else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
|
||||
// If there are variable-sized objects, spills will not be aligned.
|
||||
if (HasAlloca)
|
||||
SlotAlign = HFI.getStackAlignment();
|
||||
unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vS32Ub_ai
|
||||
: Hexagon::V6_vS32b_ai;
|
||||
MachineMemOperand *MMOA = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
|
||||
MFI.getObjectSize(FI), SlotAlign);
|
||||
BuildMI(MBB, I, DL, get(Opc))
|
||||
BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))
|
||||
.addFrameIndex(FI).addImm(0)
|
||||
.addReg(SrcReg, KillFlag).addMemOperand(MMOA);
|
||||
.addReg(SrcReg, KillFlag).addMemOperand(MMO);
|
||||
} else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
|
||||
// If there are variable-sized objects, spills will not be aligned.
|
||||
if (HasAlloca)
|
||||
SlotAlign = HFI.getStackAlignment();
|
||||
unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vstorerwu_ai
|
||||
: Hexagon::PS_vstorerw_ai;
|
||||
MachineMemOperand *MMOA = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
|
||||
MFI.getObjectSize(FI), SlotAlign);
|
||||
BuildMI(MBB, I, DL, get(Opc))
|
||||
BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))
|
||||
.addFrameIndex(FI).addImm(0)
|
||||
.addReg(SrcReg, KillFlag).addMemOperand(MMOA);
|
||||
.addReg(SrcReg, KillFlag).addMemOperand(MMO);
|
||||
} else {
|
||||
llvm_unreachable("Unimplemented");
|
||||
}
|
||||
|
@ -954,9 +935,6 @@ void HexagonInstrInfo::loadRegFromStackSlot(
|
|||
MachineFunction &MF = *MBB.getParent();
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
unsigned SlotAlign = MFI.getObjectAlignment(FI);
|
||||
unsigned RegAlign = TRI->getSpillAlignment(*RC);
|
||||
bool HasAlloca = MFI.hasVarSizedObjects();
|
||||
const HexagonFrameLowering &HFI = *Subtarget.getFrameLowering();
|
||||
|
||||
MachineMemOperand *MMO = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
|
||||
|
@ -978,27 +956,11 @@ void HexagonInstrInfo::loadRegFromStackSlot(
|
|||
BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
|
||||
} else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
|
||||
// If there are variable-sized objects, spills will not be aligned.
|
||||
if (HasAlloca)
|
||||
SlotAlign = HFI.getStackAlignment();
|
||||
unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vL32Ub_ai
|
||||
: Hexagon::V6_vL32b_ai;
|
||||
MachineMemOperand *MMOA = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
|
||||
MFI.getObjectSize(FI), SlotAlign);
|
||||
BuildMI(MBB, I, DL, get(Opc), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
|
||||
BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
|
||||
} else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
|
||||
// If there are variable-sized objects, spills will not be aligned.
|
||||
if (HasAlloca)
|
||||
SlotAlign = HFI.getStackAlignment();
|
||||
unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vloadrwu_ai
|
||||
: Hexagon::PS_vloadrw_ai;
|
||||
MachineMemOperand *MMOA = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
|
||||
MFI.getObjectSize(FI), SlotAlign);
|
||||
BuildMI(MBB, I, DL, get(Opc), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
|
||||
BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
|
||||
} else {
|
||||
llvm_unreachable("Can't store this register to stack slot");
|
||||
}
|
||||
|
@ -1040,6 +1002,15 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
|
|||
return true;
|
||||
};
|
||||
|
||||
auto UseAligned = [&] (const MachineInstr &MI, unsigned NeedAlign) {
|
||||
if (MI.memoperands().empty())
|
||||
return false;
|
||||
return all_of(MI.memoperands(),
|
||||
[NeedAlign] (const MachineMemOperand *MMO) {
|
||||
return NeedAlign <= MMO->getAlignment();
|
||||
});
|
||||
};
|
||||
|
||||
switch (Opc) {
|
||||
case TargetOpcode::COPY: {
|
||||
MachineOperand &MD = MI.getOperand(0);
|
||||
|
@ -1086,47 +1057,78 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
|
|||
MRI.clearKillFlags(SrcSubHi);
|
||||
return true;
|
||||
}
|
||||
case Hexagon::PS_vstorerw_ai:
|
||||
case Hexagon::PS_vstorerwu_ai: {
|
||||
bool Aligned = Opc == Hexagon::PS_vstorerw_ai;
|
||||
Register SrcReg = MI.getOperand(2).getReg();
|
||||
Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
|
||||
Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
|
||||
unsigned NewOpc = Aligned ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32Ub_ai;
|
||||
unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
|
||||
|
||||
MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpc))
|
||||
.add(MI.getOperand(0))
|
||||
.addImm(MI.getOperand(1).getImm())
|
||||
.addReg(SrcSubLo)
|
||||
.cloneMemRefs(MI);
|
||||
MI1New->getOperand(0).setIsKill(false);
|
||||
BuildMI(MBB, MI, DL, get(NewOpc))
|
||||
.add(MI.getOperand(0))
|
||||
// The Vectors are indexed in multiples of vector size.
|
||||
.addImm(MI.getOperand(1).getImm() + Offset)
|
||||
.addReg(SrcSubHi)
|
||||
case Hexagon::PS_vloadrv_ai: {
|
||||
Register DstReg = MI.getOperand(0).getReg();
|
||||
const MachineOperand &BaseOp = MI.getOperand(1);
|
||||
assert(BaseOp.getSubReg() == 0);
|
||||
int Offset = MI.getOperand(2).getImm();
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
|
||||
.addReg(BaseOp.getReg(), getRegState(BaseOp))
|
||||
.addImm(Offset)
|
||||
.cloneMemRefs(MI);
|
||||
MBB.erase(MI);
|
||||
return true;
|
||||
}
|
||||
case Hexagon::PS_vloadrw_ai:
|
||||
case Hexagon::PS_vloadrwu_ai: {
|
||||
bool Aligned = Opc == Hexagon::PS_vloadrw_ai;
|
||||
case Hexagon::PS_vloadrw_ai: {
|
||||
Register DstReg = MI.getOperand(0).getReg();
|
||||
unsigned NewOpc = Aligned ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32Ub_ai;
|
||||
unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
|
||||
|
||||
MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpc),
|
||||
HRI.getSubReg(DstReg, Hexagon::vsub_lo))
|
||||
.add(MI.getOperand(1))
|
||||
.addImm(MI.getOperand(2).getImm())
|
||||
.cloneMemRefs(MI);
|
||||
MI1New->getOperand(1).setIsKill(false);
|
||||
BuildMI(MBB, MI, DL, get(NewOpc), HRI.getSubReg(DstReg, Hexagon::vsub_hi))
|
||||
.add(MI.getOperand(1))
|
||||
// The Vectors are indexed in multiples of vector size.
|
||||
.addImm(MI.getOperand(2).getImm() + Offset)
|
||||
const MachineOperand &BaseOp = MI.getOperand(1);
|
||||
assert(BaseOp.getSubReg() == 0);
|
||||
int Offset = MI.getOperand(2).getImm();
|
||||
unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
|
||||
: Hexagon::V6_vL32Ub_ai;
|
||||
BuildMI(MBB, MI, DL, get(NewOpc),
|
||||
HRI.getSubReg(DstReg, Hexagon::vsub_lo))
|
||||
.addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
|
||||
.addImm(Offset)
|
||||
.cloneMemRefs(MI);
|
||||
BuildMI(MBB, MI, DL, get(NewOpc),
|
||||
HRI.getSubReg(DstReg, Hexagon::vsub_hi))
|
||||
.addReg(BaseOp.getReg(), getRegState(BaseOp))
|
||||
.addImm(Offset + VecOffset)
|
||||
.cloneMemRefs(MI);
|
||||
MBB.erase(MI);
|
||||
return true;
|
||||
}
|
||||
case Hexagon::PS_vstorerv_ai: {
|
||||
const MachineOperand &SrcOp = MI.getOperand(2);
|
||||
assert(SrcOp.getSubReg() == 0);
|
||||
const MachineOperand &BaseOp = MI.getOperand(0);
|
||||
assert(BaseOp.getSubReg() == 0);
|
||||
int Offset = MI.getOperand(1).getImm();
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
BuildMI(MBB, MI, DL, get(NewOpc))
|
||||
.addReg(BaseOp.getReg(), getRegState(BaseOp))
|
||||
.addImm(Offset)
|
||||
.addReg(SrcOp.getReg(), getRegState(SrcOp))
|
||||
.cloneMemRefs(MI);
|
||||
MBB.erase(MI);
|
||||
return true;
|
||||
}
|
||||
case Hexagon::PS_vstorerw_ai: {
|
||||
Register SrcReg = MI.getOperand(2).getReg();
|
||||
const MachineOperand &BaseOp = MI.getOperand(0);
|
||||
assert(BaseOp.getSubReg() == 0);
|
||||
int Offset = MI.getOperand(1).getImm();
|
||||
unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
|
||||
unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
|
||||
unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
|
||||
: Hexagon::V6_vS32Ub_ai;
|
||||
BuildMI(MBB, MI, DL, get(NewOpc))
|
||||
.addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
|
||||
.addImm(Offset)
|
||||
.addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))
|
||||
.cloneMemRefs(MI);
|
||||
BuildMI(MBB, MI, DL, get(NewOpc))
|
||||
.addReg(BaseOp.getReg(), getRegState(BaseOp))
|
||||
.addImm(Offset + VecOffset)
|
||||
.addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))
|
||||
.cloneMemRefs(MI);
|
||||
MBB.erase(MI);
|
||||
return true;
|
||||
|
@ -2683,9 +2685,11 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
|
|||
// misaligns with respect to load size.
|
||||
switch (Opcode) {
|
||||
case Hexagon::PS_vstorerq_ai:
|
||||
case Hexagon::PS_vstorerv_ai:
|
||||
case Hexagon::PS_vstorerw_ai:
|
||||
case Hexagon::PS_vstorerw_nt_ai:
|
||||
case Hexagon::PS_vloadrq_ai:
|
||||
case Hexagon::PS_vloadrv_ai:
|
||||
case Hexagon::PS_vloadrw_ai:
|
||||
case Hexagon::PS_vloadrw_nt_ai:
|
||||
case Hexagon::V6_vL32b_ai:
|
||||
|
|
|
@ -408,15 +408,17 @@ let isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
|
|||
// Vector store pseudos
|
||||
let Predicates = [HasV60,UseHVX], isPseudo = 1, isCodeGenOnly = 1,
|
||||
mayStore = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in
|
||||
class STrivv_template<RegisterClass RC, InstHexagon rootInst>
|
||||
class STriv_template<RegisterClass RC, InstHexagon rootInst>
|
||||
: InstHexagon<(outs), (ins IntRegs:$addr, s32_0Imm:$off, RC:$src),
|
||||
"", [], "", rootInst.Itinerary, rootInst.Type>;
|
||||
|
||||
def PS_vstorerw_ai: STrivv_template<HvxWR, V6_vS32b_ai>,
|
||||
def PS_vstorerv_ai: STriv_template<HvxVR, V6_vS32b_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
def PS_vstorerw_nt_ai: STrivv_template<HvxWR, V6_vS32b_nt_ai>,
|
||||
def PS_vstorerv_nt_ai: STriv_template<HvxVR, V6_vS32b_nt_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
def PS_vstorerwu_ai: STrivv_template<HvxWR, V6_vS32Ub_ai>,
|
||||
def PS_vstorerw_ai: STriv_template<HvxWR, V6_vS32b_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
def PS_vstorerw_nt_ai: STriv_template<HvxWR, V6_vS32b_nt_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
|
||||
let isPseudo = 1, isCodeGenOnly = 1, mayStore = 1, hasSideEffects = 0 in
|
||||
|
@ -427,15 +429,17 @@ def PS_vstorerq_ai: Pseudo<(outs),
|
|||
// Vector load pseudos
|
||||
let Predicates = [HasV60, UseHVX], isPseudo = 1, isCodeGenOnly = 1,
|
||||
mayLoad = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in
|
||||
class LDrivv_template<RegisterClass RC, InstHexagon rootInst>
|
||||
class LDriv_template<RegisterClass RC, InstHexagon rootInst>
|
||||
: InstHexagon<(outs RC:$dst), (ins IntRegs:$addr, s32_0Imm:$off),
|
||||
"", [], "", rootInst.Itinerary, rootInst.Type>;
|
||||
|
||||
def PS_vloadrw_ai: LDrivv_template<HvxWR, V6_vL32b_ai>,
|
||||
def PS_vloadrv_ai: LDriv_template<HvxVR, V6_vL32b_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
def PS_vloadrw_nt_ai: LDrivv_template<HvxWR, V6_vL32b_nt_ai>,
|
||||
def PS_vloadrv_nt_ai: LDriv_template<HvxVR, V6_vL32b_nt_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
def PS_vloadrwu_ai: LDrivv_template<HvxWR, V6_vL32Ub_ai>,
|
||||
def PS_vloadrw_ai: LDriv_template<HvxWR, V6_vL32b_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
def PS_vloadrw_nt_ai: LDriv_template<HvxWR, V6_vL32b_nt_ai>,
|
||||
Requires<[HasV60,UseHVX]>;
|
||||
|
||||
let isPseudo = 1, isCodeGenOnly = 1, mayLoad = 1, hasSideEffects = 0 in
|
||||
|
|
|
@ -73,6 +73,9 @@ HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF,
|
|||
static const MCPhysReg VecDbl[] = {
|
||||
W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
|
||||
};
|
||||
static const MCPhysReg VecPred[] = {
|
||||
Q0, Q1, Q2, Q3, 0
|
||||
};
|
||||
|
||||
switch (RC->getID()) {
|
||||
case IntRegsRegClassID:
|
||||
|
@ -85,6 +88,8 @@ HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF,
|
|||
return VecSgl;
|
||||
case HvxWRRegClassID:
|
||||
return VecDbl;
|
||||
case HvxQRRegClassID:
|
||||
return VecPred;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# RUN: llc -march=hexagon -run-pass prologepilog %s -o - | FileCheck %s
|
||||
|
||||
# Check that the spill of $q0 uses unaligned store instruction.
|
||||
# CHECK: V6_vS32Ub_ai $r30, -128, killed $v0
|
||||
|
||||
---
|
||||
name: test
|
||||
tracksRegLiveness: true
|
||||
stack:
|
||||
- { id: 0, type: variable-sized, offset: 0, alignment: 1 }
|
||||
- { id: 1, type: spill-slot, size: 128, alignment: 128 }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $q0
|
||||
PS_vstorerq_ai %stack.1, 0, $q0
|
||||
...
|
|
@ -4,7 +4,7 @@
|
|||
; has an alloca. Also, make sure the addressing mode for unaligned store does
|
||||
; is not a base+offset with a non-zero offset that is not a multiple of 128.
|
||||
|
||||
; CHECK: vmemu(r{{[0-9]+}}+#0)
|
||||
; CHECK: vmemu({{.*}}) =
|
||||
|
||||
%s.0 = type { [5 x [4 x i8]], i32, i32, i32, i32 }
|
||||
|
||||
|
|
Loading…
Reference in New Issue