Index: llvm/include/llvm/IR/IntrinsicInst.h =================================================================== --- llvm/include/llvm/IR/IntrinsicInst.h +++ llvm/include/llvm/IR/IntrinsicInst.h @@ -1381,7 +1381,7 @@ } /// The statepoint with which this gc.relocate is associated. - const GCStatepointInst *getStatepoint() const; + const Value *getStatepoint() const; }; /// Represents calls to the gc.relocate intrinsic. Index: llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -169,8 +169,11 @@ // Spill location is known for gc relocates if (const auto *Relocate = dyn_cast(Val)) { + const Value *Statepoint = Relocate->getStatepoint(); + if (isa(Statepoint)) + return None; const auto &RelocationMap = - Builder.FuncInfo.StatepointRelocationMaps[Relocate->getStatepoint()]; + Builder.FuncInfo.StatepointRelocationMaps[cast(Statepoint)]; auto It = RelocationMap.find(Relocate); if (It == RelocationMap.end()) @@ -1195,9 +1198,12 @@ void SelectionDAGBuilder::visitGCResult(const GCResultInst &CI) { // The result value of the gc_result is simply the result of the actual // call. We've already emitted this, so just grab the value. - const GCStatepointInst *SI = CI.getStatepoint(); + const Value *SI = CI.getStatepoint(); + + if (isa(SI)) + return; - if (SI->getParent() == CI.getParent()) { + if (cast(SI)->getParent() == CI.getParent()) { setValue(&CI, getValue(SI)); return; } @@ -1220,7 +1226,12 @@ // We skip this check for relocates not in the same basic block as their // statepoint. It would be too expensive to preserve validation info through // different basic blocks. - if (Relocate.getStatepoint()->getParent() == Relocate.getParent()) + const Value *Statepoint = Relocate.getStatepoint(); + + if (isa(Statepoint)) + return; + + if (cast(Statepoint)->getParent() == Relocate.getParent()) StatepointLowering.relocCallVisited(Relocate); auto *Ty = Relocate.getType()->getScalarType(); @@ -1230,14 +1241,14 @@ const Value *DerivedPtr = Relocate.getDerivedPtr(); auto &RelocationMap = - FuncInfo.StatepointRelocationMaps[Relocate.getStatepoint()]; + FuncInfo.StatepointRelocationMaps[cast(Statepoint)]; auto SlotIt = RelocationMap.find(&Relocate); assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value"); const RecordType &Record = SlotIt->second; // If relocation was done via virtual register.. if (Record.type == RecordType::SDValueNode) { - assert(Relocate.getStatepoint()->getParent() == Relocate.getParent() && + assert(cast(Statepoint)->getParent() == Relocate.getParent() && "Nonlocal gc.relocate mapped via SDValue"); SDValue SDV = StatepointLowering.getLocation(getValue(DerivedPtr)); assert(SDV.getNode() && "empty SDValue"); Index: llvm/lib/IR/IntrinsicInst.cpp =================================================================== --- llvm/lib/IR/IntrinsicInst.cpp +++ llvm/lib/IR/IntrinsicInst.cpp @@ -694,9 +694,14 @@ return OverflowingBinaryOperator::NoUnsignedWrap; } -const GCStatepointInst *GCProjectionInst::getStatepoint() const { +const Value *GCProjectionInst::getStatepoint() const { const Value *Token = getArgOperand(0); - + dbgs() << "\n" << __LINE__ << " Token.name = " << Token->getName() << " HERE \n\n"; + Token->dump(); + if (isa(Token)) { + // dbgs() << "\n\n\n HERE \n\n\n"; + return Token; + } // This takes care both of relocates for call statepoints and relocates // on normal path of invoke statepoint. if (!isa(Token)) @@ -714,13 +719,19 @@ } Value *GCRelocateInst::getBasePtr() const { - if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) + auto Statepoint = getStatepoint(); + if (isa(Statepoint)) + return const_cast(Statepoint); + if (auto Opt = cast(Statepoint)->getOperandBundle(LLVMContext::OB_gc_live)) return *(Opt->Inputs.begin() + getBasePtrIndex()); - return *(getStatepoint()->arg_begin() + getBasePtrIndex()); + return *(cast(Statepoint)->arg_begin() + getBasePtrIndex()); } Value *GCRelocateInst::getDerivedPtr() const { - if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) + auto Statepoint = getStatepoint(); + if (isa(Statepoint)) + return const_cast(Statepoint); + if (auto Opt = cast(Statepoint)->getOperandBundle(LLVMContext::OB_gc_live)) return *(Opt->Inputs.begin() + getDerivedPtrIndex()); - return *(getStatepoint()->arg_begin() + getDerivedPtrIndex()); + return *(cast(Statepoint)->arg_begin() + getDerivedPtrIndex()); } Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -5161,13 +5161,13 @@ // This covers relocates on a normal return path of invoke statepoint and // relocates of a call statepoint. auto Token = Call.getArgOperand(0); - Check(isa(Token), + Check(isa(Token) || isa(Token), "gc relocate is incorrectly tied to the statepoint", Call, Token); } // Verify rest of the relocate arguments. - const CallBase &StatepointCall = - *cast(Call).getStatepoint(); + const Value &StatepointCall = + *cast(Call).getStatepoint(); // Both the base and derived must be piped through the safepoint. Value *Base = Call.getArgOperand(1); @@ -5182,12 +5182,14 @@ const uint64_t DerivedIndex = cast(Derived)->getZExtValue(); // Check the bounds - if (auto Opt = StatepointCall.getOperandBundle(LLVMContext::OB_gc_live)) { - Check(BaseIndex < Opt->Inputs.size(), - "gc.relocate: statepoint base index out of bounds", Call); - Check(DerivedIndex < Opt->Inputs.size(), - "gc.relocate: statepoint derived index out of bounds", Call); - } + if (!isa(StatepointCall)) + if (auto Opt = cast(StatepointCall). + getOperandBundle(LLVMContext::OB_gc_live)) { + Check(BaseIndex < Opt->Inputs.size(), + "gc.relocate: statepoint base index out of bounds", Call); + Check(DerivedIndex < Opt->Inputs.size(), + "gc.relocate: statepoint derived index out of bounds", Call); + } // Relocated value must be either a pointer type or vector-of-pointer type, // but gc_relocate does not need to return the same pointer type as the