diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 33 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/opt-spill-volatile.ll | 29 |
2 files changed, 40 insertions, 22 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 03c50bbf731..c37bd4a63f4 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -1938,19 +1938,6 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, SmallSet<int,4> BadFIs; std::map<int,SlotInfo> FIRangeMap; - auto getRegClass = [&MRI,&HRI] (HexagonBlockRanges::RegisterRef R) - -> const TargetRegisterClass* { - if (TargetRegisterInfo::isPhysicalRegister(R.Reg)) - assert(R.Sub == 0); - if (TargetRegisterInfo::isVirtualRegister(R.Reg)) { - auto *RCR = MRI.getRegClass(R.Reg); - if (R.Sub == 0) - return RCR; - unsigned PR = *RCR->begin(); - R.Reg = HRI.getSubReg(PR, R.Sub); - } - return HRI.getMinimalPhysRegClass(R.Reg); - }; // Accumulate register classes: get a common class for a pre-existing // class HaveRC and a new class NewRC. Return nullptr if a common class // cannot be found, otherwise return the resulting class. If HaveRC is @@ -2003,14 +1990,8 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, bool Bad = (AM != HexagonII::BaseImmOffset); if (!Bad) { // If the addressing mode is ok, check the register class. - const TargetRegisterClass *RC = nullptr; - if (Load) { - MachineOperand &DataOp = In.getOperand(0); - RC = getRegClass({DataOp.getReg(), DataOp.getSubReg()}); - } else { - MachineOperand &DataOp = In.getOperand(2); - RC = getRegClass({DataOp.getReg(), DataOp.getSubReg()}); - } + unsigned OpNum = Load ? 0 : 2; + auto *RC = HII.getRegClass(In.getDesc(), OpNum, &HRI, MF); RC = getCommonRC(SI.RC, RC); if (RC == nullptr) Bad = true; @@ -2025,6 +2006,14 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, else SI.Size = S; } + if (!Bad) { + for (auto *Mo : In.memoperands()) { + if (!Mo->isVolatile()) + continue; + Bad = true; + break; + } + } if (Bad) BadFIs.insert(TFI); } @@ -2165,7 +2154,7 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.getReg(), SrcOp.getSubReg() }; - auto *RC = getRegClass({SrcOp.getReg(), SrcOp.getSubReg()}); + auto *RC = HII.getRegClass(SI->getDesc(), 2, &HRI, MF); // The this-> is needed to unconfuse MSVC. unsigned FoundR = this->findPhysReg(MF, Range, IM, DM, RC); DEBUG(dbgs() << "Replacement reg:" << PrintReg(FoundR, &HRI) << '\n'); diff --git a/llvm/test/CodeGen/Hexagon/opt-spill-volatile.ll b/llvm/test/CodeGen/Hexagon/opt-spill-volatile.ll new file mode 100644 index 00000000000..99dd4646d74 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/opt-spill-volatile.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; Check that the load/store to the volatile stack object has not been +; optimized away. + +target triple = "hexagon" + +; CHECK-LABEL: foo +; CHECK: memw(r29+#4) = +; CHECK: = memw(r29 + #4) +define i32 @foo(i32 %a) #0 { +entry: + %x = alloca i32, align 4 + %x.0.x.0..sroa_cast = bitcast i32* %x to i8* + call void @llvm.lifetime.start(i64 4, i8* %x.0.x.0..sroa_cast) + store volatile i32 0, i32* %x, align 4 + %call = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #0 + %x.0.x.0. = load volatile i32, i32* %x, align 4 + %add = add nsw i32 %x.0.x.0., %a + call void @llvm.lifetime.end(i64 4, i8* %x.0.x.0..sroa_cast) + ret i32 %add +} + +declare void @llvm.lifetime.start(i64, i8* nocapture) #1 +declare void @llvm.lifetime.end(i64, i8* nocapture) #1 + +declare i32 @bar(...) #0 + +attributes #0 = { nounwind } +attributes #1 = { argmemonly nounwind } |