From 592dd459242946593920911936aea47461e0faaa Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 11 Nov 2019 09:05:21 -0600 Subject: [PATCH] [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. --- llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 85 +++++++++-- llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 168 +++++++++++---------- llvm/lib/Target/Hexagon/HexagonPseudo.td | 20 ++- llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp | 5 + .../CodeGen/Hexagon/spill-vector-alignment.mir | 16 ++ llvm/test/CodeGen/Hexagon/v6-unaligned-spill.ll | 2 +- 6 files changed, 190 insertions(+), 106 deletions(-) create mode 100644 llvm/test/CodeGen/Hexagon/spill-vector-alignment.mir diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index e29dab2..aff8e57 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -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 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(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 memops = MI.memoperands(); + SmallVector new_memops; + for (MachineMemOperand *MMO : memops) { + auto *PV = MMO->getPseudoValue(); + if (auto *FS = dyn_cast_or_null(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().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().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); diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index bd84890..c3230da 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -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: diff --git a/llvm/lib/Target/Hexagon/HexagonPseudo.td b/llvm/lib/Target/Hexagon/HexagonPseudo.td index 7dd25d7..d2b6d64 100644 --- a/llvm/lib/Target/Hexagon/HexagonPseudo.td +++ b/llvm/lib/Target/Hexagon/HexagonPseudo.td @@ -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 +class STriv_template : InstHexagon<(outs), (ins IntRegs:$addr, s32_0Imm:$off, RC:$src), "", [], "", rootInst.Itinerary, rootInst.Type>; -def PS_vstorerw_ai: STrivv_template, +def PS_vstorerv_ai: STriv_template, Requires<[HasV60,UseHVX]>; -def PS_vstorerw_nt_ai: STrivv_template, +def PS_vstorerv_nt_ai: STriv_template, Requires<[HasV60,UseHVX]>; -def PS_vstorerwu_ai: STrivv_template, +def PS_vstorerw_ai: STriv_template, + Requires<[HasV60,UseHVX]>; +def PS_vstorerw_nt_ai: STriv_template, 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 +class LDriv_template : InstHexagon<(outs RC:$dst), (ins IntRegs:$addr, s32_0Imm:$off), "", [], "", rootInst.Itinerary, rootInst.Type>; -def PS_vloadrw_ai: LDrivv_template, +def PS_vloadrv_ai: LDriv_template, + Requires<[HasV60,UseHVX]>; +def PS_vloadrv_nt_ai: LDriv_template, Requires<[HasV60,UseHVX]>; -def PS_vloadrw_nt_ai: LDrivv_template, +def PS_vloadrw_ai: LDriv_template, Requires<[HasV60,UseHVX]>; -def PS_vloadrwu_ai: LDrivv_template, +def PS_vloadrw_nt_ai: LDriv_template, Requires<[HasV60,UseHVX]>; let isPseudo = 1, isCodeGenOnly = 1, mayLoad = 1, hasSideEffects = 0 in diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp index b7171fb..d55aeaf 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -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; } diff --git a/llvm/test/CodeGen/Hexagon/spill-vector-alignment.mir b/llvm/test/CodeGen/Hexagon/spill-vector-alignment.mir new file mode 100644 index 0000000..76a5e8d --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/spill-vector-alignment.mir @@ -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 +... diff --git a/llvm/test/CodeGen/Hexagon/v6-unaligned-spill.ll b/llvm/test/CodeGen/Hexagon/v6-unaligned-spill.ll index 2b72039..be53694 100644 --- a/llvm/test/CodeGen/Hexagon/v6-unaligned-spill.ll +++ b/llvm/test/CodeGen/Hexagon/v6-unaligned-spill.ll @@ -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 } -- 2.7.4