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
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;
else
SI.Size = S;
}
+ if (!Bad) {
+ for (auto *Mo : In.memoperands()) {
+ if (!Mo->isVolatile())
+ continue;
+ Bad = true;
+ break;
+ }
+ }
if (Bad)
BadFIs.insert(TFI);
}
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');
--- /dev/null
+; 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 }