Index: lib/Target/PowerPC/PPCFrameLowering.h =================================================================== --- lib/Target/PowerPC/PPCFrameLowering.h +++ lib/Target/PowerPC/PPCFrameLowering.h @@ -73,11 +73,27 @@ */ void createTailCallBranchInstr(MachineBasicBlock &MBB) const; + /** + * Check if the conditions are correct to allow for the stack update + * to be moved past the callee saved instructions. + */ + bool stackUpdateCanBeMoved(MachineFunction &MF) const; + public: PPCFrameLowering(const PPCSubtarget &STI); - unsigned determineFrameLayout(MachineFunction &MF, - bool UpdateMF = true, + /** + * Determine the frame layout and update the machine function. + */ + unsigned determineFrameLayoutAndUpdate(MachineFunction &MF, + bool UseEstimate = false) const; + + /** + * Determine the frame layout but do not update the machine function. + * The MachineFunction object can be const in this case as it is not + * modified. + */ + unsigned determineFrameLayout(const MachineFunction &MF, bool UseEstimate = false) const; /// emitProlog/emitEpilog - These methods insert prolog and epilog code into Index: lib/Target/PowerPC/PPCFrameLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCFrameLowering.cpp +++ lib/Target/PowerPC/PPCFrameLowering.cpp @@ -446,10 +446,10 @@ return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); } -/// determineFrameLayout - Determine the size of the frame and maximum call -/// frame size. -unsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF, - bool UpdateMF, +/// determineFrameLayoutAndUpdate - Determine the size of the frame and maximum +/// call frame size. Update the MachineFunction object with the stack size. +unsigned +PPCFrameLowering::determineFrameLayoutAndUpdate(MachineFunction &MF, bool UseEstimate) const { MachineFrameInfo &MFI = MF.getFrameInfo(); @@ -479,8 +479,7 @@ if (!DisableRedZone && CanUseRedZone && FitsInRedZone) { NumNoNeedForFrame++; // No need for frame - if (UpdateMF) - MFI.setStackSize(0); + MFI.setStackSize(0); return 0; } @@ -497,8 +496,7 @@ maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; // Update maximum call frame size. - if (UpdateMF) - MFI.setMaxCallFrameSize(maxCallFrameSize); + MFI.setMaxCallFrameSize(maxCallFrameSize); // Include call frame size in total. FrameSize += maxCallFrameSize; @@ -507,8 +505,62 @@ FrameSize = (FrameSize + AlignMask) & ~AlignMask; // Update frame info. - if (UpdateMF) - MFI.setStackSize(FrameSize); + MFI.setStackSize(FrameSize); + + return FrameSize; +} + +/// determineFrameLayout - Determine the size of the frame and maximum call +/// frame size. +unsigned PPCFrameLowering::determineFrameLayout(const MachineFunction &MF, + bool UseEstimate) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + // Get the number of bytes to allocate from the FrameInfo + unsigned FrameSize = + UseEstimate ? MFI.estimateStackSize(MF) : MFI.getStackSize(); + + // Get stack alignments. The frame must be aligned to the greatest of these: + unsigned TargetAlign = getStackAlignment(); // alignment required per the ABI + unsigned MaxAlign = MFI.getMaxAlignment(); // algmt required by data in frame + unsigned AlignMask = std::max(MaxAlign, TargetAlign) - 1; + + const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); + + unsigned LR = RegInfo->getRARegister(); + bool DisableRedZone = MF.getFunction().hasFnAttribute(Attribute::NoRedZone); + bool CanUseRedZone = !MFI.hasVarSizedObjects() && // No dynamic alloca. + !MFI.adjustsStack() && // No calls. + !MustSaveLR(MF, LR) && // No need to save LR. + !RegInfo->hasBasePointer(MF); // No special alignment. + + // Note: for PPC32 SVR4ABI (Non-DarwinABI), we can still generate stackless + // code if all local vars are reg-allocated. + bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize(); + + // Check whether we can skip adjusting the stack pointer (by using red zone) + if (!DisableRedZone && CanUseRedZone && FitsInRedZone) { + // No need for frame + return 0; + } + + // Get the maximum call frame size of all the calls. + unsigned maxCallFrameSize = MFI.getMaxCallFrameSize(); + + // Maximum call frame needs to be at least big enough for linkage area. + unsigned minCallFrameSize = getLinkageSize(); + maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); + + // If we have dynamic alloca then maxCallFrameSize needs to be aligned so + // that allocations will be aligned. + if (MFI.hasVarSizedObjects()) + maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; + + // Include call frame size in total. + FrameSize += maxCallFrameSize; + + // Make sure the frame is aligned. + FrameSize = (FrameSize + AlignMask) & ~AlignMask; return FrameSize; } @@ -690,7 +742,7 @@ const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); MachineFunction &MF = *(MBB->getParent()); bool HasBP = RegInfo->hasBasePointer(MF); - unsigned FrameSize = determineFrameLayout(MF, false); + unsigned FrameSize = determineFrameLayout(MF); int NegFrameSize = -FrameSize; bool IsLargeFrame = !isInt<16>(NegFrameSize); MachineFrameInfo &MFI = MF.getFrameInfo(); @@ -713,6 +765,48 @@ return findScratchRegister(TmpMBB, true); } +bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const { + const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); + PPCFunctionInfo *FI = MF.getInfo(); + + // Abort if there is no register info or function info. + if (!RegInfo || !FI) + return false; + + // Check the frame size first and return false if it does not fit the + // requirements. + // We need a non-zero frame size as well as a frame that is a maximum of + // 288 bytes. This is because by moving the stack pointer update we are + // now storing to the red zone until the stack pointer is moved. If we get + // an interrupt inside the prologue but before the stack update we now have + // a number of stores to the red zone and those stores must all fit into + // the red zone max size of 288. + MachineFrameInfo &MFI = MF.getFrameInfo(); + unsigned FrameSize = MFI.getStackSize(); + if (!FrameSize || FrameSize > 288) + return false; + + // Only try to move the stack update on PPC64. + if (!Subtarget.isPPC64()) + return false; + + // Frame pointers and base pointers complicate matters so don't do anything + // if we have them. + if (hasFP(MF) || RegInfo->hasBasePointer(MF)) + return false; + + // Cannot mode the stack pointer if we have a fast call or we use the PIC + // base. + if (FI->hasFastCall() || FI->usesPICBase()) + return false; + + bool RequiresScavenging = RegInfo->requiresFrameIndexScavenging(MF); + + // Finally we can move the stack update if we do not require regiser + // scavenging. + return !RequiresScavenging; +} + void PPCFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); @@ -748,7 +842,7 @@ MBBI = MBB.begin(); // Work out frame sizes. - unsigned FrameSize = determineFrameLayout(MF); + unsigned FrameSize = determineFrameLayoutAndUpdate(MF); int NegFrameSize = -FrameSize; if (!isInt<32>(NegFrameSize)) llvm_unreachable("Unhandled stack size!"); @@ -855,6 +949,37 @@ assert((isPPC64 || !MustSaveCR) && "Prologue CR saving supported only in 64-bit mode"); + // Check if we can move the stack update instruction (stdu) down the prologue + // past the callee saves. Hopefully this will avoid the situation where the + // saves are waiting for the update on the store with update to complete. + MachineBasicBlock::iterator StackUpdateLoc = MBBI; + bool MovingStackUpdateDown = false; + + // Check if we can move the stack update. + if (stackUpdateCanBeMoved(MF)) { + const std::vector &Info = MFI.getCalleeSavedInfo(); + for (CalleeSavedInfo CSI : Info) { + int FrIdx = CSI.getFrameIdx(); + // If the frame index is not negative the callee saved info belongs to a + // stack object that is not a fixed stack object. We ignore non-fixed + // stack objects because we won't move the stack update pointer past them. + if (FrIdx >= 0) + continue; + + if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) { + MFI.setObjectOffset(FrIdx, MFI.getObjectOffset(FrIdx) + NegFrameSize); + StackUpdateLoc++; + MovingStackUpdateDown = true; + } else { + // We need all of the Frame Indices to meet these conditions. + // If they do not, abort the whole operation. + StackUpdateLoc = MBBI; + MovingStackUpdateDown = false; + break; + } + } + } + // If we need to spill the CR and the LR but we don't have two separate // registers available, we must spill them one at a time if (MustSaveCR && SingleScratchReg && MustSaveLR) { @@ -918,7 +1043,7 @@ } if (MustSaveLR) - BuildMI(MBB, MBBI, dl, StoreInst) + BuildMI(MBB, StackUpdateLoc, dl, StoreInst) .addReg(ScratchReg, getKillRegState(true)) .addImm(LROffset) .addReg(SPReg); @@ -986,7 +1111,7 @@ HasSTUX = true; } else if (!isLargeFrame) { - BuildMI(MBB, MBBI, dl, StoreUpdtInst, SPReg) + BuildMI(MBB, StackUpdateLoc, dl, StoreUpdtInst, SPReg) .addReg(SPReg) .addImm(NegFrameSize) .addReg(SPReg); @@ -1234,6 +1359,12 @@ .addCFIIndex(CFIRegister); } else { int Offset = MFI.getObjectOffset(CSI[I].getFrameIdx()); + // We have changed the object offset above but we do not want to change + // the actual offsets in the CFI instruction so we have to undo the + // offset change here. + if (MovingStackUpdateDown) + Offset -= NegFrameSize; + unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) @@ -1380,6 +1511,31 @@ unsigned RBReg = SPReg; unsigned SPAdd = 0; + // Check if we can move the stack update instruction up the epilogue + // past the callee saves. This will allow the move to LR instruction + // to be executed before the restores of the callee saves which means + // that the callee saves can hide the latency from the MTLR instrcution. + MachineBasicBlock::iterator StackUpdateLoc = MBBI; + if (stackUpdateCanBeMoved(MF)) { + const std::vector & Info = MFI.getCalleeSavedInfo(); + for (CalleeSavedInfo CSI : Info) { + int FrIdx = CSI.getFrameIdx(); + // If the frame index is not negative the callee saved info belongs to a + // stack object that is not a fixed stack object. We ignore non-fixed + // stack objects because we won't move the stack update pointer past them. + if (FrIdx >= 0) + continue; + + if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) + StackUpdateLoc--; + else { + // Abort + StackUpdateLoc = MBBI; + break; + } + } + } + if (FrameSize) { // In the prologue, the loaded (or persistent) stack pointer value is // offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red @@ -1409,7 +1565,7 @@ } } else if (!isLargeFrame && !HasBP && !MFI.hasVarSizedObjects()) { if (HasRedZone) { - BuildMI(MBB, MBBI, dl, AddImmInst, SPReg) + BuildMI(MBB, StackUpdateLoc, dl, AddImmInst, SPReg) .addReg(SPReg) .addImm(FrameSize); } else { @@ -1433,7 +1589,7 @@ .addReg(FPReg); RBReg = FPReg; } - BuildMI(MBB, MBBI, dl, LoadInst, RBReg) + BuildMI(MBB, StackUpdateLoc, dl, LoadInst, RBReg) .addImm(0) .addReg(SPReg); } @@ -1466,7 +1622,7 @@ // a base register anyway, because it may happen to be R0. bool LoadedLR = false; if (MustSaveLR && RBReg == SPReg && isInt<16>(LROffset+SPAdd)) { - BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg) + BuildMI(MBB, StackUpdateLoc, dl, LoadInst, ScratchReg) .addImm(LROffset+SPAdd) .addReg(RBReg); LoadedLR = true; @@ -1538,7 +1694,7 @@ .addReg(TempReg, getKillRegState(i == e-1)); if (MustSaveLR) - BuildMI(MBB, MBBI, dl, MTLRInst).addReg(ScratchReg); + BuildMI(MBB, StackUpdateLoc, dl, MTLRInst).addReg(ScratchReg); // Callee pop calling convention. Pop parameter/linkage area. Used for tail // call optimization @@ -1947,7 +2103,7 @@ // the 16-bit immediate. We don't know the complete frame size here // because we've not yet computed callee-saved register spills or the // needed alignment padding. - unsigned StackSize = determineFrameLayout(MF, false, true); + unsigned StackSize = determineFrameLayout(MF, true); MachineFrameInfo &MFI = MF.getFrameInfo(); if (MFI.hasVarSizedObjects() || spillsCR(MF) || spillsVRSAVE(MF) || hasNonRISpills(MF) || (hasSpills(MF) && !isInt<16>(StackSize))) { Index: lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.cpp +++ lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1066,6 +1066,10 @@ OpcodeIndex = SOK_Float8Spill; } else if (PPC::F4RCRegClass.contains(Reg)) { OpcodeIndex = SOK_Float4Spill; + } else if (PPC::SPERCRegClass.contains(Reg)) { + OpcodeIndex = SOK_SPESpill; + } else if (PPC::SPE4RCRegClass.contains(Reg)) { + OpcodeIndex = SOK_SPE4Spill; } else if (PPC::CRRCRegClass.contains(Reg)) { OpcodeIndex = SOK_CRSpill; } else if (PPC::CRBITRCRegClass.contains(Reg)) { @@ -1152,6 +1156,10 @@ OpcodeIndex = SOK_Float8Spill; } else if (PPC::F4RCRegClass.contains(Reg)) { OpcodeIndex = SOK_Float4Spill; + } else if (PPC::SPERCRegClass.contains(Reg)) { + OpcodeIndex = SOK_SPESpill; + } else if (PPC::SPE4RCRegClass.contains(Reg)) { + OpcodeIndex = SOK_SPE4Spill; } else if (PPC::CRRCRegClass.contains(Reg)) { OpcodeIndex = SOK_CRSpill; } else if (PPC::CRBITRCRegClass.contains(Reg)) { Index: lib/Target/PowerPC/PPCRegisterInfo.h =================================================================== --- lib/Target/PowerPC/PPCRegisterInfo.h +++ lib/Target/PowerPC/PPCRegisterInfo.h @@ -90,9 +90,7 @@ return true; } - bool requiresFrameIndexScavenging(const MachineFunction &MF) const override { - return true; - } + bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override { return true; Index: lib/Target/PowerPC/PPCRegisterInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCRegisterInfo.cpp +++ lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -71,6 +71,8 @@ "caller preserved registers can be LICM candidates"), cl::init(true), cl::Hidden); +static unsigned offsetMinAlignForOpcode(unsigned OpC); + PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM) : PPCGenRegisterInfo(TM.isPPC64() ? PPC::LR8 : PPC::LR, TM.isPPC64() ? 0 : 1, @@ -316,6 +318,50 @@ return Reserved; } +bool PPCRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) const { + const PPCSubtarget &Subtarget = MF.getSubtarget(); + const PPCInstrInfo *InstrInfo = Subtarget.getInstrInfo(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const std::vector &Info = MFI.getCalleeSavedInfo(); + + // If the callee saved info is invalid we have to default to true for safety. + if (!MFI.isCalleeSavedInfoValid()) + return true; + + // We will require the use of X-Forms because the frame is larger than what + // can be represented in signed 16 bits that fit in the immediate of a D-Form. + // If we need an X-Form then we need a register to store the address offset. + unsigned FrameSize = MFI.getStackSize(); + if (FrameSize > 32767) + return true; + + // The callee saved info is valid so it can be traversed. + // Checking for registers that need saving that do not have load or store + // forms where the address offset is an immediate. + for (unsigned i = 0; i < Info.size(); i++) { + int FrIdx = Info[i].getFrameIdx(); + unsigned Reg = Info[i].getReg(); + + unsigned Opcode = InstrInfo->getStoreOpcodeForSpill(Reg); + if (!MFI.isFixedObjectIndex(FrIdx)) { + // This is not a fixed object. If it requires alignment then we may still + // need to use the XForm. + if (offsetMinAlignForOpcode(Opcode) > 1) + return true; + } + + // This is eiher: + // 1) A fixed frame index object which we know are aligned so + // as long as we have a valid DForm/DSForm/DQForm (non XForm) we don't + // need to consider the alignement here. + // 2) A not fixed object but in that case we now know that the min required + // alignment is no more than 1 based on the previous check. + if (InstrInfo->isXFormMemOp(Opcode)) + return true; + } + return false; +} + bool PPCRegisterInfo::isCallerPreservedPhysReg(unsigned PhysReg, const MachineFunction &MF) const { assert(TargetRegisterInfo::isPhysicalRegister(PhysReg)); @@ -826,9 +872,7 @@ } // If the offset must be a multiple of some value, return what that value is. -static unsigned offsetMinAlign(const MachineInstr &MI) { - unsigned OpC = MI.getOpcode(); - +static unsigned offsetMinAlignForOpcode(unsigned OpC) { switch (OpC) { default: return 1; @@ -853,6 +897,12 @@ } } +// If the offset must be a multiple of some value, return what that value is. +static unsigned offsetMinAlign(const MachineInstr &MI) { + unsigned OpC = MI.getOpcode(); + return offsetMinAlignForOpcode(OpC); +} + // Return the OffsetOperandNo given the FIOperandNum (and the instruction). static unsigned getOffsetONFromFION(const MachineInstr &MI, unsigned FIOperandNum) { @@ -1080,7 +1130,7 @@ MachineBasicBlock &MBB = *MI->getParent(); MachineFunction &MF = *MBB.getParent(); const PPCFrameLowering *TFI = getFrameLowering(MF); - unsigned StackEst = TFI->determineFrameLayout(MF, false, true); + unsigned StackEst = TFI->determineFrameLayout(MF, true); // If we likely don't need a stack frame, then we probably don't need a // virtual base register either. Index: test/CodeGen/PowerPC/MCSE-caller-preserved-reg.ll =================================================================== --- test/CodeGen/PowerPC/MCSE-caller-preserved-reg.ll +++ test/CodeGen/PowerPC/MCSE-caller-preserved-reg.ll @@ -15,13 +15,13 @@ define noalias i8* @_ZN2CC3funEv(%class.CC* %this) { ; CHECK-LABEL: _ZN2CC3funEv: ; CHECK: mflr 0 -; CHECK-NEXT: std 0, 16(1) -; CHECK-NEXT: stdu 1, -48(1) ; CHECK-NEXT: .cfi_def_cfa_offset 48 ; CHECK-NEXT: .cfi_offset lr, 16 ; CHECK-NEXT: .cfi_offset r30, -16 +; CHECK-NEXT: std 30, -16(1) +; CHECK-NEXT: std 0, 16(1) +; CHECK-NEXT: stdu 1, -48(1) ; CHECK-NEXT: ld 12, 0(3) -; CHECK-NEXT: std 30, 32(1) ; CHECK-NEXT: mr 30, 3 ; CHECK-NEXT: std 2, 24(1) ; CHECK-NEXT: mtctr 12 @@ -38,11 +38,11 @@ ; CHECK-NEXT: mr 3, 30 ; CHECK-NEXT: bl _ZN2CC3barEPi ; CHECK-NEXT: nop -; CHECK: ld 30, 32(1) -; CHECK-NEXT: li 3, 0 +; CHECK: li 3, 0 ; CHECK-NEXT: addi 1, 1, 48 ; CHECK-NEXT: ld 0, 16(1) ; CHECK-NEXT: mtlr 0 +; CHECK: ld 30, -16(1) ; CHECK-NEXT: blr entry: %foo = getelementptr inbounds %class.CC, %class.CC* %this, i64 0, i32 0, i32 0 Index: test/CodeGen/PowerPC/ppc-shrink-wrapping.ll =================================================================== --- test/CodeGen/PowerPC/ppc-shrink-wrapping.ll +++ test/CodeGen/PowerPC/ppc-shrink-wrapping.ll @@ -110,7 +110,7 @@ ; ; Epilogue code. ; CHECK: mtlr {{[0-9]+}} -; CHECK-NEXT: blr +; CHECK: blr ; ; ENABLE: .[[ELSE_LABEL]]: # %if.else ; Shift second argument by one and store into returned register. @@ -171,7 +171,7 @@ ; Next BB ; CHECK: %for.exit ; CHECK: mtlr {{[0-9]+}} -; CHECK-NEXT: blr +; CHECK: blr define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) { entry: br label %for.preheader @@ -209,9 +209,9 @@ ; Make sure we save the link register ; CHECK: mflr {{[0-9]+}} ; -; DISABLE: cmplwi 0, 3, 0 -; DISABLE-NEXT: std +; DISABLE: std ; DISABLE-NEXT: std +; DISABLE: cmplwi 0, 3, 0 ; DISABLE-NEXT: beq 0, .[[ELSE_LABEL:LBB[0-9_]+]] ; ; Loop preheader @@ -240,7 +240,7 @@ ; DISABLE: .[[EPILOG_BB]]: # %if.end ; Epilog code ; CHECK: mtlr {{[0-9]+}} -; CHECK-NEXT: blr +; CHECK: blr ; ; ENABLE: .[[ELSE_LABEL]]: # %if.else ; Shift second argument by one and store into returned register. @@ -291,9 +291,9 @@ ; Make sure we save the link register ; CHECK: mflr {{[0-9]+}} ; -; DISABLE: cmplwi 0, 3, 0 -; DISABLE-NEXT: std +; DISABLE: std ; DISABLE-NEXT: std +; DISABLE: cmplwi 0, 3, 0 ; DISABLE-NEXT: beq 0, .[[ELSE_LABEL:LBB[0-9_]+]] ; ; CHECK: bl somethingElse @@ -322,7 +322,7 @@ ; ; Epilogue code. ; CHECK: mtlr {{[0-9]+}} -; CHECK-NEXT: blr +; CHECK: blr ; ; ENABLE: .[[ELSE_LABEL]]: # %if.else ; Shift second argument by one and store into returned register. Index: test/CodeGen/PowerPC/tls_get_addr_clobbers.ll =================================================================== --- test/CodeGen/PowerPC/tls_get_addr_clobbers.ll +++ test/CodeGen/PowerPC/tls_get_addr_clobbers.ll @@ -6,7 +6,7 @@ entry: ; CHECK-LABEL: test_foo: -; CHECK: stdu 1, {{-?[0-9]+}}(1) +; CHECK-DAG: stdu 1, {{-?[0-9]+}}(1) ; CHECK-DAG: mr [[BACKUP_3:[0-9]+]], 3 ; CHECK-DAG: mr [[BACKUP_4:[0-9]+]], 4 ; CHECK-DAG: mr [[BACKUP_5:[0-9]+]], 5 @@ -15,14 +15,14 @@ ; CHECK-DAG: mr [[BACKUP_8:[0-9]+]], 8 ; CHECK-DAG: mr [[BACKUP_9:[0-9]+]], 9 ; CHECK-DAG: mr [[BACKUP_10:[0-9]+]], 10 -; CHECK-DAG: std [[BACKUP_3]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_4]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_5]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_6]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_7]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_8]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_9]], {{[0-9]+}}(1) -; CHECK-DAG: std [[BACKUP_10]], {{[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_3]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_4]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_5]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_6]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_7]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_8]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_9]], {{-?[0-9]+}}(1) +; CHECK-DAG: std [[BACKUP_10]], {{-?[0-9]+}}(1) ; CHECK: bl __tls_get_addr ; CHECK-DAG: stw 3, 0([[BACKUP_3]]) ; CHECK-DAG: stw 3, 0([[BACKUP_4]])