mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-24 13:06:56 +00:00
Lower dynamic stack allocation on mingw32 to separate instruction.
We cannot use a normal call here since it has extra unmodelled side effects (it changes stack pointer). This should fix PR5292. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0ddda3b8c6
commit
043f3c2a0e
@ -6418,24 +6418,13 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
|
||||
EVT IntPtr = getPointerTy();
|
||||
EVT SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
|
||||
|
||||
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true));
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Size, Flag);
|
||||
Flag = Chain.getValue(1);
|
||||
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain,
|
||||
DAG.getTargetExternalSymbol("_alloca", IntPtr),
|
||||
DAG.getRegister(X86::EAX, IntPtr),
|
||||
DAG.getRegister(X86StackPtr, SPTy),
|
||||
Flag };
|
||||
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops, 5);
|
||||
Flag = Chain.getValue(1);
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
|
||||
Chain = DAG.getCALLSEQ_END(Chain,
|
||||
DAG.getIntPtrConstant(0, true),
|
||||
DAG.getIntPtrConstant(0, true),
|
||||
Flag);
|
||||
Chain = DAG.getNode(X86ISD::MINGW_ALLOCA, dl, NodeTys, Chain, Flag);
|
||||
Flag = Chain.getValue(1);
|
||||
|
||||
Chain = DAG.getCopyFromReg(Chain, dl, X86StackPtr, SPTy).getValue(1);
|
||||
|
||||
@ -7741,6 +7730,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
|
||||
case X86ISD::PTEST: return "X86ISD::PTEST";
|
||||
case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS";
|
||||
case X86ISD::MINGW_ALLOCA: return "X86ISD::MINGW_ALLOCA";
|
||||
}
|
||||
}
|
||||
|
||||
@ -8410,6 +8400,29 @@ X86TargetLowering::EmitLoweredSelect(MachineInstr *MI,
|
||||
return BB;
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
X86TargetLowering::EmitLoweredMingwAlloca(MachineInstr *MI,
|
||||
MachineBasicBlock *BB,
|
||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
|
||||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
MachineFunction *F = BB->getParent();
|
||||
|
||||
// The lowering is pretty easy: we're just emitting the call to _alloca. The
|
||||
// non-trivial part is impdef of ESP.
|
||||
// FIXME: The code should be tweaked as soon as we'll try to do codegen for
|
||||
// mingw-w64.
|
||||
|
||||
BuildMI(BB, DL, TII->get(X86::CALLpcrel32))
|
||||
.addExternalSymbol("_alloca")
|
||||
.addReg(X86::EAX, RegState::Implicit)
|
||||
.addReg(X86::ESP, RegState::Implicit)
|
||||
.addReg(X86::EAX, RegState::Define | RegState::Implicit)
|
||||
.addReg(X86::ESP, RegState::Define | RegState::Implicit);
|
||||
|
||||
F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
@ -8417,6 +8430,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: assert(false && "Unexpected instr type to insert");
|
||||
case X86::MINGW_ALLOCA:
|
||||
return EmitLoweredMingwAlloca(MI, BB, EM);
|
||||
case X86::CMOV_GR8:
|
||||
case X86::CMOV_V1I64:
|
||||
case X86::CMOV_FR32:
|
||||
|
@ -249,6 +249,9 @@ namespace llvm {
|
||||
// with control flow.
|
||||
VASTART_SAVE_XMM_REGS,
|
||||
|
||||
// MINGW_ALLOCA - MingW's __alloca call to do stack probing.
|
||||
MINGW_ALLOCA,
|
||||
|
||||
// ATOMADD64_DAG, ATOMSUB64_DAG, ATOMOR64_DAG, ATOMAND64_DAG,
|
||||
// ATOMXOR64_DAG, ATOMNAND64_DAG, ATOMSWAP64_DAG -
|
||||
// Atomic 64-bit binary operations.
|
||||
@ -259,6 +262,10 @@ namespace llvm {
|
||||
ATOMAND64_DAG,
|
||||
ATOMNAND64_DAG,
|
||||
ATOMSWAP64_DAG
|
||||
|
||||
// WARNING: Do not add anything in the end unless you want the node to
|
||||
// have memop! In fact, starting from ATOMADD64_DAG all opcodes will be
|
||||
// thought as target memory ops!
|
||||
};
|
||||
}
|
||||
|
||||
@ -789,7 +796,11 @@ namespace llvm {
|
||||
MachineBasicBlock *EmitLoweredSelect(MachineInstr *I,
|
||||
MachineBasicBlock *BB,
|
||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
|
||||
|
||||
|
||||
MachineBasicBlock *EmitLoweredMingwAlloca(MachineInstr *MI,
|
||||
MachineBasicBlock *BB,
|
||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
|
||||
|
||||
/// Emit nodes that will be selected as "test Op0,Op0", or something
|
||||
/// equivalent, for use with the given x86 condition code.
|
||||
SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG);
|
||||
|
@ -65,7 +65,7 @@ def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
|
||||
|
||||
def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
|
||||
|
||||
def SDTX86RdTsc : SDTypeProfile<0, 0, []>;
|
||||
def SDTX86Void : SDTypeProfile<0, 0, []>;
|
||||
|
||||
def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
|
||||
|
||||
@ -143,7 +143,7 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
|
||||
[SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore,
|
||||
SDNPMayLoad]>;
|
||||
|
||||
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
|
||||
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
|
||||
[SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
|
||||
|
||||
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
|
||||
@ -178,6 +178,9 @@ def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
|
||||
|
||||
def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
|
||||
|
||||
def X86MingwAlloca : SDNode<"X86ISD::MINGW_ALLOCA", SDTX86Void,
|
||||
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// X86 Operand Definitions.
|
||||
//
|
||||
@ -519,7 +522,7 @@ def ADJCALLSTACKUP32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
|
||||
}
|
||||
|
||||
// x86-64 va_start lowering magic.
|
||||
let usesCustomInserter = 1 in
|
||||
let usesCustomInserter = 1 in {
|
||||
def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
|
||||
(outs),
|
||||
(ins GR8:$al,
|
||||
@ -530,6 +533,11 @@ def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
|
||||
imm:$regsavefi,
|
||||
imm:$offset)]>;
|
||||
|
||||
def MINGW_ALLOCA : I<0, Pseudo, (outs), (ins),
|
||||
"call __alloca",
|
||||
[(X86MingwAlloca)]>;
|
||||
}
|
||||
|
||||
// Nop
|
||||
let neverHasSideEffects = 1 in {
|
||||
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
|
||||
|
@ -1057,7 +1057,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
||||
.addImm(NumBytes);
|
||||
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
||||
.addExternalSymbol("_alloca");
|
||||
.addExternalSymbol("_alloca")
|
||||
.addReg(StackPtr, RegState::Define | RegState::Implicit);
|
||||
} else {
|
||||
// Save EAX
|
||||
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
|
||||
@ -1068,7 +1069,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
||||
.addImm(NumBytes - 4);
|
||||
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
||||
.addExternalSymbol("_alloca");
|
||||
.addExternalSymbol("_alloca")
|
||||
.addReg(StackPtr, RegState::Define | RegState::Implicit);
|
||||
|
||||
// Restore EAX
|
||||
MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
|
||||
|
Loading…
Reference in New Issue
Block a user