mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-25 05:25:53 +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 IntPtr = getPointerTy();
|
||||||
EVT SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
|
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);
|
Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Size, Flag);
|
||||||
Flag = Chain.getValue(1);
|
Flag = Chain.getValue(1);
|
||||||
|
|
||||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
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);
|
|
||||||
|
|
||||||
Chain = DAG.getCALLSEQ_END(Chain,
|
Chain = DAG.getNode(X86ISD::MINGW_ALLOCA, dl, NodeTys, Chain, Flag);
|
||||||
DAG.getIntPtrConstant(0, true),
|
Flag = Chain.getValue(1);
|
||||||
DAG.getIntPtrConstant(0, true),
|
|
||||||
Flag);
|
|
||||||
|
|
||||||
Chain = DAG.getCopyFromReg(Chain, dl, X86StackPtr, SPTy).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::MUL_IMM: return "X86ISD::MUL_IMM";
|
||||||
case X86ISD::PTEST: return "X86ISD::PTEST";
|
case X86ISD::PTEST: return "X86ISD::PTEST";
|
||||||
case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS";
|
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;
|
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 *
|
MachineBasicBlock *
|
||||||
X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||||
@ -8417,6 +8430,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
|||||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
|
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
default: assert(false && "Unexpected instr type to insert");
|
default: assert(false && "Unexpected instr type to insert");
|
||||||
|
case X86::MINGW_ALLOCA:
|
||||||
|
return EmitLoweredMingwAlloca(MI, BB, EM);
|
||||||
case X86::CMOV_GR8:
|
case X86::CMOV_GR8:
|
||||||
case X86::CMOV_V1I64:
|
case X86::CMOV_V1I64:
|
||||||
case X86::CMOV_FR32:
|
case X86::CMOV_FR32:
|
||||||
|
@ -249,6 +249,9 @@ namespace llvm {
|
|||||||
// with control flow.
|
// with control flow.
|
||||||
VASTART_SAVE_XMM_REGS,
|
VASTART_SAVE_XMM_REGS,
|
||||||
|
|
||||||
|
// MINGW_ALLOCA - MingW's __alloca call to do stack probing.
|
||||||
|
MINGW_ALLOCA,
|
||||||
|
|
||||||
// ATOMADD64_DAG, ATOMSUB64_DAG, ATOMOR64_DAG, ATOMAND64_DAG,
|
// ATOMADD64_DAG, ATOMSUB64_DAG, ATOMOR64_DAG, ATOMAND64_DAG,
|
||||||
// ATOMXOR64_DAG, ATOMNAND64_DAG, ATOMSWAP64_DAG -
|
// ATOMXOR64_DAG, ATOMNAND64_DAG, ATOMSWAP64_DAG -
|
||||||
// Atomic 64-bit binary operations.
|
// Atomic 64-bit binary operations.
|
||||||
@ -259,6 +262,10 @@ namespace llvm {
|
|||||||
ATOMAND64_DAG,
|
ATOMAND64_DAG,
|
||||||
ATOMNAND64_DAG,
|
ATOMNAND64_DAG,
|
||||||
ATOMSWAP64_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 *EmitLoweredSelect(MachineInstr *I,
|
||||||
MachineBasicBlock *BB,
|
MachineBasicBlock *BB,
|
||||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
|
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
|
/// Emit nodes that will be selected as "test Op0,Op0", or something
|
||||||
/// equivalent, for use with the given x86 condition code.
|
/// equivalent, for use with the given x86 condition code.
|
||||||
SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG);
|
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 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>]>;
|
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,
|
[SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore,
|
||||||
SDNPMayLoad]>;
|
SDNPMayLoad]>;
|
||||||
|
|
||||||
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
|
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
|
||||||
[SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
|
[SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
|
||||||
|
|
||||||
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
|
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 X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
|
||||||
|
|
||||||
|
def X86MingwAlloca : SDNode<"X86ISD::MINGW_ALLOCA", SDTX86Void,
|
||||||
|
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// X86 Operand Definitions.
|
// X86 Operand Definitions.
|
||||||
//
|
//
|
||||||
@ -519,7 +522,7 @@ def ADJCALLSTACKUP32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
|
|||||||
}
|
}
|
||||||
|
|
||||||
// x86-64 va_start lowering magic.
|
// x86-64 va_start lowering magic.
|
||||||
let usesCustomInserter = 1 in
|
let usesCustomInserter = 1 in {
|
||||||
def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
|
def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
|
||||||
(outs),
|
(outs),
|
||||||
(ins GR8:$al,
|
(ins GR8:$al,
|
||||||
@ -530,6 +533,11 @@ def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
|
|||||||
imm:$regsavefi,
|
imm:$regsavefi,
|
||||||
imm:$offset)]>;
|
imm:$offset)]>;
|
||||||
|
|
||||||
|
def MINGW_ALLOCA : I<0, Pseudo, (outs), (ins),
|
||||||
|
"call __alloca",
|
||||||
|
[(X86MingwAlloca)]>;
|
||||||
|
}
|
||||||
|
|
||||||
// Nop
|
// Nop
|
||||||
let neverHasSideEffects = 1 in {
|
let neverHasSideEffects = 1 in {
|
||||||
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
|
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)
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
||||||
.addImm(NumBytes);
|
.addImm(NumBytes);
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
||||||
.addExternalSymbol("_alloca");
|
.addExternalSymbol("_alloca")
|
||||||
|
.addReg(StackPtr, RegState::Define | RegState::Implicit);
|
||||||
} else {
|
} else {
|
||||||
// Save EAX
|
// Save EAX
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
|
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)
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
||||||
.addImm(NumBytes - 4);
|
.addImm(NumBytes - 4);
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
||||||
.addExternalSymbol("_alloca");
|
.addExternalSymbol("_alloca")
|
||||||
|
.addReg(StackPtr, RegState::Define | RegState::Implicit);
|
||||||
|
|
||||||
// Restore EAX
|
// Restore EAX
|
||||||
MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
|
MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
|
||||||
|
Loading…
Reference in New Issue
Block a user