Index: lib/Target/Mips/MipsFrameLowering.h =================================================================== --- lib/Target/Mips/MipsFrameLowering.h +++ lib/Target/Mips/MipsFrameLowering.h @@ -32,6 +32,8 @@ bool hasFP(const MachineFunction &MF) const override; + bool hasBP(const MachineFunction &MF) const; + protected: uint64_t estimateStackSize(const MachineFunction &MF) const; }; Index: lib/Target/Mips/MipsFrameLowering.cpp =================================================================== --- lib/Target/Mips/MipsFrameLowering.cpp +++ lib/Target/Mips/MipsFrameLowering.cpp @@ -90,12 +90,23 @@ } // hasFP - Return true if the specified function should have a dedicated frame -// pointer register. This is true if the function has variable sized allocas or -// if frame pointer elimination is disabled. +// pointer register. This is true if the function has variable sized allocas, +// if it needs dynamic stack realignment, or if frame pointer elimination is +// disabled. bool MipsFrameLowering::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); + const TargetRegisterInfo *TRI = STI.getRegisterInfo(); + return MF.getTarget().Options.DisableFramePointerElim(MF) || - MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); + MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() || + TRI->needsStackRealignment(MF); +} + +bool MipsFrameLowering::hasBP(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const TargetRegisterInfo *TRI = STI.getRegisterInfo(); + + return MFI->hasVarSizedObjects() && TRI->needsStackRealignment(MF); } uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const { Index: lib/Target/Mips/MipsRegisterInfo.h =================================================================== --- lib/Target/Mips/MipsRegisterInfo.h +++ lib/Target/Mips/MipsRegisterInfo.h @@ -60,6 +60,11 @@ void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS = nullptr) const; + // Stack realignment queries. + bool canRealignStack(const MachineFunction &MF) const; + + bool needsStackRealignment(const MachineFunction &MF) const override; + /// Debug information queries. unsigned getFrameRegister(const MachineFunction &MF) const override; Index: lib/Target/Mips/MipsRegisterInfo.cpp =================================================================== --- lib/Target/Mips/MipsRegisterInfo.cpp +++ lib/Target/Mips/MipsRegisterInfo.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/IR/Constants.h" @@ -178,6 +179,14 @@ else { Reserved.set(Mips::FP); Reserved.set(Mips::FP_64); + + // Reserve the base register if we need to both realign the stack and + // allocate variable-sized objects at runtime. + if (needsStackRealignment(MF) && + MF.getFrameInfo()->hasVarSizedObjects()) { + Reserved.set(Mips::S7); + Reserved.set(Mips::S7_64); + } } } @@ -271,6 +280,41 @@ else return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) : (IsN64 ? Mips::SP_64 : Mips::SP); +} + +bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const { + const MipsSubtarget &Subtarget = MF.getSubtarget(); + unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64; + unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64; + + if (!Subtarget.hasStandardEncoding()) + return false; + + if (MF.getFunction()->hasFnAttribute("no-realign-stack")) + return false; + + if (!MF.getRegInfo().canReserveReg(FP)) + return false; + if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF)) + return true; + + return MF.getRegInfo().canReserveReg(BP); } +bool MipsRegisterInfo::needsStackRealignment(const MachineFunction &MF) const { + const MipsSubtarget &Subtarget = MF.getSubtarget(); + const MachineFrameInfo *MFI = MF.getFrameInfo(); + + bool CanRealign = canRealignStack(MF); + + const Function *F = MF.getFunction(); + if (F->hasFnAttribute(Attribute::StackAlignment)) + return CanRealign; + + unsigned StackAlignment = Subtarget.getFrameLowering()->getStackAlignment(); + if (MFI->getMaxAlignment() > StackAlignment) + return CanRealign; + + return false; +} Index: lib/Target/Mips/MipsSEFrameLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEFrameLowering.cpp +++ lib/Target/Mips/MipsSEFrameLowering.cpp @@ -387,10 +387,14 @@ MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + const TargetRegisterClass *RC = STI.isABI_N64() ? + &Mips::GPR64RegClass : &Mips::GPR32RegClass; unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; + unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; + unsigned AND = STI.isABI_N64() ? Mips::AND64 : Mips::AND; // First, compute final stack size. uint64_t StackSize = MFI->getStackSize(); @@ -473,9 +477,6 @@ } if (MipsFI->callsEhReturn()) { - const TargetRegisterClass *RC = STI.isABI_N64() ? - &Mips::GPR64RegClass : &Mips::GPR32RegClass; - // Insert instructions that spill eh data registers. for (int I = 0; I < 4; ++I) { if (!MBB.isLiveIn(ehDataReg(I))) @@ -506,6 +507,26 @@ nullptr, MRI->getDwarfRegNum(FP, true))); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); + + if (RegInfo.needsStackRealignment(MF)) { + // addiu $Reg, $zero, -MaxAlignment + // andi $sp, $sp, $Reg + unsigned VR = MF.getRegInfo().createVirtualRegister(RC); + assert(MFI->getMaxAlignment() <= std::numeric_limits::max() && + "Function's alignment requirement is not supported."); + int MaxAlign = - (signed) MFI->getMaxAlignment(); + + BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO) .addImm(MaxAlign); + BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR); + + if (hasBP(MF)) { + // move $s7, $sp + unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7; + BuildMI(MBB, MBBI, dl, TII.get(ADDu), BP) + .addReg(SP) + .addReg(ZERO); + } + } } } @@ -633,10 +654,14 @@ MachineRegisterInfo &MRI = MF.getRegInfo(); MipsFunctionInfo *MipsFI = MF.getInfo(); unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; + unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7; // Mark $fp as used if function has dedicated frame pointer. if (hasFP(MF)) MRI.setPhysRegUsed(FP); + // Mark $s7 as used if function has dedicated base pointer. + if (hasBP(MF)) + MRI.setPhysRegUsed(BP); // Create spill slots for eh data registers if function calls eh_return. if (MipsFI->callsEhReturn()) Index: lib/Target/Mips/MipsSERegisterInfo.cpp =================================================================== --- lib/Target/Mips/MipsSERegisterInfo.cpp +++ lib/Target/Mips/MipsSERegisterInfo.cpp @@ -110,6 +110,8 @@ MachineFunction &MF = *MI.getParent()->getParent(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo(); + const MipsRegisterInfo *RegInfo = + static_cast(MF.getSubtarget().getRegisterInfo()); bool isN64 = static_cast(MF.getTarget()).getABI().IsN64(); @@ -135,7 +137,12 @@ if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI) FrameReg = isN64 ? Mips::SP_64 : Mips::SP; - else + else if (RegInfo->needsStackRealignment(MF)) { + if (MFI->hasVarSizedObjects() && !MFI->isFixedObjectIndex(FrameIndex)) + FrameReg = isN64 ? Mips::S7_64 : Mips::S7; + else + FrameReg = getFrameRegister(MF); + } else FrameReg = getFrameRegister(MF); // Calculate final offset. Index: test/CodeGen/Mips/dynamic-stack-realignment.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/dynamic-stack-realignment.ll @@ -0,0 +1,171 @@ +; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP32 +; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP32 +; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP32 +; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 +; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 +; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 + +; Check dynamic stack realignment in functions without variable-sized objects. +declare void @helper_01(i32, i32, i32, i32, i32*) + +define void @func_01() { +entry: +; ALL-LABEL: func_01: + + ; prologue + ; GP32: addiu $sp, $sp, -1024 + ; GP32: sw $ra, 1020($sp) + ; GP32: sw $fp, 1016($sp) + ; + ; GP32: move $fp, $sp + ; GP32: addiu $[[T0:[0-9]+|ra|gp]], $zero, -512 + ; GP32-NEXT: and $sp, $sp, $[[T0]] + + ; body + ; GP32: addiu $[[T1:[0-9]+]], $fp, 512 + ; GP32: sw $[[T1]], 16($sp) + + ; epilogue + ; GP32: move $sp, $fp + ; GP32: lw $fp, 1016($sp) + ; GP32: lw $ra, 1020($sp) + ; GP32: addiu $sp, $sp, 1024 + + %a = alloca i32, align 512 + call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) + ret void +} + +declare void @helper_02(i32, i32, i32, i32, + i32, i32, i32, i32, i32*) + +define void @func_02() { +entry: +; ALL-LABEL: func_02: + + ; prologue + ; GP64: daddiu $sp, $sp, -1024 + ; GP64: sd $ra, 1016($sp) + ; GP64: sd $fp, 1008($sp) + ; + ; GP64: move $fp, $sp + ; GP64: daddiu $[[T0:[0-9]+|ra]], $zero, -512 + ; GP64-NEXT: and $sp, $sp, $[[T0]] + + ; body + ; GP64: daddiu $[[T1:[0-9]+]], $fp, 512 + ; GP64: sd $[[T1]], 0($sp) + + ; epilogue + ; GP64: move $sp, $fp + ; GP64: ld $fp, 1008($sp) + ; GP64: ld $ra, 1016($sp) + ; GP64: addiu $sp, $sp, 1024 + + %a = alloca i32, align 512 + call void @helper_02(i32 0, i32 0, i32 0, i32 0, + i32 0, i32 0, i32 0, i32 0, i32* %a) + ret void +} + +; Check dynamic stack realignment in functions with variable-sized objects. +define void @func_03(i32 %sz) { +entry: +; ALL-LABEL: func_03: + + ; prologue + ; GP32: addiu $sp, $sp, -1024 + ; GP32: sw $fp, 1020($sp) + ; GP32: sw $23, 1016($sp) + ; + ; GP32: move $fp, $sp + ; GP32: addiu $[[T0:[0-9]+|gp]], $zero, -512 + ; GP32-NEXT: and $sp, $sp, $[[T0]] + ; GP32-NEXT: move $23, $sp + + ; body + ; GP32: addiu $[[T1:[0-9]+]], $zero, 222 + ; GP32: sw $[[T1]], 508($23) + + ; epilogue + ; GP32: move $sp, $fp + ; GP32: lw $23, 1016($sp) + ; GP32: lw $fp, 1020($sp) + ; GP32: addiu $sp, $sp, 1024 + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + ret void +} + +define void @func_04(i32 %sz) { +entry: +; ALL-LABEL: func_04: + + ; prologue + ; GP64: daddiu $sp, $sp, -1024 + ; GP64: sd $fp, 1016($sp) + ; GP64: sd $23, 1008($sp) + ; + ; GP64: move $fp, $sp + ; GP64: addiu $[[T0:[0-9]+|gp]], $zero, -512 + ; GP64-NEXT: and $sp, $sp, $[[T0]] + ; GP64-NEXT: move $23, $sp + + ; body + ; GP64: addiu $[[T1:[0-9]+]], $zero, 222 + ; GP64: sw $[[T1]], 508($23) + + ; epilogue + ; GP64: move $sp, $fp + ; GP64: ld $23, 1008($sp) + ; GP64: ld $fp, 1016($sp) + ; GP64: addiu $sp, $sp, 1024 + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + ret void +} + +; Check that we do not perform dynamic stack realignment in the presence of +; the "no-realign-stack" function attribute. + +define void @func_05() "no-realign-stack" { +entry: +; ALL-LABEL: func_05: + + ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] + + %a = alloca i32, align 512 + call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) + ret void +} + +define void @func_06(i32 %sz) "no-realign-stack" { +entry: +; ALL-LABEL: func_06: + + ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + ret void +} Index: test/CodeGen/Mips/msa/frameindex.ll =================================================================== --- test/CodeGen/Mips/msa/frameindex.ll +++ test/CodeGen/Mips/msa/frameindex.ll @@ -6,9 +6,9 @@ %1 = alloca <16 x i8> %2 = load volatile <16 x i8>, <16 x i8>* %1 - ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 0($sp) + ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 0($fp) store volatile <16 x i8> %2, <16 x i8>* %1 - ; MIPS32-AE: st.b [[R1]], 0($sp) + ; MIPS32-AE: st.b [[R1]], 0($fp) ret void ; MIPS32-AE: .size loadstore_v16i8_near @@ -21,9 +21,9 @@ %2 = alloca [496 x i8] ; Push the frame right up to 512 bytes %3 = load volatile <16 x i8>, <16 x i8>* %1 - ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 496($sp) + ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 496($fp) store volatile <16 x i8> %3, <16 x i8>* %1 - ; MIPS32-AE: st.b [[R1]], 496($sp) + ; MIPS32-AE: st.b [[R1]], 496($fp) ret void ; MIPS32-AE: .size loadstore_v16i8_just_under_simm10 @@ -36,10 +36,10 @@ %2 = alloca [497 x i8] ; Push the frame just over 512 bytes %3 = load volatile <16 x i8>, <16 x i8>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 512 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 512 ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <16 x i8> %3, <16 x i8>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 512 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 512 ; MIPS32-AE: st.b [[R1]], 0([[BASE]]) ret void @@ -54,11 +54,11 @@ %3 = load volatile <16 x i8>, <16 x i8>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <16 x i8> %3, <16 x i8>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.b [[R1]], 0([[BASE]]) ret void @@ -73,11 +73,11 @@ %3 = load volatile <16 x i8>, <16 x i8>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.b [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <16 x i8> %3, <16 x i8>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.b [[R1]], 0([[BASE]]) ret void @@ -89,9 +89,9 @@ %1 = alloca <8 x i16> %2 = load volatile <8 x i16>, <8 x i16>* %1 - ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 0($sp) + ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 0($fp) store volatile <8 x i16> %2, <8 x i16>* %1 - ; MIPS32-AE: st.h [[R1]], 0($sp) + ; MIPS32-AE: st.h [[R1]], 0($fp) ret void ; MIPS32-AE: .size loadstore_v8i16_near @@ -107,10 +107,10 @@ %5 = getelementptr [2 x <8 x i16>], [2 x <8 x i16>]* %4, i32 0, i32 0 %6 = load volatile <8 x i16>, <8 x i16>* %5 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1 ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <8 x i16> %6, <8 x i16>* %5 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1 ; MIPS32-AE: st.h [[R1]], 0([[BASE]]) ret void @@ -124,9 +124,9 @@ %2 = alloca [1008 x i8] ; Push the frame right up to 1024 bytes %3 = load volatile <8 x i16>, <8 x i16>* %1 - ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 1008($sp) + ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 1008($fp) store volatile <8 x i16> %3, <8 x i16>* %1 - ; MIPS32-AE: st.h [[R1]], 1008($sp) + ; MIPS32-AE: st.h [[R1]], 1008($fp) ret void ; MIPS32-AE: .size loadstore_v8i16_just_under_simm10 @@ -139,10 +139,10 @@ %2 = alloca [1009 x i8] ; Push the frame just over 1024 bytes %3 = load volatile <8 x i16>, <8 x i16>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1024 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1024 ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <8 x i16> %3, <8 x i16>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1024 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1024 ; MIPS32-AE: st.h [[R1]], 0([[BASE]]) ret void @@ -157,11 +157,11 @@ %3 = load volatile <8 x i16>, <8 x i16>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <8 x i16> %3, <8 x i16>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.h [[R1]], 0([[BASE]]) ret void @@ -176,11 +176,11 @@ %3 = load volatile <8 x i16>, <8 x i16>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.h [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <8 x i16> %3, <8 x i16>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.h [[R1]], 0([[BASE]]) ret void @@ -192,9 +192,9 @@ %1 = alloca <4 x i32> %2 = load volatile <4 x i32>, <4 x i32>* %1 - ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 0($sp) + ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 0($fp) store volatile <4 x i32> %2, <4 x i32>* %1 - ; MIPS32-AE: st.w [[R1]], 0($sp) + ; MIPS32-AE: st.w [[R1]], 0($fp) ret void ; MIPS32-AE: .size loadstore_v4i32_near @@ -210,10 +210,10 @@ %5 = getelementptr [2 x <4 x i32>], [2 x <4 x i32>]* %4, i32 0, i32 0 %6 = load volatile <4 x i32>, <4 x i32>* %5 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1 ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <4 x i32> %6, <4 x i32>* %5 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1 ; MIPS32-AE: st.w [[R1]], 0([[BASE]]) ret void @@ -227,9 +227,9 @@ %2 = alloca [2032 x i8] ; Push the frame right up to 2048 bytes %3 = load volatile <4 x i32>, <4 x i32>* %1 - ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 2032($sp) + ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 2032($fp) store volatile <4 x i32> %3, <4 x i32>* %1 - ; MIPS32-AE: st.w [[R1]], 2032($sp) + ; MIPS32-AE: st.w [[R1]], 2032($fp) ret void ; MIPS32-AE: .size loadstore_v4i32_just_under_simm10 @@ -242,10 +242,10 @@ %2 = alloca [2033 x i8] ; Push the frame just over 2048 bytes %3 = load volatile <4 x i32>, <4 x i32>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 2048 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 2048 ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <4 x i32> %3, <4 x i32>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 2048 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 2048 ; MIPS32-AE: st.w [[R1]], 0([[BASE]]) ret void @@ -260,11 +260,11 @@ %3 = load volatile <4 x i32>, <4 x i32>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <4 x i32> %3, <4 x i32>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.w [[R1]], 0([[BASE]]) ret void @@ -279,11 +279,11 @@ %3 = load volatile <4 x i32>, <4 x i32>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.w [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <4 x i32> %3, <4 x i32>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.w [[R1]], 0([[BASE]]) ret void @@ -295,9 +295,9 @@ %1 = alloca <2 x i64> %2 = load volatile <2 x i64>, <2 x i64>* %1 - ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 0($sp) + ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 0($fp) store volatile <2 x i64> %2, <2 x i64>* %1 - ; MIPS32-AE: st.d [[R1]], 0($sp) + ; MIPS32-AE: st.d [[R1]], 0($fp) ret void ; MIPS32-AE: .size loadstore_v2i64_near @@ -313,10 +313,10 @@ %5 = getelementptr [2 x <2 x i64>], [2 x <2 x i64>]* %4, i32 0, i32 0 %6 = load volatile <2 x i64>, <2 x i64>* %5 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1 ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <2 x i64> %6, <2 x i64>* %5 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 1 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 1 ; MIPS32-AE: st.d [[R1]], 0([[BASE]]) ret void @@ -330,9 +330,9 @@ %2 = alloca [4080 x i8] ; Push the frame right up to 4096 bytes %3 = load volatile <2 x i64>, <2 x i64>* %1 - ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 4080($sp) + ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 4080($fp) store volatile <2 x i64> %3, <2 x i64>* %1 - ; MIPS32-AE: st.d [[R1]], 4080($sp) + ; MIPS32-AE: st.d [[R1]], 4080($fp) ret void ; MIPS32-AE: .size loadstore_v2i64_just_under_simm10 @@ -345,10 +345,10 @@ %2 = alloca [4081 x i8] ; Push the frame just over 4096 bytes %3 = load volatile <2 x i64>, <2 x i64>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 4096 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 4096 ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <2 x i64> %3, <2 x i64>* %1 - ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $sp, 4096 + ; MIPS32-AE: addiu [[BASE:\$([0-9]+|gp)]], $fp, 4096 ; MIPS32-AE: st.d [[R1]], 0([[BASE]]) ret void @@ -363,11 +363,11 @@ %3 = load volatile <2 x i64>, <2 x i64>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <2 x i64> %3, <2 x i64>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.d [[R1]], 0([[BASE]]) ret void @@ -382,11 +382,11 @@ %3 = load volatile <2 x i64>, <2 x i64>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: ld.d [[R1:\$w[0-9]+]], 0([[BASE]]) store volatile <2 x i64> %3, <2 x i64>* %1 ; MIPS32-AE: ori [[R2:\$([0-9]+|gp)]], $zero, 32768 - ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $sp, [[R2]] + ; MIPS32-AE: addu [[BASE:\$([0-9]+|gp)]], $fp, [[R2]] ; MIPS32-AE: st.d [[R1]], 0([[BASE]]) ret void Index: test/CodeGen/Mips/return-vector.ll =================================================================== --- test/CodeGen/Mips/return-vector.ll +++ test/CodeGen/Mips/return-vector.ll @@ -32,18 +32,17 @@ ; CHECK-LABEL: call_i8: ; CHECK: call16(i8) -; CHECK: addiu $4, $sp, 32 -; CHECK: lw $[[R0:[a-z0-9]+]], 60($sp) -; CHECK: lw $[[R1:[a-z0-9]+]], 56($sp) -; CHECK: lw $[[R2:[a-z0-9]+]], 52($sp) -; CHECK: lw $[[R3:[a-z0-9]+]], 48($sp) -; CHECK: lw $[[R4:[a-z0-9]+]], 44($sp) -; CHECK: lw $[[R5:[a-z0-9]+]], 40($sp) -; CHECK: lw $[[R6:[a-z0-9]+]], 36($sp) -; CHECK: lw $[[R7:[a-z0-9]+]], 32($sp) +; CHECK: addiu $4, $fp, 32 +; CHECK: lw $[[R0:[a-z0-9]+]], 60($fp) +; CHECK: lw $[[R1:[a-z0-9]+]], 56($fp) +; CHECK: lw $[[R2:[a-z0-9]+]], 52($fp) +; CHECK: lw $[[R3:[a-z0-9]+]], 48($fp) +; CHECK: lw $[[R4:[a-z0-9]+]], 44($fp) +; CHECK: lw $[[R5:[a-z0-9]+]], 40($fp) +; CHECK: lw $[[R6:[a-z0-9]+]], 36($fp) +; CHECK: lw $[[R7:[a-z0-9]+]], 32($fp) } - define float @call_f4() { entry: %call = call <4 x float> (...)* @f4() @@ -58,11 +57,11 @@ ; CHECK-LABEL: call_f4: ; CHECK: call16(f4) -; CHECK: addiu $4, $sp, 16 -; CHECK: lwc1 $[[R0:[a-z0-9]+]], 28($sp) -; CHECK: lwc1 $[[R1:[a-z0-9]+]], 24($sp) -; CHECK: lwc1 $[[R3:[a-z0-9]+]], 20($sp) -; CHECK: lwc1 $[[R4:[a-z0-9]+]], 16($sp) +; CHECK: addiu $4, $fp, 16 +; CHECK: lwc1 $[[R0:[a-z0-9]+]], 28($fp) +; CHECK: lwc1 $[[R1:[a-z0-9]+]], 24($fp) +; CHECK: lwc1 $[[R3:[a-z0-9]+]], 20($fp) +; CHECK: lwc1 $[[R4:[a-z0-9]+]], 16($fp) } @@ -80,11 +79,11 @@ ; CHECK-LABEL: call_d4: ; CHECK: call16(d4) -; CHECK: addiu $4, $sp, 32 -; CHECK: ldc1 $[[R0:[a-z0-9]+]], 56($sp) -; CHECK: ldc1 $[[R1:[a-z0-9]+]], 48($sp) -; CHECK: ldc1 $[[R3:[a-z0-9]+]], 40($sp) -; CHECK: ldc1 $[[R4:[a-z0-9]+]], 32($sp) +; CHECK: addiu $4, $fp, 32 +; CHECK: ldc1 $[[R0:[a-z0-9]+]], 56($fp) +; CHECK: ldc1 $[[R1:[a-z0-9]+]], 48($fp) +; CHECK: ldc1 $[[R3:[a-z0-9]+]], 40($fp) +; CHECK: ldc1 $[[R4:[a-z0-9]+]], 32($fp) }