llvm.org GIT mirror llvm / fc99ce0
Revert r269828 "X86: Avoid using _chkstk when lowering WIN_ALLOCA instructions" Seems to have broken the Windows ASan bot. Reverting while investigating. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269833 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 4 years ago
17 changed file(s) with 62 addition(s) and 510 deletion(s). Raw diff Collapse all Expand all
3636 X86WinEHState.cpp
3737 X86OptimizeLEAs.cpp
3838 X86FixupBWInsts.cpp
39 X86WinAllocaExpander.cpp
4039 )
4140
4241 add_llvm_target(X86CodeGen ${sources})
5858 /// recalculations.
5959 FunctionPass *createX86OptimizeLEAs();
6060
61 /// Return a pass that expands WinAlloca pseudo-instructions.
62 FunctionPass *createX86WinAllocaExpander();
63
6461 /// Return a pass that optimizes the code-size of x86 call sequences. This is
6562 /// done by replacing esp-relative movs with pushes.
6663 FunctionPass *createX86CallFrameOptimization();
1656216562 Result = DAG.getNode(X86ISD::SEG_ALLOCA, dl, SPTy, Chain,
1656316563 DAG.getRegister(Vreg, SPTy));
1656416564 } else {
16565 SDValue Flag;
16566 const unsigned Reg = (Subtarget.isTarget64BitLP64() ? X86::RAX : X86::EAX);
16567
16568 Chain = DAG.getCopyToReg(Chain, dl, Reg, Size, Flag);
16569 Flag = Chain.getValue(1);
1656516570 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
16566 Chain = DAG.getNode(X86ISD::WIN_ALLOCA, dl, NodeTys, Chain, Size);
16567 MF.getInfo()->setHasWinAlloca(true);
16571
16572 Chain = DAG.getNode(X86ISD::WIN_ALLOCA, dl, NodeTys, Chain, Flag);
1656816573
1656916574 const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1657016575 unsigned SPReg = RegInfo->getStackRegister();
2322223227 }
2322323228
2322423229 MachineBasicBlock *
23230 X86TargetLowering::EmitLoweredWinAlloca(MachineInstr *MI,
23231 MachineBasicBlock *BB) const {
23232 assert(!Subtarget.isTargetMachO());
23233 DebugLoc DL = MI->getDebugLoc();
23234 MachineInstr *ResumeMI = Subtarget.getFrameLowering()->emitStackProbe(
23235 *BB->getParent(), *BB, MI, DL, false);
23236 MachineBasicBlock *ResumeBB = ResumeMI->getParent();
23237 MI->eraseFromParent(); // The pseudo instruction is gone now.
23238 return ResumeBB;
23239 }
23240
23241 MachineBasicBlock *
2322523242 X86TargetLowering::EmitLoweredCatchRet(MachineInstr *MI,
2322623243 MachineBasicBlock *BB) const {
2322723244 MachineFunction *MF = BB->getParent();
2368323700 case X86::TLS_base_addr32:
2368423701 case X86::TLS_base_addr64:
2368523702 return EmitLoweredTLSAddr(MI, BB);
23703 case X86::WIN_ALLOCA:
23704 return EmitLoweredWinAlloca(MI, BB);
2368623705 case X86::CATCHRET:
2368723706 return EmitLoweredCatchRet(MI, BB);
2368823707 case X86::CATCHPAD:
11611161 MachineBasicBlock *EmitLoweredAtomicFP(MachineInstr *I,
11621162 MachineBasicBlock *BB) const;
11631163
1164 MachineBasicBlock *EmitLoweredWinAlloca(MachineInstr *MI,
1165 MachineBasicBlock *BB) const;
1166
11641167 MachineBasicBlock *EmitLoweredCatchRet(MachineInstr *MI,
11651168 MachineBasicBlock *BB) const;
11661169
9898 (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)),
9999 (implicit EFLAGS)]>;
100100
101
102 // When using segmented stacks these are lowered into instructions which first
103 // check if the current stacklet has enough free memory. If it does, memory is
104 // allocated by bumping the stack pointer. Otherwise memory is allocated from
105 // the heap.
106
107 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in
108 def SEG_ALLOCA_32 : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$size),
109 "# variable sized alloca for segmented stacks",
110 [(set GR32:$dst,
111 (X86SegAlloca GR32:$size))]>,
112 Requires<[NotLP64]>;
113
114 let Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in
115 def SEG_ALLOCA_64 : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$size),
116 "# variable sized alloca for segmented stacks",
117 [(set GR64:$dst,
118 (X86SegAlloca GR64:$size))]>,
119 Requires<[In64BitMode]>;
120 }
121
122101 // Dynamic stack allocation yields a _chkstk or _alloca call for all Windows
123102 // targets. These calls are needed to probe the stack when allocating more than
124103 // 4k bytes in one go. Touching the stack at 4K increments is necessary to
128107 // (compared to ordinary calls) like stack pointer change.
129108
130109 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in
131 def WIN_ALLOCA_32 : I<0, Pseudo, (outs), (ins GR32:$size),
110 def WIN_ALLOCA : I<0, Pseudo, (outs), (ins),
132111 "# dynamic stack allocation",
133 [(X86WinAlloca GR32:$size)]>,
134 Requires<[NotLP64]>;
112 [(X86WinAlloca)]>;
113
114 // When using segmented stacks these are lowered into instructions which first
115 // check if the current stacklet has enough free memory. If it does, memory is
116 // allocated by bumping the stack pointer. Otherwise memory is allocated from
117 // the heap.
118
119 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in
120 def SEG_ALLOCA_32 : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$size),
121 "# variable sized alloca for segmented stacks",
122 [(set GR32:$dst,
123 (X86SegAlloca GR32:$size))]>,
124 Requires<[NotLP64]>;
135125
136126 let Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in
137 def WIN_ALLOCA_64 : I<0, Pseudo, (outs), (ins GR64:$size),
138 "# dynamic stack allocation",
139 [(X86WinAlloca GR64:$size)]>,
140 Requires<[In64BitMode]>;
141
127 def SEG_ALLOCA_64 : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$size),
128 "# variable sized alloca for segmented stacks",
129 [(set GR64:$dst,
130 (X86SegAlloca GR64:$size))]>,
131 Requires<[In64BitMode]>;
132 }
142133
143134 //===----------------------------------------------------------------------===//
144135 // EH Pseudo Instructions
110110 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
111111
112112 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
113
114 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
115113
116114 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
117115
274272
275273 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
276274
277 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
278 [SDNPHasChain, SDNPOutGlue]>;
275 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDTX86Void,
276 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
279277
280278 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
281279 [SDNPHasChain]>;
9797 /// True if this function uses the red zone.
9898 bool UsesRedZone = false;
9999
100 /// True if this function has WIN_ALLOCA instructions.
101 bool HasWinAlloca = false;
102
103100 private:
104101 /// ForwardedMustTailRegParms - A list of virtual and physical registers
105102 /// that must be forwarded to every musttail call.
174171
175172 bool getUsesRedZone() const { return UsesRedZone; }
176173 void setUsesRedZone(bool V) { UsesRedZone = V; }
177
178 bool hasWinAlloca() const { return HasWinAlloca; }
179 void setHasWinAlloca(bool v) { HasWinAlloca = v; }
180174 };
181175
182176 } // End llvm namespace
265265 addPass(createX86OptimizeLEAs());
266266
267267 addPass(createX86CallFrameOptimization());
268 addPass(createX86WinAllocaExpander());
269268 }
270269
271270 void X86PassConfig::addPostRegAlloc() {
+0
-294
lib/Target/X86/X86WinAllocaExpander.cpp less more
None //===----- X86WinAllocaExpander.cpp - Expand WinAlloca pseudo instruction -===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a pass that expands WinAlloca pseudo-instructions.
10 //
11 // It performs a conservative analysis to determine whether each allocation
12 // falls within a region of the stack that is safe to use, or whether stack
13 // probes must be emitted.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "X86.h"
18 #include "X86InstrBuilder.h"
19 #include "X86InstrInfo.h"
20 #include "X86MachineFunctionInfo.h"
21 #include "X86Subtarget.h"
22 #include "llvm/ADT/PostOrderIterator.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetInstrInfo.h"
30
31 using namespace llvm;
32
33 namespace {
34
35 class X86WinAllocaExpander : public MachineFunctionPass {
36 public:
37 X86WinAllocaExpander() : MachineFunctionPass(ID) {}
38
39 bool runOnMachineFunction(MachineFunction &MF) override;
40
41 private:
42 /// Strategies for lowering a WinAlloca.
43 enum Lowering { TouchAndSub, Sub, Probe };
44
45 /// Deterministic-order map from WinAlloca instruction to desired lowering.
46 typedef MapVector LoweringMap;
47
48 /// Compute which lowering to use for each WinAlloca instruction.
49 void computeLowerings(MachineFunction &MF, LoweringMap& Lowerings);
50
51 /// Get the appropriate lowering based on current offset and amount.
52 Lowering getLowering(int64_t CurrentOffset, int64_t AllocaAmount);
53
54 /// Lower a WinAlloca instruction.
55 void lower(MachineInstr* MI, Lowering L);
56
57 MachineRegisterInfo *MRI;
58 const X86Subtarget *STI;
59 const TargetInstrInfo *TII;
60 const X86RegisterInfo *TRI;
61 unsigned StackPtr;
62 unsigned SlotSize;
63 int64_t StackProbeSize;
64
65 const char *getPassName() const override { return "X86 WinAlloca Expander"; }
66 static char ID;
67 };
68
69 char X86WinAllocaExpander::ID = 0;
70
71 } // end anonymous namespace
72
73 FunctionPass *llvm::createX86WinAllocaExpander() {
74 return new X86WinAllocaExpander();
75 }
76
77 /// Return the allocation amount for a WinAlloca instruction, or -1 if unknown.
78 static int64_t getWinAllocaAmount(MachineInstr *MI, MachineRegisterInfo *MRI) {
79 assert(MI->getOpcode() == X86::WIN_ALLOCA_32 ||
80 MI->getOpcode() == X86::WIN_ALLOCA_64);
81 assert(MI->getOperand(0).isReg());
82
83 unsigned AmountReg = MI->getOperand(0).getReg();
84 MachineInstr *Def = MRI->getUniqueVRegDef(AmountReg);
85
86 // Look through copies.
87 while (Def && Def->isCopy() && Def->getOperand(1).isReg())
88 Def = MRI->getUniqueVRegDef(Def->getOperand(1).getReg());
89
90 if (!Def ||
91 (Def->getOpcode() != X86::MOV32ri && Def->getOpcode() != X86::MOV64ri) ||
92 !Def->getOperand(1).isImm())
93 return -1;
94
95 return Def->getOperand(1).getImm();
96 }
97
98 X86WinAllocaExpander::Lowering
99 X86WinAllocaExpander::getLowering(int64_t CurrentOffset,
100 int64_t AllocaAmount) {
101 // For a non-constant amount or a large amount, we have to probe.
102 if (AllocaAmount < 0 || AllocaAmount > StackProbeSize)
103 return Probe;
104
105 // If it fits within the safe region of the stack, just subtract.
106 if (CurrentOffset + AllocaAmount <= StackProbeSize)
107 return Sub;
108
109 // Otherwise, touch the current tip of the stack, then subtract.
110 return TouchAndSub;
111 }
112
113 static bool isPushPop(const MachineInstr &MI) {
114 switch (MI.getOpcode()) {
115 case X86::PUSH32i8:
116 case X86::PUSH32r:
117 case X86::PUSH32rmm:
118 case X86::PUSH32rmr:
119 case X86::PUSHi32:
120 case X86::PUSH64i8:
121 case X86::PUSH64r:
122 case X86::PUSH64rmm:
123 case X86::PUSH64rmr:
124 case X86::PUSH64i32:
125 case X86::POP32r:
126 case X86::POP64r:
127 return true;
128 default:
129 return false;
130 }
131 }
132
133 void X86WinAllocaExpander::computeLowerings(MachineFunction &MF,
134 LoweringMap &Lowerings) {
135 // Do a one-pass reverse post-order walk of the CFG to conservatively estimate
136 // the offset between the stack pointer and the lowest touched part of the
137 // stack, and use that to decide how to lower each WinAlloca instruction.
138
139 // Initialize OutOffset[B], the stack offset at exit from B, to something big.
140 DenseMap OutOffset;
141 for (MachineBasicBlock &MBB : MF)
142 OutOffset[&MBB] = INT32_MAX;
143
144 // Note: we don't know the offset at the start of the entry block since the
145 // prologue hasn't been inserted yet, and how much that will adjust the stack
146 // pointer depends on register spills, which have not been computed yet.
147
148 // Compute the reverse post-order.
149 ReversePostOrderTraversal RPO(&MF);
150
151 for (MachineBasicBlock *MBB : RPO) {
152 int64_t Offset = -1;
153 for (MachineBasicBlock *Pred : MBB->predecessors())
154 Offset = std::max(Offset, OutOffset[Pred]);
155 if (Offset == -1) Offset = INT32_MAX;
156
157 for (MachineInstr &MI : *MBB) {
158 if (MI.getOpcode() == X86::WIN_ALLOCA_32 ||
159 MI.getOpcode() == X86::WIN_ALLOCA_64) {
160 // A WinAlloca moves StackPtr, and potentially touches it.
161 int64_t Amount = getWinAllocaAmount(&MI, MRI);
162 Lowering L = getLowering(Offset, Amount);
163 Lowerings[&MI] = L;
164 switch (L) {
165 case Sub:
166 Offset += Amount;
167 break;
168 case TouchAndSub:
169 Offset = Amount;
170 break;
171 case Probe:
172 Offset = 0;
173 break;
174 }
175 } else if (MI.isCall() || isPushPop(MI)) {
176 // Calls, pushes and pops touch the tip of the stack.
177 Offset = 0;
178 } else if (MI.getOpcode() == X86::ADJCALLSTACKUP32 ||
179 MI.getOpcode() == X86::ADJCALLSTACKUP64) {
180 Offset -= MI.getOperand(0).getImm();
181 } else if (MI.getOpcode() == X86::ADJCALLSTACKDOWN32 ||
182 MI.getOpcode() == X86::ADJCALLSTACKDOWN64) {
183 Offset += MI.getOperand(0).getImm();
184 } else if (MI.modifiesRegister(StackPtr, TRI)) {
185 // Any other modification of SP means we've lost track of it.
186 Offset = INT32_MAX;
187 }
188 }
189
190 OutOffset[MBB] = Offset;
191 }
192 }
193
194 static unsigned getSubOpcode(bool Is64Bit, int64_t Amount) {
195 if (Is64Bit)
196 return isInt<8>(Amount) ? X86::SUB64ri8 : X86::SUB64ri32;
197 return isInt<8>(Amount) ? X86::SUB32ri8 : X86::SUB32ri;
198 }
199
200 void X86WinAllocaExpander::lower(MachineInstr* MI, Lowering L) {
201 DebugLoc DL = MI->getDebugLoc();
202 MachineBasicBlock *MBB = MI->getParent();
203 MachineBasicBlock::iterator I = *MI;
204
205 int64_t Amount = getWinAllocaAmount(MI, MRI);
206 if (Amount == 0) {
207 MI->eraseFromParent();
208 return;
209 }
210
211 bool Is64Bit = STI->is64Bit();
212 assert(SlotSize == 4 || SlotSize == 8);
213 unsigned RegA = (SlotSize == 8) ? X86::RAX : X86::EAX;
214
215 switch (L) {
216 case TouchAndSub:
217 assert(Amount >= SlotSize);
218
219 // Use a push to touch the top of the stack.
220 BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
221 .addReg(RegA, RegState::Undef);
222 Amount -= SlotSize;
223 if (!Amount)
224 break;
225
226 // Fall through to make any remaining adjustment.
227 case Sub:
228 assert(Amount > 0);
229 if (Amount == SlotSize) {
230 // Use push to save size.
231 BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
232 .addReg(RegA, RegState::Undef);
233 } else {
234 // Sub.
235 BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64Bit, Amount)), StackPtr)
236 .addReg(StackPtr)
237 .addImm(Amount);
238 }
239 break;
240 case Probe:
241 // The probe lowering expects the amount in RAX/EAX.
242 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY), RegA)
243 .addReg(MI->getOperand(0).getReg());
244
245 // Do the probe.
246 STI->getFrameLowering()->emitStackProbe(*MBB->getParent(), *MBB, MI, DL,
247 /*InPrologue=*/false);
248 break;
249 }
250
251 unsigned AmountReg = MI->getOperand(0).getReg();
252 MI->eraseFromParent();
253
254 // Delete the definition of AmountReg, possibly walking a chain of copies.
255 for (;;) {
256 if (!MRI->use_empty(AmountReg))
257 break;
258 MachineInstr *AmountDef = MRI->getUniqueVRegDef(AmountReg);
259 if (!AmountDef)
260 break;
261 if (AmountDef->isCopy() && AmountDef->getOperand(1).isReg())
262 AmountReg = AmountDef->getOperand(1).isReg();
263 AmountDef->eraseFromParent();
264 break;
265 }
266 }
267
268 bool X86WinAllocaExpander::runOnMachineFunction(MachineFunction &MF) {
269 if (!MF.getInfo()->hasWinAlloca())
270 return false;
271
272 MRI = &MF.getRegInfo();
273 STI = &MF.getSubtarget();
274 TII = STI->getInstrInfo();
275 TRI = STI->getRegisterInfo();
276 StackPtr = TRI->getStackRegister();
277 SlotSize = TRI->getSlotSize();
278
279 StackProbeSize = 4096;
280 if (MF.getFunction()->hasFnAttribute("stack-probe-size")) {
281 MF.getFunction()
282 ->getFnAttribute("stack-probe-size")
283 .getValueAsString()
284 .getAsInteger(0, StackProbeSize);
285 }
286
287 LoweringMap Lowerings;
288 computeLowerings(MF, Lowerings);
289 for (auto &P : Lowerings)
290 lower(P.first, P.second);
291
292 return true;
293 }
3737 ; CHECK: pushl %ebp
3838 ; CHECK: movl %esp, %ebp
3939 ; CHECK: subl ${{[0-9]+}}, %esp
40 ; CHECK: pushl %eax
41 ; CHECK: pushl %eax
40 ; CHECK: movl $8, %eax
41 ; CHECK: calll __chkstk
4242 ; CHECK: calll "??0A@@QAE@XZ"
4343 ; CHECK: calll "??0A@@QAE@XZ"
4444 ; CHECK: calll _takes_two
1414 ret void
1515 }
1616 ; CHECK-LABEL: _bar:
17 ; CHECK: pushl %eax
17 ; CHECK: calll __chkstk
1818 ; CHECK: retl
1111 entry:
1212 %args = alloca inalloca %frame
1313 %c = getelementptr %frame, %frame* %args, i32 0, i32 2
14 ; CHECK: pushl %eax
15 ; CHECK: subl $16, %esp
14 ; CHECK: movl $20, %eax
15 ; CHECK: calll __chkstk
1616 ; CHECK: movl %esp,
1717 call void @Foo_ctor(%Foo* %c)
1818 ; CHECK: leal 12(%{{.*}}),
2020 %beg = getelementptr %frame.reverse, %frame.reverse* %rev_args, i32 0, i32 0
2121 %end = getelementptr %frame.reverse, %frame.reverse* %rev_args, i32 0, i32 1
2222
23 ; CHECK: pushl %eax
24 ; CHECK: subl $20, %esp
23 ; CHECK: calll __chkstk
2524 ; CHECK: movl %esp, %[[beg:[^ ]*]]
2625 ; CHECK: leal 12(%[[beg]]), %[[end:[^ ]*]]
2726
77 define void @g() {
88 ; CHECK-LABEL: _g:
99 %b = alloca inalloca %Foo
10 ; CHECK: pushl %eax
11 ; CHECK: pushl %eax
10 ; CHECK: movl $8, %eax
11 ; CHECK: calll __chkstk
1212 %f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0
1313 %f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1
1414 store i32 13, i32* %f1
77 ; CHECK-LABEL: _a:
88 entry:
99 %b = alloca inalloca %Foo
10 ; CHECK: pushl %eax
11 ; CHECK: pushl %eax
10 ; CHECK: movl $8, %eax
11 ; CHECK: calll __chkstk
1212 %f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0
1313 %f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1
1414 store i32 13, i32* %f1
2727 ; CHECK-LABEL: _b:
2828 entry:
2929 %b = alloca inalloca %Foo
30 ; CHECK: pushl %eax
31 ; CHECK: pushl %eax
30 ; CHECK: movl $8, %eax
31 ; CHECK: calll __chkstk
3232 %f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0
3333 %f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1
3434 store i32 13, i32* %f1
4848 ; CHECK-LABEL: _c:
4949 entry:
5050 %b = alloca inalloca %Foo
51 ; CHECK: pushl %eax
52 ; CHECK: pushl %eax
51 ; CHECK: movl $8, %eax
52 ; CHECK: calll __chkstk
5353 %f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0
5454 %f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1
5555 store i32 13, i32* %f1
66 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
77 target triple = "i686-pc-windows-msvc18.0.0"
88
9 %struct.S = type { [8192 x i8] }
9 %struct.S = type { [12 x i8] }
1010
1111 define x86_thiscallcc void @call_inalloca(i1 %x) {
1212 entry:
2828 ; CHECK-LABEL: _call_inalloca: # @call_inalloca
2929 ; CHECK: pushl %ebp
3030 ; CHECK: movl %esp, %ebp
31 ; CHECK: movl $8192, %eax
31 ; CHECK: movl $12, %eax
3232 ; CHECK: calll __chkstk
3333 ; CHECK: calll _inalloca_params
3434 ; CHECK: movl %ebp, %esp
+0
-153
test/CodeGen/X86/win-alloca-expander.ll less more
None ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s
1
2 %struct.S = type { [1024 x i8] }
3 %struct.T = type { [3000 x i8] }
4 %struct.U = type { [10000 x i8] }
5
6 define void @basics() {
7 ; CHECK-LABEL: basics:
8 entry:
9 br label %bb1
10
11 ; Allocation move sizes should have been removed.
12 ; CHECK-NOT: movl $1024
13 ; CHECK-NOT: movl $3000
14
15 bb1:
16 %p0 = alloca %struct.S
17 ; The allocation is small enough not to require stack probing, but the %esp
18 ; offset after the prologue is not known, so the stack must be touched before
19 ; the pointer is adjusted.
20 ; CHECK: pushl %eax
21 ; CHECK: subl $1020, %esp
22
23 %saved_stack = tail call i8* @llvm.stacksave()
24
25 %p1 = alloca %struct.S
26 ; We know the %esp offset from above, so there is no need to touch the stack
27 ; before adjusting it.
28 ; CHECK: subl $1024, %esp
29
30 %p2 = alloca %struct.T
31 ; The offset is now 2048 bytes, so allocating a T must touch the stack again.
32 ; CHECK: pushl %eax
33 ; CHECK: subl $2996, %esp
34
35 call void @f(%struct.S* %p0)
36 ; CHECK: calll
37
38 %p3 = alloca %struct.T
39 ; The call above touched the stack, so there is room for a T object.
40 ; CHECK: subl $3000, %esp
41
42 %p4 = alloca %struct.U
43 ; The U object is large enough to require stack probing.
44 ; CHECK: movl $10000, %eax
45 ; CHECK: calll __chkstk
46
47 %p5 = alloca %struct.T
48 ; The stack probing above touched the tip of the stack, so there's room for a T.
49 ; CHECK: subl $3000, %esp
50
51 call void @llvm.stackrestore(i8* %saved_stack)
52 %p6 = alloca %struct.S
53 ; The stack restore means we lose track of the stack pointer and must probe.
54 ; CHECK: pushl %eax
55 ; CHECK: subl $1020, %esp
56
57 ; Use the pointers so they're not optimized away.
58 call void @f(%struct.S* %p1)
59 call void @g(%struct.T* %p2)
60 call void @g(%struct.T* %p3)
61 call void @h(%struct.U* %p4)
62 call void @g(%struct.T* %p5)
63 ret void
64 }
65
66 define void @loop() {
67 ; CHECK-LABEL: loop:
68 entry:
69 br label %bb1
70
71 bb1:
72 %p1 = alloca %struct.S
73 ; The entry offset is unknown; touch-and-sub.
74 ; CHECK: pushl %eax
75 ; CHECK: subl $1020, %esp
76 br label %loop1
77
78 loop1:
79 %i1 = phi i32 [ 10, %bb1 ], [ %dec1, %loop1 ]
80 %p2 = alloca %struct.S
81 ; We know the incoming offset from bb1, but from the back-edge, we assume the
82 ; worst, and therefore touch-and-sub to allocate.
83 ; CHECK: pushl %eax
84 ; CHECK: subl $1020, %esp
85 %dec1 = sub i32 %i1, 1
86 %cmp1 = icmp sgt i32 %i1, 0
87 br i1 %cmp1, label %loop1, label %end
88 ; CHECK: decl
89 ; CHECK: jg
90
91 end:
92 call void @f(%struct.S* %p1)
93 call void @f(%struct.S* %p2)
94 ret void
95 }
96
97 define void @probe_size_attribute() "stack-probe-size"="512" {
98 ; CHECK-LABEL: probe_size_attribute:
99 entry:
100 br label %bb1
101
102 bb1:
103 %p0 = alloca %struct.S
104 ; The allocation would be small enough not to require probing, if it wasn't
105 ; for the stack-probe-size attribute.
106 ; CHECK: movl $1024, %eax
107 ; CHECK: calll __chkstk
108 call void @f(%struct.S* %p0)
109 ret void
110 }
111
112 define void @cfg(i1 %x, i1 %y) {
113 ; Test that the blocks are analyzed in the correct order.
114 ; CHECK-LABEL: cfg:
115 entry:
116 br i1 %x, label %bb1, label %bb2
117
118 bb1:
119 %p1 = alloca %struct.S
120 ; CHECK: pushl %eax
121 ; CHECK: subl $1020, %esp
122 br label %bb3
123 bb2:
124 %p2 = alloca %struct.T
125 ; CHECK: pushl %eax
126 ; CHECK: subl $2996, %esp
127 br label %bb3
128
129 bb3:
130 br i1 %y, label %bb4, label %bb5
131
132 bb4:
133 %p4 = alloca %struct.S
134 ; CHECK: subl $1024, %esp
135 call void @f(%struct.S* %p4)
136 ret void
137
138 bb5:
139 %p5 = alloca %struct.T
140 ; CHECK: pushl %eax
141 ; CHECK: subl $2996, %esp
142 call void @g(%struct.T* %p5)
143 ret void
144 }
145
146
147 declare void @f(%struct.S*)
148 declare void @g(%struct.T*)
149 declare void @h(%struct.U*)
150
151 declare i8* @llvm.stacksave()
152 declare void @llvm.stackrestore(i8*)