Index: docs/Statepoints.rst =================================================================== --- docs/Statepoints.rst +++ docs/Statepoints.rst @@ -142,7 +142,7 @@ define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj) gc "statepoint-example" { - %0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj) + %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) %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 4, i32 4) ret i8 addrspace(1)* %obj.relocated } @@ -297,7 +297,8 @@ :: declare i32 - @llvm.experimental.gc.statepoint(func_type , + @llvm.experimental.gc.statepoint(i64 , i32 , + func_type , i64 <#call args>. i64 , ... (call parameters), i64 <# transition args>, ... (transition parameters), @@ -313,12 +314,21 @@ Operands: """"""""" +The 'id' operand is a statepoint specific ID that is reported as the +ID field in the generated stackmap. + +If 'num patch bytes' is non-zero then the statepoint is lowered to a +'num patch bytes' byte long nop sequence instead of a call. + The 'target' operand is the function actually being called. The target can be specified as either a symbolic LLVM function, or as an arbitrary Value of appropriate function type. Note that the function type must match the signature of the callee and the types of the 'call parameters' arguments. +If 'num patch bytes' is non-zero then 'target' has to be the constant +pointer null of the appropriate function type. + The '#call args' operand is the number of arguments to the actual call. It must exactly match the number of arguments passed in the 'call parameters' variable length section. @@ -500,9 +510,6 @@ physical location. e.g. A stack slot may appear as a deopt location, a gc base pointer, and a gc derived pointer. -The ID field of the 'StkMapRecord' for a statepoint is meaningless and -it's value is explicitly unspecified. - The LiveOut section of the StkMapRecord will be empty for a statepoint record. Index: include/llvm/CodeGen/StackMaps.h =================================================================== --- include/llvm/CodeGen/StackMaps.h +++ include/llvm/CodeGen/StackMaps.h @@ -85,16 +85,14 @@ /// MI-level Statepoint operands /// /// Statepoint operands take the form: -/// , , [call arguments], -/// , , +/// , , , , +/// [call arguments], , , /// , , [other args], /// [gc values] class StatepointOpers { private: - enum { - NCallArgsPos = 0, - CallTargetPos = 1 - }; + /// Enumerate the meta operands. + enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd }; public: explicit StatepointOpers(const MachineInstr *MI): @@ -103,20 +101,15 @@ /// Get starting index of non call related arguments /// (statepoint flags, vm state and gc state). unsigned getVarIdx() const { - return MI->getOperand(NCallArgsPos).getImm() + 2; + return MI->getOperand(NCallArgsPos).getImm() + MetaEnd; } - /// Returns the index of the operand containing the number of non-gc non-call - /// arguments. - unsigned getNumVMSArgsIdx() const { - return getVarIdx() + 3; - } + /// Return the ID for the given statepoint. + uint64_t getID() const { return MI->getOperand(IDPos).getImm(); } - /// Returns the number of non-gc non-call arguments attached to the - /// statepoint. Note that this is the number of arguments, not the number of - /// operands required to represent those arguments. - unsigned getNumVMSArgs() const { - return MI->getOperand(getNumVMSArgsIdx()).getImm(); + /// Return the number of patchable bytes the given statepoint should emit. + uint32_t getNumPatchBytes() const { + return MI->getOperand(NBytesPos).getImm(); } /// Returns the target of the underlying call. Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -447,7 +447,8 @@ /// \brief Create a call to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. - CallInst *CreateGCStatepointCall(Value *ActualCallee, + CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, + Value *ActualCallee, ArrayRef CallArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, @@ -456,7 +457,8 @@ // \brief Conveninence function for the common case when CallArgs are filled // in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be // .get()'ed to get the Value pointer. - CallInst *CreateGCStatepointCall(Value *ActualCallee, ArrayRef CallArgs, + CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, + Value *ActualCallee, ArrayRef CallArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); @@ -464,7 +466,8 @@ /// brief Create an invoke to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. InvokeInst * - CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest, + CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); @@ -473,7 +476,8 @@ // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to // get the Value *. InvokeInst * - CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest, + CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -528,7 +528,8 @@ // These are documented in docs/Statepoint.rst def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty], - [llvm_anyptr_ty, llvm_i32_ty, + [llvm_i64_ty, llvm_i32_ty, + llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_vararg_ty]>; def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>; Index: include/llvm/IR/Statepoint.h =================================================================== --- include/llvm/IR/Statepoint.h +++ include/llvm/IR/Statepoint.h @@ -74,16 +74,35 @@ typedef typename CallSiteTy::arg_iterator arg_iterator; enum { - ActualCalleePos = 0, - NumCallArgsPos = 1, - CallArgsBeginPos = 3, + IDPos = 0, + NumPatchBytesPos = 1, + ActualCalleePos = 2, + NumCallArgsPos = 3, + FlagsPos = 4, + CallArgsBeginPos = 5, }; /// Return the underlying CallSite. CallSiteTy getCallSite() { return StatepointCS; } uint64_t getFlags() const { - return cast(StatepointCS.getArgument(2))->getZExtValue(); + return cast(StatepointCS.getArgument(FlagsPos)) + ->getZExtValue(); + } + + /// Return the ID associated with this statepoint. + uint64_t getID() { + const Value *IDVal = StatepointCS.getArgument(IDPos); + return cast(IDVal)->getZExtValue(); + } + + /// Return the number of patchable bytes associated with this statepoint. + uint32_t getNumPatchBytes() { + const Value *NumPatchBytesVal = StatepointCS.getArgument(NumPatchBytesPos); + uint64_t NumPatchBytes = + cast(NumPatchBytesVal)->getZExtValue(); + assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!"); + return NumPatchBytes; } /// Return the value actually being called or invoked. Index: lib/CodeGen/SelectionDAG/StatepointLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -588,11 +588,6 @@ // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END // nodes with all the appropriate arguments and return values. - // TODO: Currently, all of these operands are being marked as read/write in - // PrologEpilougeInserter.cpp, we should special case the VMState arguments - // and flags to be read-only. - SmallVector Ops; - // Call Node: Chain, Target, {Args}, RegMask, [Glue] SDValue Chain = CallNode->getOperand(0); @@ -641,6 +636,16 @@ Glue = GCTransitionStart.getValue(1); } + // TODO: Currently, all of these operands are being marked as read/write in + // PrologEpilougeInserter.cpp, we should special case the VMState arguments + // and flags to be read-only. + SmallVector Ops; + + // Add the and constants. + Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64)); + Ops.push_back( + DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32)); + // Calculate and push starting position of vmstate arguments // Get number of arguments incoming directly into call node unsigned NumCallRegArgs = @@ -663,7 +668,7 @@ // Add a leading constant argument with the Flags and the calling convention // masked together CallingConv::ID CallConv = CS.getCallingConv(); - uint64_t Flags = cast(CS.getArgument(2))->getZExtValue(); + uint64_t Flags = ISP.getFlags(); assert( ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) && "unknown flag used"); Index: lib/CodeGen/StackMaps.cpp =================================================================== --- lib/CodeGen/StackMaps.cpp +++ lib/CodeGen/StackMaps.cpp @@ -370,9 +370,8 @@ // Record all the deopt and gc operands (they're contiguous and run from the // initial index to the end of the operand list) const unsigned StartIdx = opers.getVarIdx(); - recordStackMapOpers(MI, 0xABCDEF00, - MI.operands_begin() + StartIdx, MI.operands_end(), - false); + recordStackMapOpers(MI, opers.getID(), MI.operands_begin() + StartIdx, + MI.operands_end(), false); } /// Emit the stackmap header. Index: lib/IR/IRBuilder.cpp =================================================================== --- lib/IR/IRBuilder.cpp +++ lib/IR/IRBuilder.cpp @@ -245,12 +245,13 @@ return createCallHelper(TheFn, Ops, this, Name); } -static std::vector getStatepointArgs(IRBuilderBase &B, - Value *ActualCallee, - ArrayRef CallArgs, - ArrayRef DeoptArgs, - ArrayRef GCArgs) { +static std::vector +getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, + Value *ActualCallee, ArrayRef CallArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs) { std::vector Args; + Args.push_back(B.getInt64(ID)); + Args.push_back(B.getInt32(NumPatchBytes)); Args.push_back(ActualCallee); Args.push_back(B.getInt32(CallArgs.size())); Args.push_back(B.getInt32((unsigned)StatepointFlags::None)); @@ -263,11 +264,10 @@ return Args; } -CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee, - ArrayRef CallArgs, - ArrayRef DeoptArgs, - ArrayRef GCArgs, - const Twine &Name) { +CallInst *IRBuilderBase::CreateGCStatepointCall( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, + ArrayRef CallArgs, ArrayRef DeoptArgs, + ArrayRef GCArgs, const Twine &Name) { // Extract out the type of the callee. PointerType *FuncPtrType = cast(ActualCallee->getType()); assert(isa(FuncPtrType->getElementType()) && @@ -280,25 +280,25 @@ Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint, ArgTypes); - std::vector Args = - getStatepointArgs(*this, ActualCallee, CallArgs, DeoptArgs, GCArgs); + std::vector Args = getStatepointArgs( + *this, ID, NumPatchBytes, ActualCallee, CallArgs, DeoptArgs, GCArgs); return createCallHelper(FnStatepoint, Args, this, Name); } -CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee, - ArrayRef CallArgs, - ArrayRef DeoptArgs, - ArrayRef GCArgs, - const Twine &Name) { +CallInst *IRBuilderBase::CreateGCStatepointCall( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, + ArrayRef CallArgs, ArrayRef DeoptArgs, + ArrayRef GCArgs, const Twine &Name) { std::vector VCallArgs; for (auto &U : CallArgs) VCallArgs.push_back(U.get()); - return CreateGCStatepointCall(ActualCallee, VCallArgs, DeoptArgs, GCArgs, - Name); + return CreateGCStatepointCall(ID, NumPatchBytes, ActualCallee, VCallArgs, + DeoptArgs, GCArgs, Name); } InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( - Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, + uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, + BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { // Extract out the type of the callee. @@ -311,21 +311,22 @@ Function *FnStatepoint = Intrinsic::getDeclaration( M, Intrinsic::experimental_gc_statepoint, {FuncPtrType}); - std::vector Args = - getStatepointArgs(*this, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs); + std::vector Args = getStatepointArgs( + *this, ID, NumPatchBytes, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs); return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this, Name); } InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( - Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, - ArrayRef InvokeArgs, ArrayRef DeoptArgs, - ArrayRef GCArgs, const Twine &Name) { + uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, + BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { std::vector VCallArgs; for (auto &U : InvokeArgs) VCallArgs.push_back(U.get()); - return CreateGCStatepointInvoke(ActualInvokee, NormalDest, UnwindDest, - VCallArgs, DeoptArgs, GCArgs, Name); + return CreateGCStatepointInvoke(ID, NumPatchBytes, ActualInvokee, NormalDest, + UnwindDest, VCallArgs, DeoptArgs, GCArgs, + Name); } CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -1499,13 +1499,34 @@ "reordering restrictions required by safepoint semantics", &CI); - const Value *Target = CS.getArgument(0); + const Value *IDV = CS.getArgument(0); + Assert(isa(IDV), "gc.statepoint ID must be a constant integer", + &CI); + + const Value *NumPatchBytesV = CS.getArgument(1); + Assert(isa(NumPatchBytesV), + "gc.statepoint number of patchable bytes must be a constant integer", + &CI); + const uint64_t NumPatchBytes = + cast(NumPatchBytesV)->getSExtValue(); + assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!"); + Assert(NumPatchBytes >= 0, "gc.statepoint number of patchable bytes must be " + "positive", + &CI); + + const Value *Target = CS.getArgument(2); const PointerType *PT = dyn_cast(Target->getType()); Assert(PT && PT->getElementType()->isFunctionTy(), "gc.statepoint callee must be of function pointer type", &CI, Target); FunctionType *TargetFuncType = cast(PT->getElementType()); - const Value *NumCallArgsV = CS.getArgument(1); + if (NumPatchBytes) + Assert(isa(Target->stripPointerCasts()), + "gc.statepoint must have null as call target if number of patchable " + "bytes is non zero", + &CI); + + const Value *NumCallArgsV = CS.getArgument(3); Assert(isa(NumCallArgsV), "gc.statepoint number of arguments to underlying call " "must be constant integer", @@ -1529,7 +1550,7 @@ Assert(NumCallArgs == NumParams, "gc.statepoint mismatch in number of call args", &CI); - const Value *FlagsV = CS.getArgument(2); + const Value *FlagsV = CS.getArgument(4); Assert(isa(FlagsV), "gc.statepoint flags must be constant integer", &CI); const uint64_t Flags = cast(FlagsV)->getZExtValue(); @@ -1540,13 +1561,14 @@ // the type of the wrapped callee. for (int i = 0; i < NumParams; i++) { Type *ParamType = TargetFuncType->getParamType(i); - Type *ArgType = CS.getArgument(3+i)->getType(); + Type *ArgType = CS.getArgument(5 + i)->getType(); Assert(ArgType == ParamType, "gc.statepoint call argument does not match wrapped " "function type", &CI); } - const int EndCallArgsInx = 2+NumCallArgs; + + const int EndCallArgsInx = 4 + NumCallArgs; const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1); Assert(isa(NumTransitionArgsV), @@ -1570,7 +1592,7 @@ &CI); const int ExpectedNumArgs = - 5 + NumCallArgs + NumTransitionArgs + NumDeoptArgs; + 7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs; Assert(ExpectedNumArgs <= (int)CS.arg_size(), "gc.statepoint too few arguments according to length fields", &CI); @@ -3289,7 +3311,7 @@ CI.getArgOperand(0)); // Assert that result type matches wrapped callee. - const Value *Target = StatepointCS.getArgument(0); + const Value *Target = StatepointCS.getArgument(2); const PointerType *PT = cast(Target->getType()); const FunctionType *TargetFuncType = cast(PT->getElementType()); @@ -3356,18 +3378,19 @@ // section of the statepoint's argument Assert(StatepointCS.arg_size() > 0, "gc.statepoint: insufficient arguments"); - Assert(isa(StatepointCS.getArgument(1)), + Assert(isa(StatepointCS.getArgument(3)), "gc.statement: number of call arguments must be constant integer"); const unsigned NumCallArgs = - cast(StatepointCS.getArgument(1))->getZExtValue(); - Assert(StatepointCS.arg_size() > NumCallArgs+3, + cast(StatepointCS.getArgument(3))->getZExtValue(); + Assert(StatepointCS.arg_size() > NumCallArgs + 5, "gc.statepoint: mismatch in number of call arguments"); - Assert(isa(StatepointCS.getArgument(NumCallArgs+3)), + Assert(isa(StatepointCS.getArgument(NumCallArgs + 5)), "gc.statepoint: number of transition arguments must be " "a constant integer"); const int NumTransitionArgs = - cast(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue(); - const int DeoptArgsStart = 2 + NumCallArgs + 1 + NumTransitionArgs + 1; + cast(StatepointCS.getArgument(NumCallArgs + 5)) + ->getZExtValue(); + const int DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1; Assert(isa(StatepointCS.getArgument(DeoptArgsStart)), "gc.statepoint: number of deoptimization arguments must be " "a constant integer"); Index: lib/Target/X86/X86MCInstLower.cpp =================================================================== --- lib/Target/X86/X86MCInstLower.cpp +++ lib/Target/X86/X86MCInstLower.cpp @@ -812,43 +812,50 @@ X86MCInstLower &MCIL) { assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64"); - // Lower call target and choose correct opcode - const MachineOperand &CallTarget = StatepointOpers(&MI).getCallTarget(); - MCOperand CallTargetMCOp; - unsigned CallOpcode; - switch (CallTarget.getType()) { - case MachineOperand::MO_GlobalAddress: - case MachineOperand::MO_ExternalSymbol: - CallTargetMCOp = MCIL.LowerSymbolOperand( - CallTarget, MCIL.GetSymbolFromOperand(CallTarget)); - CallOpcode = X86::CALL64pcrel32; - // Currently, we only support relative addressing with statepoints. - // Otherwise, we'll need a scratch register to hold the target - // address. You'll fail asserts during load & relocation if this - // symbol is to far away. (TODO: support non-relative addressing) - break; - case MachineOperand::MO_Immediate: - CallTargetMCOp = MCOperand::CreateImm(CallTarget.getImm()); - CallOpcode = X86::CALL64pcrel32; - // Currently, we only support relative addressing with statepoints. - // Otherwise, we'll need a scratch register to hold the target - // immediate. You'll fail asserts during load & relocation if this - // address is to far away. (TODO: support non-relative addressing) - break; - case MachineOperand::MO_Register: - CallTargetMCOp = MCOperand::CreateReg(CallTarget.getReg()); - CallOpcode = X86::CALL64r; - break; - default: - llvm_unreachable("Unsupported operand type in statepoint call target"); - break; - } + StatepointOpers SOpers(&MI); - // Emit call - MCInst CallInst; - CallInst.setOpcode(CallOpcode); - CallInst.addOperand(CallTargetMCOp); - OutStreamer->EmitInstruction(CallInst, getSubtargetInfo()); + if (unsigned PatchBytes = SOpers.getNumPatchBytes()) { + EmitNops(*OutStreamer, PatchBytes, Subtarget->is64Bit(), + getSubtargetInfo()); + } else { + // Lower call target and choose correct opcode + const MachineOperand &CallTarget = SOpers.getCallTarget(); + MCOperand CallTargetMCOp; + unsigned CallOpcode; + switch (CallTarget.getType()) { + case MachineOperand::MO_GlobalAddress: + case MachineOperand::MO_ExternalSymbol: + CallTargetMCOp = MCIL.LowerSymbolOperand( + CallTarget, MCIL.GetSymbolFromOperand(CallTarget)); + CallOpcode = X86::CALL64pcrel32; + // Currently, we only support relative addressing with statepoints. + // Otherwise, we'll need a scratch register to hold the target + // address. You'll fail asserts during load & relocation if this + // symbol is to far away. (TODO: support non-relative addressing) + break; + case MachineOperand::MO_Immediate: + CallTargetMCOp = MCOperand::CreateImm(CallTarget.getImm()); + CallOpcode = X86::CALL64pcrel32; + // Currently, we only support relative addressing with statepoints. + // Otherwise, we'll need a scratch register to hold the target + // immediate. You'll fail asserts during load & relocation if this + // address is to far away. (TODO: support non-relative addressing) + break; + case MachineOperand::MO_Register: + CallTargetMCOp = MCOperand::CreateReg(CallTarget.getReg()); + CallOpcode = X86::CALL64r; + break; + default: + llvm_unreachable("Unsupported operand type in statepoint call target"); + break; + } + + // Emit call + MCInst CallInst; + CallInst.setOpcode(CallOpcode); + CallInst.addOperand(CallTargetMCOp); + OutStreamer->EmitInstruction(CallInst, getSubtargetInfo()); + } // Record our statepoint node in the same section used by STACKMAP // and PATCHPOINT Index: lib/Transforms/Scalar/PlaceSafepoints.cpp =================================================================== --- lib/Transforms/Scalar/PlaceSafepoints.cpp +++ lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -886,8 +886,8 @@ if (CS.isCall()) { CallInst *ToReplace = cast(CS.getInstruction()); CallInst *Call = Builder.CreateGCStatepointCall( - CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None, - None, "safepoint_token"); + 0, 0, CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), + None, None, "safepoint_token"); Call->setTailCall(ToReplace->isTailCall()); Call->setCallingConv(ToReplace->getCallingConv()); @@ -915,7 +915,7 @@ // original block. Builder.SetInsertPoint(ToReplace->getParent()); InvokeInst *Invoke = Builder.CreateGCStatepointInvoke( - CS.getCalledValue(), ToReplace->getNormalDest(), + 0, 0, CS.getCalledValue(), ToReplace->getNormalDest(), ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()), Builder.getInt32(0), None, "safepoint_token"); Index: test/Analysis/ValueTracking/memory-dereferenceable.ll =================================================================== --- test/Analysis/ValueTracking/memory-dereferenceable.ll +++ test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -22,13 +22,13 @@ %alloca = alloca i1 %load2 = load i1, i1* %alloca %load3 = load i32, i32 addrspace(1)* %dparam - %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) - %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 5, i32 5) + %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) + %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 7, i32 7) %load4 = load i32, i32 addrspace(1)* %relocate %nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5 %load5 = load i32, i32 addrspace(1)* %nparam ret void } -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) -declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) +declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) \ No newline at end of file Index: test/CodeGen/Generic/overloaded-intrinsic-name.ll =================================================================== --- test/CodeGen/Generic/overloaded-intrinsic-name.ll +++ test/CodeGen/Generic/overloaded-intrinsic-name.ll @@ -13,29 +13,29 @@ ; function and integer define i32* @test_iAny(i32* %v) gc "statepoint-example" { - %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) - %v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5) + %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) + %v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7) ret i32* %v-new } ; float define float* @test_fAny(float* %v) gc "statepoint-example" { - %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) - %v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 5, i32 5) + %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) + %v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 7, i32 7) ret float* %v-new } ; array of integers define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" { - %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) - %v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5) + %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) + %v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7) ret [3 x i32]* %v-new } ; vector of integers define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" { - %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) - %v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 5, i32 5) + %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) + %v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 7, i32 7) ret <3 x i32>* %v-new } @@ -43,13 +43,13 @@ ; struct define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" { - %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) - %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 5, i32 5) + %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) + %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 7, i32 7) ret %struct.test* %v-new } declare zeroext i1 @return_i1() -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32) declare float* @llvm.experimental.gc.relocate.p0f32(i32, i32, i32) declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32) Index: test/CodeGen/X86/statepoint-allocas.ll =================================================================== --- test/CodeGen/X86/statepoint-allocas.ll +++ test/CodeGen/X86/statepoint-allocas.ll @@ -21,7 +21,7 @@ entry: %alloca = alloca i32 addrspace(1)*, align 8 store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca - 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) + 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) %rel = load i32 addrspace(1)*, i32 addrspace(1)** %alloca ret i32 addrspace(1)* %rel } @@ -38,11 +38,11 @@ entry: %alloca = alloca i32 addrspace(1)*, align 8 store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca - 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) + 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) ret i32 addrspace(1)* null } -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) ; CHECK-LABEL: .section .llvm_stackmaps @@ -66,7 +66,7 @@ ; Large Constants ; Statepoint ID only -; CHECK: .quad 2882400000 +; CHECK: .quad 0 ; Callsites ; The GC one @@ -118,4 +118,3 @@ ; CHECK: .short 0 ; CHECK: .align 8 - Index: test/CodeGen/X86/statepoint-call-lowering.ll =================================================================== --- test/CodeGen/X86/statepoint-call-lowering.ll +++ test/CodeGen/X86/statepoint-call-lowering.ll @@ -20,7 +20,7 @@ ; CHECK: popq %rdx ; CHECK: retq entry: - %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) + %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) %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) ret i1 %call1 } @@ -32,7 +32,7 @@ ; CHECK: popq %rdx ; CHECK: retq entry: - %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) + %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) %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token) ret i32 %call1 } @@ -44,7 +44,7 @@ ; CHECK: popq %rdx ; CHECK: retq entry: - %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) + %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) %call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token) ret i32* %call1 } @@ -56,7 +56,7 @@ ; CHECK: popq %rax ; CHECK: retq entry: - %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) + %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) %call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token) ret float %call1 } @@ -70,8 +70,8 @@ ; CHECK-NEXT: popq %rdx ; CHECK-NEXT: retq entry: - %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) - %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) ret i1 %call2 } @@ -81,24 +81,37 @@ ; Check a statepoint wrapping a *void* returning vararg function works ; CHECK: callq varargf entry: - %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) + %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) ;; if we try to use the result from a statepoint wrapping a ;; non-void-returning varargf, we will experience a crash. ret void } -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +define i1 @test_i1_return_patchable() gc "statepoint-example" { +; CHECK-LABEL: test_i1_return_patchable +; A patchable variant of test_i1_return +; CHECK: pushq %rax +; CHECK: nopl +; CHECK: popq %rdx +; CHECK: retq +entry: + %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) + %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) + ret i1 %call1 +} + +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i1 @llvm.experimental.gc.result.i1(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...) declare i32 @llvm.experimental.gc.result.i32(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...) declare i32* @llvm.experimental.gc.result.p0i32(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...) declare float @llvm.experimental.gc.result.f32(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) Index: test/CodeGen/X86/statepoint-forward.ll =================================================================== --- test/CodeGen/X86/statepoint-forward.ll +++ test/CodeGen/X86/statepoint-forward.ll @@ -25,8 +25,8 @@ %before = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p %cmp1 = call i1 @f(i32 addrspace(1)* %before) call void @llvm.assume(i1 %cmp1) - %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) - %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 7, i32 7) %after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew %cmp2 = call i1 @f(i32 addrspace(1)* %after) ret i1 %cmp2 @@ -44,8 +44,8 @@ %cmp1 = call i1 @f(i32 addrspace(1)* %v) call void @llvm.assume(i1 %cmp1) store i32 addrspace(1)* %v, i32 addrspace(1)* addrspace(1)* %p - %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) - %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %pnew = call i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32 %safepoint_token, i32 7, i32 7) %after = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %pnew %cmp2 = call i1 @f(i32 addrspace(1)* %after) ret i1 %cmp2 @@ -72,7 +72,7 @@ %before = load i32 addrspace(1)*, i32 addrspace(1)** %p %cmp1 = call i1 @f(i32 addrspace(1)* %before) call void @llvm.assume(i1 %cmp1) - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0) + 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) %after = load i32 addrspace(1)*, i32 addrspace(1)** %p %cmp2 = call i1 @f(i32 addrspace(1)* %after) ret i1 %cmp2 @@ -90,7 +90,7 @@ %cmp1 = call i1 @f(i32 addrspace(1)* %v) call void @llvm.assume(i1 %cmp1) store i32 addrspace(1)* %v, i32 addrspace(1)** %p - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 0) + 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) %after = load i32 addrspace(1)*, i32 addrspace(1)** %p %cmp2 = call i1 @f(i32 addrspace(1)* %after) ret i1 %cmp2 @@ -102,6 +102,5 @@ } declare void @llvm.assume(i1) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) declare i32 addrspace(1)* addrspace(1)* @llvm.experimental.gc.relocate.p1p1i32(i32, i32, i32) #3 - Index: test/CodeGen/X86/statepoint-gctransition-call-lowering.ll =================================================================== --- test/CodeGen/X86/statepoint-gctransition-call-lowering.ll +++ test/CodeGen/X86/statepoint-gctransition-call-lowering.ll @@ -21,7 +21,7 @@ ; CHECK: popq %rdx ; CHECK: retq entry: - %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) + %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) %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) ret i1 %call1 } @@ -33,7 +33,7 @@ ; CHECK: popq %rdx ; CHECK: retq entry: - %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) + %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) %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token) ret i32 %call1 } @@ -45,7 +45,7 @@ ; CHECK: popq %rdx ; CHECK: retq entry: - %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) + %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) %call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token) ret i32* %call1 } @@ -57,7 +57,7 @@ ; CHECK: popq %rax ; CHECK: retq entry: - %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) + %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) %call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token) ret float %call1 } @@ -71,8 +71,8 @@ ; CHECK-NEXT: popq %rdx ; CHECK-NEXT: retq entry: - %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) - %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) ret i1 %call2 } @@ -82,7 +82,7 @@ ; Check a statepoint wrapping a *void* returning vararg function works ; CHECK: callq varargf entry: - %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) + %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) ;; if we try to use the result from a statepoint wrapping a ;; non-void-returning varargf, we will experience a crash. ret void @@ -96,7 +96,7 @@ ; CHECK: retq entry: %val = alloca i32 - %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) + %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) %call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token) ret i32 %call1 } @@ -110,24 +110,24 @@ entry: %val = alloca i32 %arg = alloca i8 - %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) + %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) %call1 = call i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token) ret i32 %call1 } -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i1 @llvm.experimental.gc.result.i1(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i32 (i32, i8*)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i32i32p0i8f(i64, i32, i32 (i32, i8*)*, i32, i32, ...) declare i32 @llvm.experimental.gc.result.i32(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...) declare i32* @llvm.experimental.gc.result.p0i32(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...) declare float @llvm.experimental.gc.result.f32(i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...) -declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) +declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) \ No newline at end of file Index: test/CodeGen/X86/statepoint-invoke.ll =================================================================== --- test/CodeGen/X86/statepoint-invoke.ll +++ test/CodeGen/X86/statepoint-invoke.ll @@ -13,7 +13,7 @@ ; CHECK: .Ltmp{{[0-9]+}}: ; CHECK: callq some_other_call ; CHECK: .Ltmp{{[0-9]+}}: - %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) + %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) to label %normal_return unwind label %exceptional_return normal_return: @@ -36,5 +36,5 @@ ; CHECK: .byte 0 ; CHECK: .align 4 -declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) -declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32) +declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) +declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32) \ No newline at end of file Index: test/CodeGen/X86/statepoint-stack-usage.ll =================================================================== --- test/CodeGen/X86/statepoint-stack-usage.ll +++ test/CodeGen/X86/statepoint-stack-usage.ll @@ -14,17 +14,17 @@ ; CHECK: movq %rdx, 16(%rsp) ; CHECK: movq %rdi, 8(%rsp) ; CHECK: movq %rsi, (%rsp) - %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) - %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10) - %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 11) - %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 12) + %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) + %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 12) + %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 13) + %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 14) ; CHECK: callq ; This is the key check. There should NOT be any memory moves here ; CHECK-NOT: movq - %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) - %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 12) - %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 11) - %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 10) + %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) + %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 14) + %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 13) + %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 12) ; CHECK: callq ret i32 1 } @@ -37,17 +37,17 @@ ; CHECK: movq %rdx, 16(%rsp) ; CHECK: movq %rdi, 8(%rsp) ; CHECK: movq %rsi, (%rsp) - %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) - %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10) - %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 11) - %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 12) + %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) + %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 12) + %b1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 13) + %c1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 12, i32 14) ; CHECK: callq ; This is the key check. There should NOT be any memory moves here ; CHECK-NOT: movq - %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) - %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 12) - %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 11) - %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 10, i32 10) + %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) + %a2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 14) + %b2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 13) + %c2 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token2, i32 12, i32 12) ; CHECK: callq ret i32 1 } @@ -55,6 +55,6 @@ ; Function Attrs: nounwind declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) -attributes #1 = { uwtable } +attributes #1 = { uwtable } \ No newline at end of file Index: test/CodeGen/X86/statepoint-stackmap-format.ll =================================================================== --- test/CodeGen/X86/statepoint-stackmap-format.ll +++ test/CodeGen/X86/statepoint-stackmap-format.ll @@ -21,15 +21,15 @@ entry: %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1 - %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, i32 addrspace(1)* null, i32 addrspace(1)* %ptr, i32 addrspace(1)* null) + %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, i32 addrspace(1)* null, i32 addrspace(1)* %ptr, i32 addrspace(1)* null) %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) - %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) - %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 8, i32 8) + %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) + %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10) ; ret i1 %call1 } -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i1 @llvm.experimental.gc.result.i1(i32) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 @@ -53,7 +53,7 @@ ; Large Constants ; Statepoint ID only -; CHECK: .quad 2882400000 +; CHECK: .quad 0 ; Callsites ; Constant arguments @@ -106,4 +106,3 @@ ; CHECK: .short 0 ; CHECK: .align 8 - Index: test/Transforms/CodeGenPrepare/statepoint-relocate.ll =================================================================== --- test/Transforms/CodeGenPrepare/statepoint-relocate.ll +++ test/Transforms/CodeGenPrepare/statepoint-relocate.ll @@ -10,9 +10,9 @@ ; CHECK: getelementptr i32, i32* %base-new, i32 15 entry: %ptr = getelementptr i32, i32* %base, i32 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* %base, i32* %ptr) - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) + %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) + %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7) + %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) %ret = load i32, i32* %ptr-new ret i32 %ret } @@ -25,10 +25,10 @@ entry: %ptr = getelementptr i32, i32* %base, i32 15 %ptr2 = getelementptr i32, i32* %base, i32 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, i32* %ptr2) - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) - %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7) + %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) + %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7) + %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) + %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9) %ret = load i32, i32* %ptr-new ret i32 %ret } @@ -38,9 +38,9 @@ ; CHECK: getelementptr i32, i32* %base-new, i32 15 entry: %ptr = getelementptr i32, i32* %base, i32 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* %base, i32* %ptr) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 5) + %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) + %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) + %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 7) %ret = load i32, i32* %ptr-new ret i32 %ret } @@ -50,9 +50,9 @@ ; CHECK: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 2 entry: %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2 - %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) - %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) + %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) + %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7) + %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) %ret = load i32, i32* %ptr-new ret i32 %ret } @@ -62,27 +62,27 @@ ; CHECK-NOT: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 21 entry: %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21 - %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) - %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 5, i32 5) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) + %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) + %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 7, i32 7) + %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) %ret = load i32, i32* %ptr-new ret i32 %ret } define i32 @test_sor_noop(i32* %base) gc "statepoint-example" { ; CHECK: getelementptr i32, i32* %base, i32 15 -; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) -; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7) +; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) +; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9) entry: %ptr = getelementptr i32, i32* %base, i32 15 %ptr2 = getelementptr i32, i32* %base, i32 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, i32* %ptr2) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 6) - %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 5, i32 7) + %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) + %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 8) + %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 7, i32 9) %ret = load i32, i32* %ptr-new ret i32 %ret } -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32) declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32) Index: test/Transforms/InstCombine/gc.relocate.ll =================================================================== --- test/Transforms/InstCombine/gc.relocate.ll +++ test/Transforms/InstCombine/gc.relocate.ll @@ -6,7 +6,7 @@ ; then the return attribute of gc.relocate is dereferenceable(N). declare zeroext i1 @return_i1() -declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" { @@ -15,7 +15,7 @@ ; CHECK: call dereferenceable(8) entry: %load = load i32, i32 addrspace(1)* %dparam - %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) - %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 5, i32 5) + %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) + %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 7, i32 7) ret i32 addrspace(1)* %relocate } Index: test/Transforms/InstCombine/statepoint.ll =================================================================== --- test/Transforms/InstCombine/statepoint.ll +++ test/Transforms/InstCombine/statepoint.ll @@ -7,8 +7,8 @@ define i1 @test_negative(i32 addrspace(1)* %p) gc "statepoint-example" { entry: - %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) - %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) %cmp = icmp eq i32 addrspace(1)* %pnew, null ret i1 %cmp ; CHECK-LABEL: test_negative @@ -18,8 +18,8 @@ define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) gc "statepoint-example" { entry: - %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) - %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) %cmp = icmp eq i32 addrspace(1)* %pnew, null ret i1 %cmp ; CHECK-LABEL: test_nonnull @@ -28,8 +28,8 @@ define i1 @test_null() gc "statepoint-example" { entry: - %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) - %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) %cmp = icmp eq i32 addrspace(1)* %pnew, null ret i1 %cmp ; CHECK-LABEL: test_null @@ -39,8 +39,8 @@ define i1 @test_undef() gc "statepoint-example" { entry: - %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) - %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 5, i32 5) + %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) + %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) %cmp = icmp eq i32 addrspace(1)* %pnew, null ret i1 %cmp ; CHECK-LABEL: test_undef @@ -48,5 +48,5 @@ ; CHECK: ret i1 undef } -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 Index: test/Transforms/PlaceSafepoints/basic.ll =================================================================== --- test/Transforms/PlaceSafepoints/basic.ll +++ test/Transforms/PlaceSafepoints/basic.ll @@ -73,7 +73,7 @@ ; inserted for a function that takes 1 argument. ; CHECK: gc.statepoint.p0f_isVoidf ; CHECK: gc.statepoint.p0f_i1i1f -; CHECK: (i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0) +; CHECK: (i64 0, i32 0, i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0) ; CHECK: %call12 = call i1 @llvm.experimental.gc.result.i1 entry: %call1 = tail call i1 (i1) @i1_return_i1(i1 false) Index: test/Transforms/PlaceSafepoints/call-in-loop.ll =================================================================== --- test/Transforms/PlaceSafepoints/call-in-loop.ll +++ test/Transforms/PlaceSafepoints/call-in-loop.ll @@ -15,7 +15,7 @@ loop: ; CHECK-LABEL: loop -; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo +; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo ; CHECK-NOT: statepoint call void @foo() br label %loop Index: test/Transforms/PlaceSafepoints/finite-loops.ll =================================================================== --- test/Transforms/PlaceSafepoints/finite-loops.ll +++ test/Transforms/PlaceSafepoints/finite-loops.ll @@ -77,4 +77,4 @@ entry: call void @do_safepoint() ret void -} +} \ No newline at end of file Index: test/Transforms/PlaceSafepoints/invokes.ll =================================================================== --- test/Transforms/PlaceSafepoints/invokes.ll +++ test/Transforms/PlaceSafepoints/invokes.ll @@ -108,4 +108,4 @@ entry: call void @do_safepoint() ret void -} +} \ No newline at end of file Index: test/Transforms/PlaceSafepoints/split-backedge.ll =================================================================== --- test/Transforms/PlaceSafepoints/split-backedge.ll +++ test/Transforms/PlaceSafepoints/split-backedge.ll @@ -43,4 +43,4 @@ entry: call void @do_safepoint() ret void -} +} \ No newline at end of file Index: test/Transforms/PlaceSafepoints/statepoint-frameescape.ll =================================================================== --- test/Transforms/PlaceSafepoints/statepoint-frameescape.ll +++ test/Transforms/PlaceSafepoints/statepoint-frameescape.ll @@ -26,4 +26,4 @@ entry: call void @do_safepoint() ret void -} +} \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-1.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-1.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-1.ll @@ -20,9 +20,9 @@ ; CHECK-LABEL: merge: ; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %here ], [ %base_obj_y, %there ] %merged_value = phi i64 addrspace(1)* [ %x, %here ], [ %y, %there ] - %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) + %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) ret i64 addrspace(1)* %merged_value } declare void @foo() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-10.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-10.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-10.ll @@ -30,8 +30,8 @@ merge: %next = phi i64 addrspace(1)* [ %next_x, %true ], [ %next_y, %false ] - %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) + %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) br label %loop } -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll @@ -19,8 +19,8 @@ ; CHECK-DAG: [ %next.relocated.casted, %loop ] %current = phi i64 addrspace(1)* [ %obj, %entry ], [ %next, %loop ] %next = getelementptr i64, i64 addrspace(1)* %current, i32 1 - %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) + %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) br label %loop } -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-2.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-2.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-2.ll @@ -13,9 +13,9 @@ merge: %merged_value = phi i64 addrspace(1)* [ %base_obj, %entry ], [ %derived_obj, %there ] - %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) + %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) ret i64 addrspace(1)* %merged_value } declare void @foo() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-3.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-3.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-3.ll @@ -12,9 +12,9 @@ %current.i32 = bitcast i64 addrspace(1)* %current to i32 addrspace(1)* %next.i32 = getelementptr i32, i32 addrspace(1)* %current.i32, i32 1 %next.i64 = bitcast i32 addrspace(1)* %next.i32 to i64 addrspace(1)* - %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) + %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) br label %loop } declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-4.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-4.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-4.ll @@ -13,9 +13,9 @@ loop: ; CHECK: loop: -; 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 +; 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 ; CHECK-NEXT: %obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result - %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) + %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) %obj2 = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32 %safepoint_token1) switch i32 %condition, label %dest_a [ i32 0, label %dest_b @@ -37,17 +37,17 @@ ; CHECK: %obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ] %obj_to_consume = phi i64 addrspace(1)* [ %obj2, %dest_a ], [ null, %dest_b ], [ null, %dest_c ] - %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) + %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) br label %merge.split merge.split: ; preds = %merge - %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) + %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) br label %loop } ; Function Attrs: nounwind declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32) #0 -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 addrspace(1)* ()*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-5.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-5.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-5.ll @@ -23,9 +23,8 @@ ; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %base_obj_y, %there ] ; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ] %merged_value = phi i64 addrspace(1)* [ %base_obj_x, %bump ], [ %y, %there ] - %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) + %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) ret i64 addrspace(1)* %merged_value } -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) - +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) Index: test/Transforms/RewriteStatepointsForGC/base-pointers-6.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-6.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-6.ll @@ -33,9 +33,9 @@ ; CHECK: %base_phi = phi i64 addrspace(1)* [ %base_obj_x, %merge_here ], [ %base_obj_y, %there ] ; CHECK-NEXT: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ] %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ] - %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) + %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) ret i64 addrspace(1)* %merged_value } declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-7.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-7.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-7.ll @@ -44,10 +44,9 @@ ; CHECK: %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ] %merged_value = phi i64 addrspace(1)* [ %x, %merge_here ], [ %y, %there ] - %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) + %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) ret i64 addrspace(1)* %merged_value } declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) - +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) Index: test/Transforms/RewriteStatepointsForGC/base-pointers-8.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-8.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-8.ll @@ -24,7 +24,7 @@ loop_back: %next_element_ptr = getelementptr i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* %current_element_ptr, i32 1 %next_index = add i32 %index, 1 - %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) + %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) br label %loop_check not_found: @@ -35,4 +35,4 @@ } declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers-9.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers-9.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers-9.ll @@ -13,9 +13,9 @@ %condition = call i1 @runtime_value() %maybe_next = getelementptr i64, i64 addrspace(1)* %current, i32 1 %next = select i1 %condition, i64 addrspace(1)* %maybe_next, i64 addrspace(1)* %current - %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) + %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) br label %loop } declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/base-pointers.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/base-pointers.ll +++ test/Transforms/RewriteStatepointsForGC/base-pointers.ll @@ -16,7 +16,7 @@ ; CHECK-DAG: [ %obj.relocated.casted, %loop ] ; CHECK-DAG: [ %obj, %entry ] call void @use_obj(i64 addrspace(1)* %obj) - %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) + %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) br label %loop } @@ -57,7 +57,7 @@ ; CHECK: merge: ; CHECK-NEXT: %base_phi = phi i64 addrspace(1)* [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_L]], %left ], [ [[CAST_R]], %right ], !is_base_value !0 %value = phi i64 addrspace(1)* [ %a.cast, %left], [ %a.cast, %left], [ %a.cast, %left], [ %b.cast, %right] - %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) + %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) ret i64 addrspace(1)* %value } @@ -91,10 +91,10 @@ %nexta = getelementptr i64, i64 addrspace(1)* %current, i32 1 %next = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2 %extra2 = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2 - %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) + %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) br label %loop } declare void @foo() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(void (i64 addrspace(1)*)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/basics.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/basics.ll +++ test/Transforms/RewriteStatepointsForGC/basics.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: gc.statepoint ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* entry: - 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) + 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) ret i8 addrspace(1)* %obj } @@ -23,8 +23,8 @@ ; CHECK-NEXT: gc.statepoint ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)* entry: - 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) - 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) + 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) + 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) ret i8 addrspace(1)* %obj } @@ -39,7 +39,7 @@ ; CHECK-NEXT: load i8, i8 addrspace(1)* %obj.relocated entry: %derived = getelementptr i8, i8 addrspace(1)* %obj, i64 10 - 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) + 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) %a = load i8, i8 addrspace(1)* %derived %b = load i8, i8 addrspace(1)* %obj @@ -57,14 +57,14 @@ ; CHECK-LABEL: taken: ; CHECK-NEXT: gc.statepoint ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* - 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) + 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) br label %merge untaken: ; CHECK-LABEL: untaken: ; CHECK-NEXT: gc.statepoint ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)* - 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) + 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) br label %merge merge: @@ -81,8 +81,8 @@ ; CHECK-NEXT: gc.statepoint ; CHECK-NOT: %obj.relocated = call coldcc i8 addrspace(1)* entry: - 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) + 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) ret i8 addrspace(1)* %obj } -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/constants.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/constants.ll +++ test/Transforms/RewriteStatepointsForGC/constants.ll @@ -1,7 +1,7 @@ ; RUN: opt -S -rewrite-statepoints-for-gc %s | FileCheck %s declare void @foo() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) ; constants don't get relocated. define i8 @test() gc "statepoint-example" { @@ -9,7 +9,7 @@ ; CHECK: gc.statepoint ; CHECK-NEXT: load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*) entry: - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) %res = load i8, i8 addrspace(1)* inttoptr (i64 15 to i8 addrspace(1)*) ret i8 %res } @@ -22,7 +22,7 @@ ; CHECK-NEXT: gc.relocate ; CHECK-NEXT: icmp entry: - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) %cmp = icmp eq i8 addrspace(1)* %p, null br i1 %cmp, label %taken, label %not_taken @@ -52,10 +52,9 @@ ; CHECK: gc.statepoint ; CHECK-NEXT: load i8, i8 addrspace(1)* @G entry: - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) %res = load i8, i8 addrspace(1)* @G, align 1 ret i8 %res } - Index: test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll +++ test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll @@ -8,13 +8,13 @@ declare void @foo() declare void @use(...) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) define void @test1(<2 x i32 addrspace(1)*> addrspace(1)* %obj) gc "statepoint-example" { entry: - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) -; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 5, i32 5) + %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) +; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 7, i32 7) ; CHECK-NEXT: %obj.relocated.casted = bitcast i8 addrspace(1)* %obj.relocated to <2 x i32 addrspace(1)*> addrspace(1)* call void (...) @use(<2 x i32 addrspace(1)*> addrspace(1)* %obj) ret void -} \ No newline at end of file +} Index: test/Transforms/RewriteStatepointsForGC/live-vector.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/live-vector.ll +++ test/Transforms/RewriteStatepointsForGC/live-vector.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: bitcast ; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted entry: - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + %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) ret i64 addrspace(1)* %obj } @@ -28,7 +28,7 @@ ; CHECK-NEXT: insertelement ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7 entry: - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + %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) ret <2 x i64 addrspace(1)*> %obj } @@ -48,7 +48,7 @@ ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7 entry: %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + %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) ret <2 x i64 addrspace(1)*> %obj } @@ -63,7 +63,7 @@ ; CHECK-NEXT: gc.statepoint entry: %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr - invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + 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) to label %normal_return unwind label %exceptional_return ; CHECK-LABEL: normal_return: @@ -93,4 +93,4 @@ declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) \ No newline at end of file Index: test/Transforms/RewriteStatepointsForGC/liveness-basics.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/liveness-basics.ll +++ test/Transforms/RewriteStatepointsForGC/liveness-basics.ll @@ -16,7 +16,7 @@ ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* ; CHECK-NEXT: bitcast ; CHECK-NEXT: br label %merge - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) br label %merge untaken: @@ -25,7 +25,7 @@ ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)* ; CHECK-NEXT: bitcast ; CHECK-NEXT: br label %merge - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) br label %merge merge: @@ -42,7 +42,7 @@ ; CHECK-LABEL: entry: ; CHECK-NEXT: gc.statepoint ; CHECK-NEXT: br - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) br i1 %cmp, label %taken, label %untaken taken: @@ -54,7 +54,7 @@ ; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) ret i64 addrspace(1)* %obj untaken: @@ -76,16 +76,16 @@ ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* ; CHECK-NEXT: bitcast ; CHECK-NEXT: br label %merge - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) br label %merge untaken: ; CHECK-LABEL: taken: ; CHECK-NEXT: gc.statepoint ; CHECK-NEXT: br label %merge - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) br label %merge merge: @@ -114,9 +114,9 @@ ; CHECK-NEXT: ret i64 addrspace(1)* %derived.relocated1.casted ; %derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8 - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) ret i64 addrspace(1)* %derived } @@ -136,7 +136,7 @@ ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* ; CHECK-NEXT: bitcast ; CHECK-NEXT: br label %merge - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) br label %merge untaken: @@ -163,5 +163,4 @@ declare void @foo() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) - +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) Index: test/Transforms/RewriteStatepointsForGC/preprocess.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/preprocess.ll +++ test/Transforms/RewriteStatepointsForGC/preprocess.ll @@ -17,7 +17,7 @@ ; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted) ; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted) %obj2 = phi i64 addrspace(1)* [ %obj, %entry ] - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) call void (...) @consume(i64 addrspace(1)* %obj2) call void (...) @consume(i64 addrspace(1)* %obj) ret void @@ -33,7 +33,7 @@ unreached: %obj = phi i64 addrspace(1)* [null, %unreached] - call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) call void (...) @consume(i64 addrspace(1)* %obj) br label %unreached } @@ -46,7 +46,7 @@ ret void unreached: - invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + 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) to label %normal_return unwind label %exceptional_return normal_return: ; preds = %entry @@ -62,5 +62,4 @@ ; Bound the last check-not ; CHECK-LABEL: @foo -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) - +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) Index: test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll +++ test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll @@ -23,12 +23,11 @@ normal_dest: ;; CHECK-LABEL: normal_dest: ;; CHECK-NEXT: gc.statepoint -;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* -;; CHECK-NEXT: bitcast - %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) +;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)* +;; CHECK-NEXT: bitcast + %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) ret i64* addrspace(1)* %obj } -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) - +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) Index: test/Transforms/RewriteStatepointsForGC/relocation.ll =================================================================== --- test/Transforms/RewriteStatepointsForGC/relocation.ll +++ test/Transforms/RewriteStatepointsForGC/relocation.ll @@ -9,7 +9,7 @@ ; CHECK-LABEL: @test1 ; CHECK-DAG: %obj.relocated ; CHECK-DAG: %obj2.relocated - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + %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) br label %joint joint: @@ -61,7 +61,7 @@ br label %loop.backedge loop.backedge: - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + %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) br label %loop loop_y: @@ -79,14 +79,14 @@ ; CHECK-LABEL: if_branch: ; CHECK: gc.statepoint ; CHECK: gc.relocate - %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + %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) br label %join else_branch: ; CHECK-LABEL: else_branch: ; CHECK: gc.statepoint ; CHECK: gc.relocate - %safepoint_token1 = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0) + %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) br label %join join: @@ -110,8 +110,8 @@ ; CHECK-NEXT: gc.relocate ; CHECK-NEXT: bitcast ; CHECK-NEXT: gc.statepoint - %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) - %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) + %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) + %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) ret void } @@ -124,9 +124,9 @@ ; CHECK: gc.statepoint ; CHECK: gc.relocate ; CHECK: @use(i8 addrspace(1)* %res.relocated) - %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) + %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) %res = call i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32 %safepoint_token2) - 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) + 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) call void (...) @use(i8 addrspace(1)* %res) unreachable } @@ -136,7 +136,7 @@ define void @test5(i8 addrspace(1)* %arg) gc "statepoint-example" { ; CHECK-LABEL: test5 entry: - 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) + 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) switch i32 undef, label %kill [ i32 10, label %merge i32 13, label %merge @@ -170,7 +170,7 @@ ; CHECK: arg1.relocated = ; CHECK: arg2.relocated = ; CHECK: arg3.relocated = - 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) + 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) br label %gc.safepoint_poll.exit2 gc.safepoint_poll.exit2: @@ -209,7 +209,7 @@ ; CHECK-LABEL: outer-inc: ; CHECK: %arg1.relocated ; CHECK: %arg2.relocated - %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) + %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) br label %outer-loop } @@ -238,7 +238,7 @@ ; CHECK: gc.statepoint ; CHECK: %arg1.relocated ; CHECK: %arg2.relocated - %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) + %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) br i1 %cmp, label %inner-loop, label %outer-inc outer-inc: @@ -258,7 +258,7 @@ br i1 %condition, label %callbb, label %join2 callbb: - %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) + %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) br label %join join: @@ -285,12 +285,11 @@ declare void @do_safepoint() -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_p1i8f(i8 addrspace(1)* ()*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi64f(void (i64)*, i32, i32, ...) -declare i32 @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i32 (i64 addrspace(1)*)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_p1i8f(i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi64f(i64, i32, void (i64)*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i64, i32, i32 (i64 addrspace(1)*)*, i32, i32, ...) declare i8 addrspace(1)* @llvm.experimental.gc.result.ptr.p1i8(i32) #3 - Index: test/Verifier/invalid-patchable-statepoint.ll =================================================================== --- /dev/null +++ test/Verifier/invalid-patchable-statepoint.ll @@ -0,0 +1,14 @@ +; RUN: not opt -verify 2>&1 < %s | FileCheck %s + +; CHECK: gc.statepoint must have null as call target if number of patchable bytes is non zero + +define i1 @invalid_patchable_statepoint() gc "statepoint-example" { +entry: + %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) + %call1 = call i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) + ret i1 %call1 +} + +declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) +declare i1 @llvm.experimental.gc.result.i1(i32) +declare i1 @func() Index: test/Verifier/invalid-statepoint.ll =================================================================== --- test/Verifier/invalid-statepoint.ll +++ test/Verifier/invalid-statepoint.ll @@ -5,16 +5,16 @@ declare zeroext i1 @return0i1() ; Function Attrs: nounwind -declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()*, i32, i32, ...) #0 +declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i64, i32, i1 ()*, i32, i32, ...) #0 ; Function Attrs: nounwind declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #0 define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) { %a00 = load i32, i32 addrspace(1)* %dparam - %to0 = call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam) - %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 0, i32 4) + %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) + %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 2, i32 6) ret i32 addrspace(1)* %relocate } -attributes #0 = { nounwind } +attributes #0 = { nounwind } \ No newline at end of file Index: test/Verifier/invalid-statepoint2.ll =================================================================== --- test/Verifier/invalid-statepoint2.ll +++ test/Verifier/invalid-statepoint2.ll @@ -5,15 +5,14 @@ declare void @use(...) declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32) declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) declare i32 @"personality_function"() ;; Basic usage define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg, i32 %val) gc "statepoint-example" { entry: %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)* - %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) - %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11) + %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) + %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13) ret i64 addrspace(1)* %reloc } - Index: test/Verifier/statepoint.ll =================================================================== --- test/Verifier/statepoint.ll +++ test/Verifier/statepoint.ll @@ -3,18 +3,18 @@ declare void @use(...) declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32) declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32) -declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) declare i32 @"personality_function"() ;; Basic usage define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" { entry: %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)* - %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) - %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11) + %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) + %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13) ;; It is perfectly legal to relocate the same value multiple times... - %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11) - %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 11, i32 10) + %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13) + %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 13, i32 12) ret i64 addrspace(1)* %reloc ; CHECK-LABEL: test1 ; CHECK: statepoint @@ -39,8 +39,8 @@ ret void equal: - %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) - %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 10, i32 11) + %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) + %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 12, i32 13) call void undef(i64 addrspace(1)* %reloc) ret void ; CHECK-LABEL: test2 @@ -57,7 +57,7 @@ entry: ; CHECK-LABEL: entry ; CHECK: statepoint - %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) + %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) to label %normal_dest unwind label %exceptional_return normal_dest: @@ -65,8 +65,8 @@ ; CHECK: gc.relocate ; CHECK: gc.relocate ; CHECK: ret - %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10) - %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10) + %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12) + %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12) ret i8 addrspace(1)* %obj.relocated exceptional_return: @@ -76,8 +76,7 @@ %landing_pad = landingpad { i8*, i32 } personality i32 ()* @"personality_function" cleanup %relocate_token = extractvalue { i8*, i32 } %landing_pad, 1 - %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10) - %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10) + %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 12, i32 12) + %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 12, i32 12) ret i8 addrspace(1)* %obj1.relocated1 } -