llvm.org GIT mirror llvm / ead2d1f
[Statepoints] Support for "patchable" statepoints. Summary: This change adds two new parameters to the statepoint intrinsic, `i64 id` and `i32 num_patch_bytes`. `id` gets propagated to the ID field in the generated StackMap section. If the `num_patch_bytes` is non-zero then the statepoint is lowered to `num_patch_bytes` bytes of nops instead of a call (the spill and reload code remains unchanged). A non-zero `num_patch_bytes` is useful in situations where a language runtime requires complete control over how a call is lowered. This change brings statepoints one step closer to patchpoints. With some additional work (that is not part of this patch) it should be possible to get rid of `TargetOpcode::STATEPOINT` altogether. PlaceSafepoints generates `statepoint` wrappers with `id` set to `0xABCDEF00` (the old default value for the ID reported in the stackmap) and `num_patch_bytes` set to `0`. This can be made more sophisticated later. Reviewers: reames, pgavlin, swaroop.sridhar, AndyAyers Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9546 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237214 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
53 changed file(s) with 509 addition(s) and 373 deletion(s). Raw diff Collapse all Expand all
141141
142142 define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
143143 gc "statepoint-example" {
144 %0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
144 %0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
145145 %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 4, i32 4)
146146 ret i8 addrspace(1)* %obj.relocated
147147 }
296296 ::
297297
298298 declare i32
299 @llvm.experimental.gc.statepoint(func_type ,
299 @llvm.experimental.gc.statepoint(i64 , i32 ,
300 func_type ,
300301 i64 <#call args>. i64 ,
301302 ... (call parameters),
302303 i64 <# transition args>, ... (transition parameters),
312313 Operands:
313314 """""""""
314315
316 The 'id' operand is a constant integer that is reported as the ID
317 field in the generated stackmap. LLVM does not interpret this
318 parameter in any way and its meaning is up to the statepoint user to
319 decide. Note that LLVM is free to duplicate code containing
320 statepoint calls, and this may transform IR that had a unique 'id' per
321 lexical call to statepoint to IR that does not.
322
323 If 'num patch bytes' is non-zero then the call instruction
324 corresponding to the statepoint is not emitted and LLVM emits 'num
325 patch bytes' bytes of nops in its place. LLVM will emit code to
326 prepare the function arguments and retrieve the function return value
327 in accordance to the calling convention; the former before the nop
328 sequence and the latter after the nop sequence. It is expected that
329 the user will patch over the 'num patch bytes' bytes of nops with a
330 calling sequence specific to their runtime before executing the
331 generated machine code. There are no guarantees with respect to the
332 alignment of the nop sequence. Unlike :doc:`StackMaps` statepoints do
333 not have a concept of shadow bytes.
334
315335 The 'target' operand is the function actually being called. The
316336 target can be specified as either a symbolic LLVM function, or as an
317337 arbitrary Value of appropriate function type. Note that the function
318338 type must match the signature of the callee and the types of the 'call
319 parameters' arguments.
339 parameters' arguments. If 'num patch bytes' is non-zero then 'target'
340 has to be the constant pointer null of the appropriate function type.
320341
321342 The '#call args' operand is the number of arguments to the actual
322343 call. It must exactly match the number of arguments passed in the
505526 physical location. e.g. A stack slot may appear as a deopt location,
506527 a gc base pointer, and a gc derived pointer.
507528
508 The ID field of the 'StkMapRecord' for a statepoint is meaningless and
509 it's value is explicitly unspecified.
510
511529 The LiveOut section of the StkMapRecord will be empty for a statepoint
512530 record.
513531
8484 /// MI-level Statepoint operands
8585 ///
8686 /// Statepoint operands take the form:
87 /// , , [call arguments],
88 /// <StackMaps::ConstantOp>, >,
87 /// <id>, , , >,
88 /// [call arguments], , ,
8989 /// , ,
9090 /// , , [other args],
9191 /// [gc values]
9393 private:
9494 // These values are aboolute offsets into the operands of the statepoint
9595 // instruction.
96 enum {
97 NCallArgsPos = 0,
98 CallTargetPos = 1
99 };
96 enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
10097
10198 // These values are relative offests from the start of the statepoint meta
10299 // arguments (i.e. the end of the call arguments).
113110 /// Get starting index of non call related arguments
114111 /// (calling convention, statepoint flags, vm state and gc state).
115112 unsigned getVarIdx() const {
116 return MI->getOperand(NCallArgsPos).getImm() + 2;
117 }
118
119 /// Returns the index of the operand containing the number of non-gc non-call
120 /// arguments.
121 unsigned getNumVMSArgsIdx() const {
122 return getVarIdx() + NumVMSArgsOffset;
123 }
124
125 /// Returns the number of non-gc non-call arguments attached to the
126 /// statepoint. Note that this is the number of arguments, not the number of
127 /// operands required to represent those arguments.
128 unsigned getNumVMSArgs() const {
129 return MI->getOperand(getNumVMSArgsIdx()).getImm();
113 return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
114 }
115
116 /// Return the ID for the given statepoint.
117 uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
118
119 /// Return the number of patchable bytes the given statepoint should emit.
120 uint32_t getNumPatchBytes() const {
121 return MI->getOperand(NBytesPos).getImm();
130122 }
131123
132124 /// Returns the target of the underlying call.
446446
447447 /// \brief Create a call to the experimental.gc.statepoint intrinsic to
448448 /// start a new statepoint sequence.
449 CallInst *CreateGCStatepointCall(Value *ActualCallee,
449 CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
450 Value *ActualCallee,
450451 ArrayRef CallArgs,
451452 ArrayRef DeoptArgs,
452453 ArrayRef GCArgs,
455456 // \brief Conveninence function for the common case when CallArgs are filled
456457 // in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be
457458 // .get()'ed to get the Value pointer.
458 CallInst *CreateGCStatepointCall(Value *ActualCallee, ArrayRef CallArgs,
459 CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
460 Value *ActualCallee, ArrayRef CallArgs,
459461 ArrayRef DeoptArgs,
460462 ArrayRef GCArgs,
461463 const Twine &Name = "");
463465 /// brief Create an invoke to the experimental.gc.statepoint intrinsic to
464466 /// start a new statepoint sequence.
465467 InvokeInst *
466 CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest,
468 CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
469 Value *ActualInvokee, BasicBlock *NormalDest,
467470 BasicBlock *UnwindDest, ArrayRef InvokeArgs,
468471 ArrayRef DeoptArgs,
469472 ArrayRef GCArgs, const Twine &Name = "");
472475 // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to
473476 // get the Value *.
474477 InvokeInst *
475 CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest,
478 CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
479 Value *ActualInvokee, BasicBlock *NormalDest,
476480 BasicBlock *UnwindDest, ArrayRef InvokeArgs,
477481 ArrayRef DeoptArgs,
478482 ArrayRef GCArgs, const Twine &Name = "");
527527 // These are documented in docs/Statepoint.rst
528528
529529 def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty],
530 [llvm_anyptr_ty, llvm_i32_ty,
530 [llvm_i64_ty, llvm_i32_ty,
531 llvm_anyptr_ty, llvm_i32_ty,
531532 llvm_i32_ty, llvm_vararg_ty]>;
532533
533534 def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>;
7373 typedef typename CallSiteTy::arg_iterator arg_iterator;
7474
7575 enum {
76 ActualCalleePos = 0,
77 NumCallArgsPos = 1,
78 CallArgsBeginPos = 3,
76 IDPos = 0,
77 NumPatchBytesPos = 1,
78 ActualCalleePos = 2,
79 NumCallArgsPos = 3,
80 FlagsPos = 4,
81 CallArgsBeginPos = 5,
7982 };
8083
8184 /// Return the underlying CallSite.
8285 CallSiteTy getCallSite() { return StatepointCS; }
8386
8487 uint64_t getFlags() const {
85 return cast(StatepointCS.getArgument(2))->getZExtValue();
88 return cast(StatepointCS.getArgument(FlagsPos))
89 ->getZExtValue();
90 }
91
92 /// Return the ID associated with this statepoint.
93 uint64_t getID() {
94 const Value *IDVal = StatepointCS.getArgument(IDPos);
95 return cast(IDVal)->getZExtValue();
96 }
97
98 /// Return the number of patchable bytes associated with this statepoint.
99 uint32_t getNumPatchBytes() {
100 const Value *NumPatchBytesVal = StatepointCS.getArgument(NumPatchBytesPos);
101 uint64_t NumPatchBytes =
102 cast(NumPatchBytesVal)->getZExtValue();
103 assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
104 return NumPatchBytes;
86105 }
87106
88107 /// Return the value actually being called or invoked.
582582 // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END
583583 // nodes with all the appropriate arguments and return values.
584584
585 // TODO: Currently, all of these operands are being marked as read/write in
586 // PrologEpilougeInserter.cpp, we should special case the VMState arguments
587 // and flags to be read-only.
588 SmallVector Ops;
589
590585 // Call Node: Chain, Target, {Args}, RegMask, [Glue]
591586 SDValue Chain = CallNode->getOperand(0);
592587
633628 Glue = GCTransitionStart.getValue(1);
634629 }
635630
631 // TODO: Currently, all of these operands are being marked as read/write in
632 // PrologEpilougeInserter.cpp, we should special case the VMState arguments
633 // and flags to be read-only.
634 SmallVector Ops;
635
636 // Add the and constants.
637 Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64));
638 Ops.push_back(
639 DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32));
640
636641 // Calculate and push starting position of vmstate arguments
637642 // Get number of arguments incoming directly into call node
638643 unsigned NumCallRegArgs =
656661 pushStackMapConstant(Ops, *this, CS.getCallingConv());
657662
658663 // Add a constant argument for the flags
659 uint64_t Flags = cast(CS.getArgument(2))->getZExtValue();
664 uint64_t Flags = ISP.getFlags();
660665 assert(
661666 ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0)
662667 && "unknown flag used");
369369 // Record all the deopt and gc operands (they're contiguous and run from the
370370 // initial index to the end of the operand list)
371371 const unsigned StartIdx = opers.getVarIdx();
372 recordStackMapOpers(MI, 0xABCDEF00,
373 MI.operands_begin() + StartIdx, MI.operands_end(),
374 false);
372 recordStackMapOpers(MI, opers.getID(), MI.operands_begin() + StartIdx,
373 MI.operands_end(), false);
375374 }
376375
377376 /// Emit the stackmap header.
244244 return createCallHelper(TheFn, Ops, this, Name);
245245 }
246246
247 static std::vector getStatepointArgs(IRBuilderBase &B,
248 Value *ActualCallee,
249 ArrayRef CallArgs,
250 ArrayRef DeoptArgs,
251 ArrayRef GCArgs) {
247 static std::vector
248 getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
249 Value *ActualCallee, ArrayRef CallArgs,
250 ArrayRef DeoptArgs, ArrayRef GCArgs) {
252251 std::vector Args;
252 Args.push_back(B.getInt64(ID));
253 Args.push_back(B.getInt32(NumPatchBytes));
253254 Args.push_back(ActualCallee);
254255 Args.push_back(B.getInt32(CallArgs.size()));
255256 Args.push_back(B.getInt32((unsigned)StatepointFlags::None));
262263 return Args;
263264 }
264265
265 CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
266 ArrayRef CallArgs,
267 ArrayRef DeoptArgs,
268 ArrayRef GCArgs,
269 const Twine &Name) {
266 CallInst *IRBuilderBase::CreateGCStatepointCall(
267 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
268 ArrayRef CallArgs, ArrayRef DeoptArgs,
269 ArrayRef GCArgs, const Twine &Name) {
270270 // Extract out the type of the callee.
271271 PointerType *FuncPtrType = cast(ActualCallee->getType());
272272 assert(isa(FuncPtrType->getElementType()) &&
279279 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
280280 ArgTypes);
281281
282 std::vector Args =
283 getStatepointArgs(*this, ActualCallee, CallArgs, DeoptArgs, GCArgs);
282 std::vector Args = getStatepointArgs(
283 *this, ID, NumPatchBytes, ActualCallee, CallArgs, DeoptArgs, GCArgs);
284284 return createCallHelper(FnStatepoint, Args, this, Name);
285285 }
286286
287 CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
288 ArrayRef CallArgs,
289 ArrayRef DeoptArgs,
290 ArrayRef GCArgs,
291 const Twine &Name) {
287 CallInst *IRBuilderBase::CreateGCStatepointCall(
288 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
289 ArrayRef CallArgs, ArrayRef DeoptArgs,
290 ArrayRef GCArgs, const Twine &Name) {
292291 std::vector VCallArgs;
293292 for (auto &U : CallArgs)
294293 VCallArgs.push_back(U.get());
295 return CreateGCStatepointCall(ActualCallee, VCallArgs, DeoptArgs, GCArgs,
296 Name);
294 return CreateGCStatepointCall(ID, NumPatchBytes, ActualCallee, VCallArgs,
295 DeoptArgs, GCArgs, Name);
297296 }
298297
299298 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
300 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
299 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
300 BasicBlock *NormalDest, BasicBlock *UnwindDest,
301301 ArrayRef InvokeArgs, ArrayRef DeoptArgs,
302302 ArrayRef GCArgs, const Twine &Name) {
303303 // Extract out the type of the callee.
310310 Function *FnStatepoint = Intrinsic::getDeclaration(
311311 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
312312
313 std::vector Args =
314 getStatepointArgs(*this, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs);
313 std::vector Args = getStatepointArgs(
314 *this, ID, NumPatchBytes, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs);
315315 return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this,
316316 Name);
317317 }
318318
319319 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
320 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
321 ArrayRef InvokeArgs, ArrayRef DeoptArgs,
322 ArrayRef GCArgs, const Twine &Name) {
320 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
321 BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs,
322 ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) {
323323 std::vector VCallArgs;
324324 for (auto &U : InvokeArgs)
325325 VCallArgs.push_back(U.get());
326 return CreateGCStatepointInvoke(ActualInvokee, NormalDest, UnwindDest,
327 VCallArgs, DeoptArgs, GCArgs, Name);
326 return CreateGCStatepointInvoke(ID, NumPatchBytes, ActualInvokee, NormalDest,
327 UnwindDest, VCallArgs, DeoptArgs, GCArgs,
328 Name);
328329 }
329330
330331 CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
14981498 "reordering restrictions required by safepoint semantics",
14991499 &CI);
15001500
1501 const Value *Target = CS.getArgument(0);
1501 const Value *IDV = CS.getArgument(0);
1502 Assert(isa(IDV), "gc.statepoint ID must be a constant integer",
1503 &CI);
1504
1505 const Value *NumPatchBytesV = CS.getArgument(1);
1506 Assert(isa(NumPatchBytesV),
1507 "gc.statepoint number of patchable bytes must be a constant integer",
1508 &CI);
1509 const uint64_t NumPatchBytes =
1510 cast(NumPatchBytesV)->getSExtValue();
1511 assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!");
1512 Assert(NumPatchBytes >= 0, "gc.statepoint number of patchable bytes must be "
1513 "positive",
1514 &CI);
1515
1516 const Value *Target = CS.getArgument(2);
15021517 const PointerType *PT = dyn_cast(Target->getType());
15031518 Assert(PT && PT->getElementType()->isFunctionTy(),
15041519 "gc.statepoint callee must be of function pointer type", &CI, Target);
15051520 FunctionType *TargetFuncType = cast(PT->getElementType());
15061521
1507 const Value *NumCallArgsV = CS.getArgument(1);
1522 if (NumPatchBytes)
1523 Assert(isa(Target->stripPointerCasts()),
1524 "gc.statepoint must have null as call target if number of patchable "
1525 "bytes is non zero",
1526 &CI);
1527
1528 const Value *NumCallArgsV = CS.getArgument(3);
15081529 Assert(isa(NumCallArgsV),
15091530 "gc.statepoint number of arguments to underlying call "
15101531 "must be constant integer",
15281549 Assert(NumCallArgs == NumParams,
15291550 "gc.statepoint mismatch in number of call args", &CI);
15301551
1531 const Value *FlagsV = CS.getArgument(2);
1552 const Value *FlagsV = CS.getArgument(4);
15321553 Assert(isa(FlagsV),
15331554 "gc.statepoint flags must be constant integer", &CI);
15341555 const uint64_t Flags = cast(FlagsV)->getZExtValue();
15391560 // the type of the wrapped callee.
15401561 for (int i = 0; i < NumParams; i++) {
15411562 Type *ParamType = TargetFuncType->getParamType(i);
1542 Type *ArgType = CS.getArgument(3+i)->getType();
1563 Type *ArgType = CS.getArgument(5 + i)->getType();
15431564 Assert(ArgType == ParamType,
15441565 "gc.statepoint call argument does not match wrapped "
15451566 "function type",
15461567 &CI);
15471568 }
1548 const int EndCallArgsInx = 2+NumCallArgs;
1569
1570 const int EndCallArgsInx = 4 + NumCallArgs;
15491571
15501572 const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1);
15511573 Assert(isa(NumTransitionArgsV),
15691591 &CI);
15701592
15711593 const int ExpectedNumArgs =
1572 5 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
1594 7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
15731595 Assert(ExpectedNumArgs <= (int)CS.arg_size(),
15741596 "gc.statepoint too few arguments according to length fields", &CI);
15751597
32883310 CI.getArgOperand(0));
32893311
32903312 // Assert that result type matches wrapped callee.
3291 const Value *Target = StatepointCS.getArgument(0);
3313 const Value *Target = StatepointCS.getArgument(2);
32923314 const PointerType *PT = cast(Target->getType());
32933315 const FunctionType *TargetFuncType =
32943316 cast(PT->getElementType());
33553377 // section of the statepoint's argument
33563378 Assert(StatepointCS.arg_size() > 0,
33573379 "gc.statepoint: insufficient arguments");
3358 Assert(isa(StatepointCS.getArgument(1)),
3380 Assert(isa(StatepointCS.getArgument(3)),
33593381 "gc.statement: number of call arguments must be constant integer");
33603382 const unsigned NumCallArgs =
3361 cast(StatepointCS.getArgument(1))->getZExtValue();
3362 Assert(StatepointCS.arg_size() > NumCallArgs+3,
3383 cast(StatepointCS.getArgument(3))->getZExtValue();
3384 Assert(StatepointCS.arg_size() > NumCallArgs + 5,
33633385 "gc.statepoint: mismatch in number of call arguments");
3364 Assert(isa(StatepointCS.getArgument(NumCallArgs+3)),
3386 Assert(isa(StatepointCS.getArgument(NumCallArgs + 5)),
33653387 "gc.statepoint: number of transition arguments must be "
33663388 "a constant integer");
33673389 const int NumTransitionArgs =
3368 cast(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue();
3369 const int DeoptArgsStart = 2 + NumCallArgs + 1 + NumTransitionArgs + 1;
3390 cast(StatepointCS.getArgument(NumCallArgs + 5))
3391 ->getZExtValue();
3392 const int DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1;
33703393 Assert(isa(StatepointCS.getArgument(DeoptArgsStart)),
33713394 "gc.statepoint: number of deoptimization arguments must be "
33723395 "a constant integer");
811811 X86MCInstLower &MCIL) {
812812 assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
813813
814 // Lower call target and choose correct opcode
815 const MachineOperand &CallTarget = StatepointOpers(&MI).getCallTarget();
816 MCOperand CallTargetMCOp;
817 unsigned CallOpcode;
818 switch (CallTarget.getType()) {
819 case MachineOperand::MO_GlobalAddress:
820 case MachineOperand::MO_ExternalSymbol:
821 CallTargetMCOp = MCIL.LowerSymbolOperand(
822 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
823 CallOpcode = X86::CALL64pcrel32;
824 // Currently, we only support relative addressing with statepoints.
825 // Otherwise, we'll need a scratch register to hold the target
826 // address. You'll fail asserts during load & relocation if this
827 // symbol is to far away. (TODO: support non-relative addressing)
828 break;
829 case MachineOperand::MO_Immediate:
830 CallTargetMCOp = MCOperand::CreateImm(CallTarget.getImm());
831 CallOpcode = X86::CALL64pcrel32;
832 // Currently, we only support relative addressing with statepoints.
833 // Otherwise, we'll need a scratch register to hold the target
834 // immediate. You'll fail asserts during load & relocation if this
835 // address is to far away. (TODO: support non-relative addressing)
836 break;
837 case MachineOperand::MO_Register:
838 CallTargetMCOp = MCOperand::CreateReg(CallTarget.getReg());
839 CallOpcode = X86::CALL64r;
840 break;
841 default:
842 llvm_unreachable("Unsupported operand type in statepoint call target");
843 break;
844 }
845
846 // Emit call
847 MCInst CallInst;
848 CallInst.setOpcode(CallOpcode);
849 CallInst.addOperand(CallTargetMCOp);
850 OutStreamer->EmitInstruction(CallInst, getSubtargetInfo());
814 StatepointOpers SOpers(&MI);
815
816 if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
817 EmitNops(*OutStreamer, PatchBytes, Subtarget->is64Bit(),
818 getSubtargetInfo());
819 } else {
820 // Lower call target and choose correct opcode
821 const MachineOperand &CallTarget = SOpers.getCallTarget();
822 MCOperand CallTargetMCOp;
823 unsigned CallOpcode;
824 switch (CallTarget.getType()) {
825 case MachineOperand::MO_GlobalAddress:
826 case MachineOperand::MO_ExternalSymbol:
827 CallTargetMCOp = MCIL.LowerSymbolOperand(
828 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
829 CallOpcode = X86::CALL64pcrel32;
830 // Currently, we only support relative addressing with statepoints.
831 // Otherwise, we'll need a scratch register to hold the target
832 // address. You'll fail asserts during load & relocation if this
833 // symbol is to far away. (TODO: support non-relative addressing)
834 break;
835 case MachineOperand::MO_Immediate:
836 CallTargetMCOp = MCOperand::CreateImm(CallTarget.getImm());
837 CallOpcode = X86::CALL64pcrel32;
838 // Currently, we only support relative addressing with statepoints.
839 // Otherwise, we'll need a scratch register to hold the target
840 // immediate. You'll fail asserts during load & relocation if this
841 // address is to far away. (TODO: support non-relative addressing)
842 break;
843 case MachineOperand::MO_Register:
844 CallTargetMCOp = MCOperand::CreateReg(CallTarget.getReg());
845 CallOpcode = X86::CALL64r;
846 break;
847 default:
848 llvm_unreachable("Unsupported operand type in statepoint call target");
849 break;
850 }
851
852 // Emit call
853 MCInst CallInst;
854 CallInst.setOpcode(CallOpcode);
855 CallInst.addOperand(CallTargetMCOp);
856 OutStreamer->EmitInstruction(CallInst, getSubtargetInfo());
857 }
851858
852859 // Record our statepoint node in the same section used by STACKMAP
853860 // and PATCHPOINT
903903 if (CS.isCall()) {
904904 CallInst *ToReplace = cast(CS.getInstruction());
905905 CallInst *Call = Builder.CreateGCStatepointCall(
906 CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None,
907 None, "safepoint_token");
906 0xABCDEF00, 0, CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
907 None, None, "safepoint_token");
908908 Call->setTailCall(ToReplace->isTailCall());
909909 Call->setCallingConv(ToReplace->getCallingConv());
910910
932932 // original block.
933933 Builder.SetInsertPoint(ToReplace->getParent());
934934 InvokeInst *Invoke = Builder.CreateGCStatepointInvoke(
935 CS.getCalledValue(), ToReplace->getNormalDest(),
935 0xABCDEF00, 0, CS.getCalledValue(), ToReplace->getNormalDest(),
936936 ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
937937 Builder.getInt32(0), None, "safepoint_token");
938938
2121 %alloca = alloca i1
2222 %load2 = load i1, i1* %alloca
2323 %load3 = load i32, i32 addrspace(1)* %dparam
24 %tok = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
25 %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 5, i32 5)
24 %tok = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
25 %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 7, i32 7)
2626 %load4 = load i32, i32 addrspace(1)* %relocate
2727 %nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5
2828 %load5 = load i32, i32 addrspace(1)* %nparam
2929 ret void
3030 }
3131
32 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
33 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
32 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
33 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
1212
1313 ; function and integer
1414 define i32* @test_iAny(i32* %v) gc "statepoint-example" {
15 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %v)
16 %v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
15 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %v)
16 %v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
1717 ret i32* %v-new
1818 }
1919
2020 ; float
2121 define float* @test_fAny(float* %v) gc "statepoint-example" {
22 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, float* %v)
23 %v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 5, i32 5)
22 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, float* %v)
23 %v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 7, i32 7)
2424 ret float* %v-new
2525 }
2626
2727 ; array of integers
2828 define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" {
29 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %v)
30 %v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5)
29 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %v)
30 %v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7)
3131 ret [3 x i32]* %v-new
3232 }
3333
3434 ; vector of integers
3535 define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" {
36 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, <3 x i32>* %v)
37 %v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 5, i32 5)
36 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, <3 x i32>* %v)
37 %v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 7, i32 7)
3838 ret <3 x i32>* %v-new
3939 }
4040
4242
4343 ; struct
4444 define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" {
45 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %struct.test* %v)
46 %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 5, i32 5)
45 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %struct.test* %v)
46 %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 7, i32 7)
4747 ret %struct.test* %v-new
4848 }
4949
5050 declare zeroext i1 @return_i1()
51 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
51 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
5252 declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
5353 declare float* @llvm.experimental.gc.relocate.p0f32(i32, i32, i32)
5454 declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
2020 entry:
2121 %alloca = alloca i32 addrspace(1)*, align 8
2222 store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
23 call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)** %alloca)
23 call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)** %alloca)
2424 %rel = load i32 addrspace(1)*, i32 addrspace(1)** %alloca
2525 ret i32 addrspace(1)* %rel
2626 }
3737 entry:
3838 %alloca = alloca i32 addrspace(1)*, align 8
3939 store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
40 call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 1, i32 addrspace(1)** %alloca)
40 call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 1, i32 addrspace(1)** %alloca)
4141 ret i32 addrspace(1)* null
4242 }
4343
44 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
44 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
4545
4646
4747 ; CHECK-LABEL: .section .llvm_stackmaps
6565
6666 ; Large Constants
6767 ; Statepoint ID only
68 ; CHECK: .quad 2882400000
68 ; CHECK: .quad 0
6969
7070 ; Callsites
7171 ; The GC one
127127 ; CHECK: .short 0
128128 ; CHECK: .align 8
129129
130
1919 ; CHECK: popq %rdx
2020 ; CHECK: retq
2121 entry:
22 %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
22 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
2323 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
2424 ret i1 %call1
2525 }
3131 ; CHECK: popq %rdx
3232 ; CHECK: retq
3333 entry:
34 %safepoint_token = tail call i32 (i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0)
34 %safepoint_token = tail call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0)
3535 %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
3636 ret i32 %call1
3737 }
4343 ; CHECK: popq %rdx
4444 ; CHECK: retq
4545 entry:
46 %safepoint_token = tail call i32 (i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0)
46 %safepoint_token = tail call i32 (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0)
4747 %call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
4848 ret i32* %call1
4949 }
5555 ; CHECK: popq %rax
5656 ; CHECK: retq
5757 entry:
58 %safepoint_token = tail call i32 (float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(float ()* @return_float, i32 0, i32 0, i32 0, i32 0)
58 %safepoint_token = tail call i32 (i64, i32, float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(i64 0, i32 0, float ()* @return_float, i32 0, i32 0, i32 0, i32 0)
5959 %call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
6060 ret float %call1
6161 }
6969 ; CHECK-NEXT: popq %rdx
7070 ; CHECK-NEXT: retq
7171 entry:
72 %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %a)
73 %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
72 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %a)
73 %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
7474 %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
7575 ret i1 %call2
7676 }
8080 ; Check a statepoint wrapping a *void* returning vararg function works
8181 ; CHECK: callq varargf
8282 entry:
83 %safepoint_token = tail call i32 (void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)* @varargf, i32 2, i32 0, i32 42, i32 43, i32 0, i32 0)
83 %safepoint_token = tail call i32 (i64, i32, void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64 0, i32 0, void (i32, ...)* @varargf, i32 2, i32 0, i32 42, i32 43, i32 0, i32 0)
8484 ;; if we try to use the result from a statepoint wrapping a
8585 ;; non-void-returning varargf, we will experience a crash.
8686 ret void
8787 }
8888
89 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
89 define i1 @test_i1_return_patchable() gc "statepoint-example" {
90 ; CHECK-LABEL: test_i1_return_patchable
91 ; A patchable variant of test_i1_return
92 ; CHECK: pushq %rax
93 ; CHECK: nopl
94 ; CHECK: popq %rdx
95 ; CHECK: retq
96 entry:
97 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()*null, i32 0, i32 0, i32 0, i32 0)
98 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
99 ret i1 %call1
100 }
101
102 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
90103 declare i1 @llvm.experimental.gc.result.i1(i32)
91104
92 declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...)
105 declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...)
93106 declare i32 @llvm.experimental.gc.result.i32(i32)
94107
95 declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...)
108 declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...)
96109 declare i32* @llvm.experimental.gc.result.p0i32(i32)
97110
98 declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...)
111 declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...)
99112 declare float @llvm.experimental.gc.result.f32(i32)
100113
101 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...)
114 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...)
102115
103116 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
2424 %before = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p
2525 %cmp1 = call i1 @f(i32 addrspace(1)* %before)
2626 call void @llvm.assume(i1 %cmp1)
27 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
28 %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 5, i32 5)
27 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
28 %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 7, i32 7)
2929 %after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew
3030 %cmp2 = call i1 @f(i32 addrspace(1)* %after)
3131 ret i1 %cmp2
4343 %cmp1 = call i1 @f(i32 addrspace(1)* %v)
4444 call void @llvm.assume(i1 %cmp1)
4545 store i32 addrspace(1)* %v, i32 addrspace(1)* addrspace(1)* %p
46 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
47 %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 5, i32 5)
46 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* addrspace(1)* %p)
47 %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 7, i32 7)
4848 %after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew
4949 %cmp2 = call i1 @f(i32 addrspace(1)* %after)
5050 ret i1 %cmp2
7171 %before = load i32 addrspace(1)*, i32 addrspace(1)** %p
7272 %cmp1 = call i1 @f(i32 addrspace(1)* %before)
7373 call void @llvm.assume(i1 %cmp1)
74 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0)
74 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0)
7575 %after = load i32 addrspace(1)*, i32 addrspace(1)** %p
7676 %cmp2 = call i1 @f(i32 addrspace(1)* %after)
7777 ret i1 %cmp2
8989 %cmp1 = call i1 @f(i32 addrspace(1)* %v)
9090 call void @llvm.assume(i1 %cmp1)
9191 store i32 addrspace(1)* %v, i32 addrspace(1)** %p
92 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0)
92 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0)
9393 %after = load i32 addrspace(1)*, i32 addrspace(1)** %p
9494 %cmp2 = call i1 @f(i32 addrspace(1)* %after)
9595 ret i1 %cmp2
101101 }
102102
103103 declare void @llvm.assume(i1)
104 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
104 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
105105 declare i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32, i32, i32) #3
106
2020 ; CHECK: popq %rdx
2121 ; CHECK: retq
2222 entry:
23 %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0)
23 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0)
2424 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
2525 ret i1 %call1
2626 }
3232 ; CHECK: popq %rdx
3333 ; CHECK: retq
3434 entry:
35 %safepoint_token = tail call i32 (i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 1, i32 0, i32 0)
35 %safepoint_token = tail call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 1, i32 0, i32 0)
3636 %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
3737 ret i32 %call1
3838 }
4444 ; CHECK: popq %rdx
4545 ; CHECK: retq
4646 entry:
47 %safepoint_token = tail call i32 (i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()* @return_i32ptr, i32 0, i32 1, i32 0, i32 0)
47 %safepoint_token = tail call i32 (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 1, i32 0, i32 0)
4848 %call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
4949 ret i32* %call1
5050 }
5656 ; CHECK: popq %rax
5757 ; CHECK: retq
5858 entry:
59 %safepoint_token = tail call i32 (float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(float ()* @return_float, i32 0, i32 1, i32 0, i32 0)
59 %safepoint_token = tail call i32 (i64, i32, float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(i64 0, i32 0, float ()* @return_float, i32 0, i32 1, i32 0, i32 0)
6060 %call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
6161 ret float %call1
6262 }
7070 ; CHECK-NEXT: popq %rdx
7171 ; CHECK-NEXT: retq
7272 entry:
73 %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0, i32 addrspace(1)* %a)
74 %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
73 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 1, i32 0, i32 0, i32 addrspace(1)* %a)
74 %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
7575 %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
7676 ret i1 %call2
7777 }
8181 ; Check a statepoint wrapping a *void* returning vararg function works
8282 ; CHECK: callq varargf
8383 entry:
84 %safepoint_token = tail call i32 (void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)* @varargf, i32 2, i32 1, i32 42, i32 43, i32 0, i32 0)
84 %safepoint_token = tail call i32 (i64, i32, void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64 0, i32 0, void (i32, ...)* @varargf, i32 2, i32 1, i32 42, i32 43, i32 0, i32 0)
8585 ;; if we try to use the result from a statepoint wrapping a
8686 ;; non-void-returning varargf, we will experience a crash.
8787 ret void
9595 ; CHECK: retq
9696 entry:
9797 %val = alloca i32
98 %safepoint_token = call i32 (i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 1, i32 2, i32* %val, i64 42, i32 0)
98 %safepoint_token = call i32 (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 1, i32 2, i32* %val, i64 42, i32 0)
9999 %call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
100100 ret i32 %call1
101101 }
109109 entry:
110110 %val = alloca i32
111111 %arg = alloca i8
112 %safepoint_token = call i32 (i32 (i32, i8*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i32 (i32, i8*)* @return_i32_with_args, i32 2, i32 1, i32 0, i8* %arg, i32 2, i32* %val, i64 42, i32 0)
112 %safepoint_token = call i32 (i64, i32, i32 (i32, i8*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i64 0, i32 0, i32 (i32, i8*)* @return_i32_with_args, i32 2, i32 1, i32 0, i8* %arg, i32 2, i32* %val, i64 42, i32 0)
113113 %call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
114114 ret i32 %call1
115115 }
116116
117 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
117 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
118118 declare i1 @llvm.experimental.gc.result.i1(i32)
119119
120 declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...)
121 declare i32 @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i32 (i32, i8*)*, i32, i32, ...)
120 declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...)
121 declare i32 @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i64, i32, i32 (i32, i8*)*, i32, i32, ...)
122122 declare i32 @llvm.experimental.gc.result.i32(i32)
123123
124 declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...)
124 declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...)
125125 declare i32* @llvm.experimental.gc.result.p0i32(i32)
126126
127 declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...)
127 declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...)
128128 declare float @llvm.experimental.gc.result.f32(i32)
129129
130 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...)
130 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...)
131131
132 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
132 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
1212 ; CHECK: .Ltmp{{[0-9]+}}:
1313 ; CHECK: callq some_other_call
1414 ; CHECK: .Ltmp{{[0-9]+}}:
15 %0 = invoke i32 (i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)* @some_other_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
15 %0 = invoke i32 (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 0, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @some_other_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
1616 to label %normal_return unwind label %exceptional_return
1717
1818 normal_return:
3535 ; CHECK: .byte 0
3636 ; CHECK: .align 4
3737
38 declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...)
39 declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32)
38 declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...)
39 declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32)
1313 ; CHECK: movq %rdi, 16(%rsp)
1414 ; CHECK: movq %rdx, 8(%rsp)
1515 ; CHECK: movq %rsi, (%rsp)
16 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
17 %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10)
18 %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 11)
19 %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 12)
16 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
17 %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 12)
18 %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 13)
19 %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 14)
2020 ; CHECK: callq
2121 ; This is the key check. There should NOT be any memory moves here
2222 ; CHECK-NOT: movq
23 %safepoint_token2 = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
24 %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 12)
25 %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 11)
26 %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 10)
23 %safepoint_token2 = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
24 %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 14)
25 %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 13)
26 %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 12)
2727 ; CHECK: callq
2828 ret i32 1
2929 }
3636 ; CHECK: movq %rdi, 16(%rsp)
3737 ; CHECK: movq %rdx, 8(%rsp)
3838 ; CHECK: movq %rsi, (%rsp)
39 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
40 %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10)
41 %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 11)
42 %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 12)
39 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c)
40 %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 12)
41 %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 13)
42 %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 14)
4343 ; CHECK: callq
4444 ; This is the key check. There should NOT be any memory moves here
4545 ; CHECK-NOT: movq
46 %safepoint_token2 = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 addrspace(1)* %a1, i32 0, i32 addrspace(1)* %c1, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
47 %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 12)
48 %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 11)
49 %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 10)
46 %safepoint_token2 = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 addrspace(1)* %a1, i32 0, i32 addrspace(1)* %c1, i32 0, i32 0, i32 addrspace(1)* %c1, i32 addrspace(1)* %b1, i32 addrspace(1)* %a1)
47 %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 14)
48 %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 13)
49 %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 12)
5050 ; CHECK: callq
5151 ret i32 1
5252 }
5454 ; Function Attrs: nounwind
5555 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
5656
57 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
57 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
5858
59 attributes #1 = { uwtable }
59 attributes #1 = { uwtable }
2323 %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
2424 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
2525 %ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg
26 %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
26 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
2727 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
28 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
29 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 8)
30 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
28 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
29 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10)
30 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 11, i32 11)
3131 ;
3232 ret i1 %call1
3333 }
5151 entry:
5252 %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
5353 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
54 %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
54 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
5555 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
56 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
57 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 8)
58 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
56 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
57 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10)
58 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 11, i32 11)
5959 ;
6060 ret i1 %call1
6161 }
6262
63
64 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
63 ; Simple test case to check that we emit the ID field correctly
64 define i1 @test_id() gc "statepoint-example" {
65 ; CHECK-LABEL: test_id
66 entry:
67 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 237, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
68 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
69 ret i1 %call1
70 }
71
72
73 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
6574 declare i1 @llvm.experimental.gc.result.i1(i32)
6675 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
6776
7281 ; CHECK-NEXT: .byte 0
7382 ; CHECK-NEXT: .short 0
7483 ; Num Functions
75 ; CHECK-NEXT: .long 2
84 ; CHECK-NEXT: .long 3
7685 ; Num LargeConstants
7786 ; CHECK-NEXT: .long 0
7887 ; Num Callsites
79 ; CHECK-NEXT: .long 2
88 ; CHECK-NEXT: .long 3
8089
8190 ; Functions and stack size
8291 ; CHECK-NEXT: .quad test
9099
91100 ; Large Constants
92101 ; Statepoint ID only
93 ; CHECK: .quad 2882400000
102 ; CHECK: .quad 0
94103
95104 ; Callsites
96105 ; Constant arguments
164173
165174 ; Large Constants
166175 ; Statepoint ID only
167 ; CHECK: .quad 2882400000
176 ; CHECK: .quad 0
168177
169178 ; Callsites
170179 ; Constant arguments
226235 ; CHECK: .short 0
227236 ; CHECK: .short 0
228237 ; CHECK: .align 8
238
239 ; Records for the test_id function:
240 ; No large constants
241
242 ; The Statepoint ID:
243 ; CHECK: .quad 237
244
245 ; Instruction Offset
246 ; CHECK: .long .Ltmp5-test_id
247
248 ; Reserved:
249 ; CHECK: .short 0
250
251 ; NumLocations:
252 ; CHECK: .short 3
253
254 ; StkMapRecord[0]:
255 ; SmallConstant(0):
256 ; CHECK: .byte 4
257 ; CHECK: .byte 8
258 ; CHECK: .short 0
259 ; CHECK: .long 0
260
261 ; StkMapRecord[1]:
262 ; SmallConstant(0):
263 ; CHECK: .byte 4
264 ; CHECK: .byte 8
265 ; CHECK: .short 0
266 ; CHECK: .long 0
267
268 ; StkMapRecord[2]:
269 ; SmallConstant(0):
270 ; CHECK: .byte 4
271 ; CHECK: .byte 8
272 ; CHECK: .short 0
273 ; CHECK: .long 0
274
275 ; No padding or LiveOuts
276 ; CHECK: .short 0
277 ; CHECK: .short 0
278 ; CHECK: .align 8
279
99 ; CHECK: getelementptr i32, i32* %base-new, i32 15
1010 entry:
1111 %ptr = getelementptr i32, i32* %base, i32 15
12 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
13 %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
14 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
12 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
13 %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
14 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
1515 %ret = load i32, i32* %ptr-new
1616 ret i32 %ret
1717 }
2424 entry:
2525 %ptr = getelementptr i32, i32* %base, i32 15
2626 %ptr2 = getelementptr i32, i32* %base, i32 12
27 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
28 %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
29 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
30 %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7)
27 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
28 %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
29 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
30 %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9)
3131 %ret = load i32, i32* %ptr-new
3232 ret i32 %ret
3333 }
3737 ; CHECK: getelementptr i32, i32* %base-new, i32 15
3838 entry:
3939 %ptr = getelementptr i32, i32* %base, i32 15
40 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
41 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
42 %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5)
40 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
41 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
42 %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7)
4343 %ret = load i32, i32* %ptr-new
4444 ret i32 %ret
4545 }
4949 ; CHECK: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 2
5050 entry:
5151 %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2
52 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
53 %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5)
54 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
52 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
53 %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7)
54 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
5555 %ret = load i32, i32* %ptr-new
5656 ret i32 %ret
5757 }
6161 ; CHECK-NOT: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 21
6262 entry:
6363 %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21
64 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
65 %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5)
66 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
64 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
65 %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7)
66 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
6767 %ret = load i32, i32* %ptr-new
6868 ret i32 %ret
6969 }
7070
7171 define i32 @test_sor_noop(i32* %base) gc "statepoint-example" {
7272 ; CHECK: getelementptr i32, i32* %base, i32 15
73 ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
74 ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7)
73 ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
74 ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9)
7575 entry:
7676 %ptr = getelementptr i32, i32* %base, i32 15
7777 %ptr2 = getelementptr i32, i32* %base, i32 12
78 %tok = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
79 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6)
80 %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7)
78 %tok = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
79 %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8)
80 %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9)
8181 %ret = load i32, i32* %ptr-new
8282 ret i32 %ret
8383 }
8484
85 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
85 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
8686 declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
8787 declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
55 ; then the return attribute of gc.relocate is dereferenceable(N).
66
77 declare zeroext i1 @return_i1()
8 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
8 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
99 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
1010
1111 define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" {
1414 ; CHECK: call dereferenceable(8)
1515 entry:
1616 %load = load i32, i32 addrspace(1)* %dparam
17 %tok = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
18 %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 5, i32 5)
17 %tok = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
18 %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 7, i32 7)
1919 ret i32 addrspace(1)* %relocate
2020 }
66
77 define i1 @test_negative(i32 addrspace(1)* %p) gc "statepoint-example" {
88 entry:
9 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
10 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
9 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
10 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
1111 %cmp = icmp eq i32 addrspace(1)* %pnew, null
1212 ret i1 %cmp
1313 ; CHECK-LABEL: test_negative
1717
1818 define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) gc "statepoint-example" {
1919 entry:
20 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
21 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
20 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
21 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
2222 %cmp = icmp eq i32 addrspace(1)* %pnew, null
2323 ret i1 %cmp
2424 ; CHECK-LABEL: test_nonnull
2727
2828 define i1 @test_null() gc "statepoint-example" {
2929 entry:
30 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* null)
31 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
30 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* null)
31 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
3232 %cmp = icmp eq i32 addrspace(1)* %pnew, null
3333 ret i1 %cmp
3434 ; CHECK-LABEL: test_null
3838
3939 define i1 @test_undef() gc "statepoint-example" {
4040 entry:
41 %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* undef)
42 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5)
41 %safepoint_token = tail call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* undef)
42 %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
4343 %cmp = icmp eq i32 addrspace(1)* %pnew, null
4444 ret i1 %cmp
4545 ; CHECK-LABEL: test_undef
4747 ; CHECK: ret i1 undef
4848 }
4949
50 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
50 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
5151 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
7272 ; inserted for a function that takes 1 argument.
7373 ; CHECK: gc.statepoint.p0f_isVoidf
7474 ; CHECK: gc.statepoint.p0f_i1i1f
75 ; CHECK: (i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0)
75 ; CHECK: (i64 2882400000, i32 0, i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0)
7676 ; CHECK: %call1.2 = call i1 @llvm.experimental.gc.result.i1
7777 entry:
7878 %call1 = tail call i1 (i1) @i1_return_i1(i1 false)
1414
1515 loop:
1616 ; CHECK-LABEL: loop
17 ; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo
17 ; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo
1818 ; CHECK-NOT: statepoint
1919 call void @foo()
2020 br label %loop
7676 entry:
7777 call void @do_safepoint()
7878 ret void
79 }
79 }
107107 entry:
108108 call void @do_safepoint()
109109 ret void
110 }
110 }
4242 entry:
4343 call void @do_safepoint()
4444 ret void
45 }
45 }
2525 entry:
2626 call void @do_safepoint()
2727 ret void
28 }
28 }
1919 ; CHECK-LABEL: merge:
2020 ; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %here ], [ %base_obj_y, %there ]
2121 %merged_value = phi i64 addrspace(1)* [ %x, %here ], [ %y, %there ]
22 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
22 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
2323 ret i64 addrspace(1)* %merged_value
2424 }
2525
2626 declare void @foo()
27 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
27 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
2929
3030 merge:
3131 %next = phi i64 addrspace(1)* [ %next_x, %true ], [ %next_y, %false ]
32 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
32 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
3333 br label %loop
3434 }
3535
36 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
36 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1818 ; CHECK-DAG: [ %next.relocated.casted, %loop ]
1919 %current = phi i64 addrspace(1)* [ %obj, %entry ], [ %next, %loop ]
2020 %next = getelementptr i64, i64 addrspace(1)* %current, i32 1
21 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
21 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
2222 br label %loop
2323 }
2424
25 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
25 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1212
1313 merge:
1414 %merged_value = phi i64 addrspace(1)* [ %base_obj, %entry ], [ %derived_obj, %there ]
15 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
15 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
1616 ret i64 addrspace(1)* %merged_value
1717 }
1818
1919 declare void @foo()
20 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
20 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1111 %current.i32 = bitcast i64 addrspace(1)* %current to i32 addrspace(1)*
1212 %next.i32 = getelementptr i32, i32 addrspace(1)* %current.i32, i32 1
1313 %next.i64 = bitcast i32 addrspace(1)* %next.i32 to i64 addrspace(1)*
14 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
14 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
1515 br label %loop
1616 }
1717
1818 declare void @do_safepoint()
19 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
19 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1212
1313 loop:
1414 ; CHECK: loop:
15 ; CHECK: %safepoint_token1 = call i32 (i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i3
15 ; CHECK: %safepoint_token1 = call i32 (i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 0, i32 0, i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i3
1616 ; CHECK-NEXT: %obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result
17 %safepoint_token1 = call i32 (i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
17 %safepoint_token1 = call i32 (i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 0, i32 0, i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
1818 %obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32 %safepoint_token1)
1919 switch i32 %condition, label %dest_a [
2020 i32 0, label %dest_b
3636 ; CHECK: %obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ]
3737
3838 %obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ]
39 %safepoint_token3 = call i32 (void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* %obj_to_consume, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
39 %safepoint_token3 = call i32 (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* %obj_to_consume, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
4040 br label %merge.split
4141
4242 merge.split: ; preds = %merge
43 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
43 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
4444 br label %loop
4545 }
4646
4747
4848 ; Function Attrs: nounwind
4949 declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32) #0
50 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
51 declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()*, i32, i32, ...)
52 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)*, i32, i32, ...)
50 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
51 declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64, i32, i64 addrspace(1)* ()*, i32, i32, ...)
52 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...)
2222 ; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %base_obj_y, %there ]
2323 ; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ]
2424 %merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ]
25 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
25 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
2626 ret i64 addrspace(1)* %merged_value
2727 }
2828
29 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
30
29 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
3232 ; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %merge_here ], [ %base_obj_y, %there ]
3333 ; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
3434 %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
35 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
35 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
3636 ret i64 addrspace(1)* %merged_value
3737 }
3838
3939 declare void @do_safepoint()
40 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
40 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
4343 ; CHECK: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
4444 %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ]
4545
46 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
46 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @site_for_call_safpeoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
4747 ret i64 addrspace(1)* %merged_value
4848 }
4949
5050 declare void @do_safepoint()
51 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
52
51 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
2323 loop_back:
2424 %next_element_ptr = getelementptr i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* %current_element_ptr, i32 1
2525 %next_index = add i32 %index, 1
26 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
26 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
2727 br label %loop_check
2828
2929 not_found:
3434 }
3535
3636 declare void @do_safepoint()
37 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
37 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1212 %condition = call i1 @runtime_value()
1313 %maybe_next = getelementptr i64, i64 addrspace(1)* %current, i32 1
1414 %next = select i1 %condition, i64 addrspace(1)* %maybe_next, i64 addrspace(1)* %current
15 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
15 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
1616 br label %loop
1717 }
1818
1919 declare void @do_safepoint()
20 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
20 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1515 ; CHECK-DAG: [ %obj.relocated.casted, %loop ]
1616 ; CHECK-DAG: [ %obj, %entry ]
1717 call void @use_obj(i64 addrspace(1)* %obj)
18 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
18 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
1919 br label %loop
2020 }
2121
5656 ; CHECK: merge:
5757 ; CHECK-NEXT: %base_phi = phi i64 addrspace(1)* [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_R]], %right ], !is_base_value !0
5858 %value = phi i64 addrspace(1)* [ %a.cast, %left], [ %a.cast, %left], [ %a.cast, %left], [ %b.cast, %right]
59 %safepoint_token = call i32 (void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)* @parse_point, i32 1, i32 0, i64 addrspace(1)* %value, i32 0, i32 5, i32 0, i32 0, i32 0, i32 0, i32 0)
59 %safepoint_token = call i32 (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @parse_point, i32 1, i32 0, i64 addrspace(1)* %value, i32 0, i32 5, i32 0, i32 0, i32 0, i32 0, i32 0)
6060
6161 ret i64 addrspace(1)* %value
6262 }
9090 %nexta = getelementptr i64, i64 addrspace(1)* %current, i32 1
9191 %next = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
9292 %extra2 = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
93 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
93 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
9494 br label %loop
9595 }
9696
9797 declare void @foo()
98 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
99 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)*, i32, i32, ...)
98 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
99 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...)
99 ; CHECK-NEXT: gc.statepoint
1010 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
1111 entry:
12 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
12 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
1313 ret i8 addrspace(1)* %obj
1414 }
1515
2222 ; CHECK-NEXT: gc.statepoint
2323 ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
2424 entry:
25 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
26 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
25 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
26 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
2727 ret i8 addrspace(1)* %obj
2828 }
2929
3838 ; CHECK-NEXT: load i8, i8 addrspace(1)* %obj.relocated
3939 entry:
4040 %derived = getelementptr i8, i8 addrspace(1)* %obj, i64 10
41 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
41 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
4242
4343 %a = load i8, i8 addrspace(1)* %derived
4444 %b = load i8, i8 addrspace(1)* %obj
5656 ; CHECK-LABEL: taken:
5757 ; CHECK-NEXT: gc.statepoint
5858 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
59 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
59 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
6060 br label %merge
6161
6262 untaken:
6363 ; CHECK-LABEL: untaken:
6464 ; CHECK-NEXT: gc.statepoint
6565 ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
66 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
66 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
6767 br label %merge
6868
6969 merge:
8080 ; CHECK-NEXT: gc.statepoint
8181 ; CHECK-NOT: %obj.relocated = call coldcc i8 addrspace(1)*
8282 entry:
83 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
83 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
8484 ret i8 addrspace(1)* %obj
8585 }
8686
87 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
87 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
0 ; RUN: opt -S -rewrite-statepoints-for-gc %s | FileCheck %s
11
22 declare void @foo()
3 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
3 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
44
55 ; constants don't get relocated.
66 define i8 @test() gc "statepoint-example" {
88 ; CHECK: gc.statepoint
99 ; CHECK-NEXT: load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*)
1010 entry:
11 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
11 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
1212 %res = load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*)
1313 ret i8 %res
1414 }
2121 ; CHECK-NEXT: gc.relocate
2222 ; CHECK-NEXT: icmp
2323 entry:
24 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
24 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
2525 %cmp = icmp eq i8 addrspace(1)* %p, null
2626 br i1 %cmp, label %taken, label %not_taken
2727
5151 ; CHECK: gc.statepoint
5252 ; CHECK-NEXT: load i8, i8 addrspace(1)* @G
5353 entry:
54 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
54 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
5555 %res = load i8, i8 addrspace(1)* @G, align 1
5656 ret i8 %res
5757 }
5858
5959
60
77
88 declare void @foo()
99 declare void @use(...)
10 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
10 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1111
1212 define void @test1(<2 x i32 addrspace(1)*> addrspace(1)* %obj) gc "statepoint-example" {
1313 entry:
14 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
15 ; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 5, i32 5)
14 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
15 ; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 7, i32 7)
1616 ; CHECK-NEXT: %obj.relocated.casted = bitcast i8 addrspace(1)* %obj.relocated to <2 x i32 addrspace(1)*> addrspace(1)*
1717 call void (...) @use(<2 x i32 addrspace(1)*> addrspace(1)* %obj)
1818 ret void
19 }
19 }
99 ; CHECK-NEXT: bitcast
1010 ; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
1111 entry:
12 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
12 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
1313 ret i64 addrspace(1)* %obj
1414 }
1515
2727 ; CHECK-NEXT: insertelement
2828 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
2929 entry:
30 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
30 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
3131 ret <2 x i64 addrspace(1)*> %obj
3232 }
3333
4747 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
4848 entry:
4949 %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
50 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
50 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
5151 ret <2 x i64 addrspace(1)*> %obj
5252 }
5353
6262 ; CHECK-NEXT: gc.statepoint
6363 entry:
6464 %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
65 invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
65 invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
6666 to label %normal_return unwind label %exceptional_return
6767
6868 ; CHECK-LABEL: normal_return:
111111 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
112112 entry:
113113 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
114 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
114 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
115115 ret <2 x i64 addrspace(1)*> %vec
116116 }
117117
118118 declare void @do_safepoint()
119119
120 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
120 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1515 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
1616 ; CHECK-NEXT: bitcast
1717 ; CHECK-NEXT: br label %merge
18 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
18 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
1919 br label %merge
2020
2121 untaken:
2424 ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
2525 ; CHECK-NEXT: bitcast
2626 ; CHECK-NEXT: br label %merge
27 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
27 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
2828 br label %merge
2929
3030 merge:
4141 ; CHECK-LABEL: entry:
4242 ; CHECK-NEXT: gc.statepoint
4343 ; CHECK-NEXT: br
44 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
44 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
4545 br i1 %cmp, label %taken, label %untaken
4646
4747 taken:
5353 ; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
5454
5555 %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
56 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
56 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
5757 ret i64 addrspace(1)* %obj
5858
5959 untaken:
7575 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
7676 ; CHECK-NEXT: bitcast
7777 ; CHECK-NEXT: br label %merge
78 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
78 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
7979 %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
80 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
80 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
8181 br label %merge
8282
8383 untaken:
8484 ; CHECK-LABEL: taken:
8585 ; CHECK-NEXT: gc.statepoint
8686 ; CHECK-NEXT: br label %merge
87 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
87 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
8888 br label %merge
8989
9090 merge:
113113 ; CHECK-NEXT: ret i64 addrspace(1)* %derived.relocated1.casted
114114 ;
115115 %derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8
116 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
116 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
117117
118 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
118 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
119119 ret i64 addrspace(1)* %derived
120120 }
121121
135135 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
136136 ; CHECK-NEXT: bitcast
137137 ; CHECK-NEXT: br label %merge
138 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
138 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
139139 br label %merge
140140
141141 untaken:
162162
163163 declare void @foo()
164164
165 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
166
165 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
1616 ; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
1717 ; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
1818 %obj2 = phi i64 addrspace(1)* [ %obj, %entry ]
19 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
19 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
2020 call void (...) @consume(i64 addrspace(1)* %obj2)
2121 call void (...) @consume(i64 addrspace(1)* %obj)
2222 ret void
3232
3333 unreached:
3434 %obj = phi i64 addrspace(1)* [null, %unreached]
35 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
35 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
3636 call void (...) @consume(i64 addrspace(1)* %obj)
3737 br label %unreached
3838 }
4545 ret void
4646
4747 unreached:
48 invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
48 invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
4949 to label %normal_return unwind label %exceptional_return
5050
5151 normal_return: ; preds = %entry
6161 ; Bound the last check-not
6262 ; CHECK-LABEL: @foo
6363
64 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
65
64 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
2222 normal_dest:
2323 ;; CHECK-LABEL: normal_dest:
2424 ;; CHECK-NEXT: gc.statepoint
25 ;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
26 ;; CHECK-NEXT: bitcast
27 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @gc_call, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
25 ;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
26 ;; CHECK-NEXT: bitcast
27 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @gc_call, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
2828 ret i64* addrspace(1)* %obj
2929 }
3030
31 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
31 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
3232
33
88 ; CHECK-LABEL: @test1
99 ; CHECK-DAG: %obj.relocated
1010 ; CHECK-DAG: %obj2.relocated
11 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
11 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
1212 br label %joint
1313
1414 joint:
6060 br label %loop.backedge
6161
6262 loop.backedge:
63 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
63 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
6464 br label %loop
6565
6666 loop_y:
7878 ; CHECK-LABEL: if_branch:
7979 ; CHECK: gc.statepoint
8080 ; CHECK: gc.relocate
81 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
81 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
8282 br label %join
8383
8484 else_branch:
8585 ; CHECK-LABEL: else_branch:
8686 ; CHECK: gc.statepoint
8787 ; CHECK: gc.relocate
88 %safepoint_token1 = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
88 %safepoint_token1 = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
8989 br label %join
9090
9191 join:
109109 ; CHECK-NEXT: gc.relocate
110110 ; CHECK-NEXT: bitcast
111111 ; CHECK-NEXT: gc.statepoint
112 %safepoint_token = call i32 (void (i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi64f(void (i64)* undef, i32 1, i32 0, i64 undef, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
113 %safepoint_token1 = call i32 (i32 (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i32 (i64 addrspace(1)*)* undef, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
112 %safepoint_token = call i32 (i64, i32, void (i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi64f(i64 0, i32 0, void (i64)* undef, i32 1, i32 0, i64 undef, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
113 %safepoint_token1 = call i32 (i64, i32, i32 (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i64 0, i32 0, i32 (i64 addrspace(1)*)* undef, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
114114 ret void
115115 }
116116
123123 ; CHECK: gc.statepoint
124124 ; CHECK: gc.relocate
125125 ; CHECK: @use(i8 addrspace(1)* %res.relocated)
126 %safepoint_token2 = tail call i32 (i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
126 %safepoint_token2 = tail call i32 (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 0, i32 0, i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
127127 %res = call i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32 %safepoint_token2)
128 call i32 (i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
128 call i32 (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 0, i32 0, i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
129129 call void (...) @use(i8 addrspace(1)* %res)
130130 unreachable
131131 }
135135 define void @test5(i8 addrspace(1)* %arg) gc "statepoint-example" {
136136 ; CHECK-LABEL: test5
137137 entry:
138 call i32 (i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
138 call i32 (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 0, i32 0, i8 addrspace(1)* ()* undef, i32 0, i32 0, i32 0, i32 0)
139139 switch i32 undef, label %kill [
140140 i32 10, label %merge
141141 i32 13, label %merge
169169 ; CHECK: arg1.relocated =
170170 ; CHECK: arg2.relocated =
171171 ; CHECK: arg3.relocated =
172 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 3, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2, i8 addrspace(1)* %arg3)
172 call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 3, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2, i8 addrspace(1)* %arg3)
173173 br label %gc.safepoint_poll.exit2
174174
175175 gc.safepoint_poll.exit2:
208208 ; CHECK-LABEL: outer-inc:
209209 ; CHECK: %arg1.relocated
210210 ; CHECK: %arg2.relocated
211 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
211 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
212212 br label %outer-loop
213213 }
214214
237237 ; CHECK: gc.statepoint
238238 ; CHECK: %arg1.relocated
239239 ; CHECK: %arg2.relocated
240 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
240 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 2, i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2)
241241 br i1 %cmp, label %inner-loop, label %outer-inc
242242
243243 outer-inc:
257257 br i1 %condition, label %callbb, label %join2
258258
259259 callbb:
260 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
260 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
261261 br label %join
262262
263263 join:
284284
285285 declare void @do_safepoint()
286286
287 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
288 declare i32 @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()*, i32, i32, ...)
289 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi64f(void (i64)*, i32, i32, ...)
290 declare i32 @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i32 (i64 addrspace(1)*)*, i32, i32, ...)
287 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
288 declare i32 @llvm.experimental.gc.statepoint.p0f_p1i8f(i64, i32, i8 addrspace(1)* ()*, i32, i32, ...)
289 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi64f(i64, i32, void (i64)*, i32, i32, ...)
290 declare i32 @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i64, i32, i32 (i64 addrspace(1)*)*, i32, i32, ...)
291291 declare i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32) #3
292292
293293
294294
295
0 ; RUN: not opt -verify 2>&1 < %s | FileCheck %s
1
2 ; CHECK: gc.statepoint must have null as call target if number of patchable bytes is non zero
3
4 define i1 @invalid_patchable_statepoint() gc "statepoint-example" {
5 entry:
6 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()* @func, i32 0, i32 0, i32 0, i32 0)
7 %call1 = call i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
8 ret i1 %call1
9 }
10
11 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
12 declare i1 @llvm.experimental.gc.result.i1(i32)
13 declare i1 @func()
44 declare zeroext i1 @return0i1()
55
66 ; Function Attrs: nounwind
7 declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()*, i32, i32, ...) #0
7 declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i64, i32, i1 ()*, i32, i32, ...) #0
88
99 ; Function Attrs: nounwind
1010 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #0
1111
1212 define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) {
1313 %a00 = load i32, i32 addrspace(1)* %dparam
14 %to0 = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam)
15 %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 0, i32 4)
14 %to0 = call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i64 0, i32 0, i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam)
15 %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 2, i32 6)
1616 ret i32 addrspace(1)* %relocate
1717 }
1818
19 attributes #0 = { nounwind }
19 attributes #0 = { nounwind }
44 declare void @use(...)
55 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
66 declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
7 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
7 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
88 declare i32 @"personality_function"()
99
1010 ;; Basic usage
1111 define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg, i32 %val) gc "statepoint-example" {
1212 entry:
1313 %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
14 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 %val, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
15 %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
14 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 %val, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
15 %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
1616 ret i64 addrspace(1)* %reloc
1717 }
18
22 declare void @use(...)
33 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
44 declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
5 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
5 declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
66 declare i32 @"personality_function"()
77
88 ;; Basic usage
99 define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" {
1010 entry:
1111 %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
12 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
13 %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
12 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
13 %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
1414 ;; It is perfectly legal to relocate the same value multiple times...
15 %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
16 %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 11, i32 10)
15 %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
16 %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 13, i32 12)
1717 ret i64 addrspace(1)* %reloc
1818 ; CHECK-LABEL: test1
1919 ; CHECK: statepoint
3838 ret void
3939
4040 equal:
41 %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
42 %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11)
41 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
42 %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13)
4343 call void undef(i64 addrspace(1)* %reloc)
4444 ret void
4545 ; CHECK-LABEL: test2
5656 entry:
5757 ; CHECK-LABEL: entry
5858 ; CHECK: statepoint
59 %0 = invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
59 %0 = invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
6060 to label %normal_dest unwind label %exceptional_return
6161
6262 normal_dest:
6464 ; CHECK: gc.relocate
6565 ; CHECK: gc.relocate
6666 ; CHECK: ret
67 %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10)
68 %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10)
67 %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12)
68 %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12)
6969 ret i8 addrspace(1)* %obj.relocated
7070
7171 exceptional_return:
7575 %landing_pad = landingpad { i8*, i32 } personality i32 ()* @"personality_function"
7676 cleanup
7777 %relocate_token = extractvalue { i8*, i32 } %landing_pad, 1
78 %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10)
79 %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10)
78 %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 12, i32 12)
79 %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 12, i32 12)
8080 ret i8 addrspace(1)* %obj1.relocated1
8181 }
82