How to use createinboundsgep in a right way?

I have a struct array of type

%func_p = type {i8*}

and a global pointer to that struct array

FP_Ptr->dump () : @fp_pointer = external global %func_p*

Now, I want to access the first structure of this array of structures and write data to it. My content is as follows:

Value *FP_Idx = IRB.getInt32(fp_idx); // fp_idx = 0
        
LoadInst *F_P = IRB.CreateLoad(FP_Pointer);
F_P->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));

Value *fp_store = IRB.CreateInBoundsGEP(func_p, FP_Pointer, FP_Idx);

But there seems to be a problem with the createinbounds statement:

clang-12: /llvmtest/llvm/lib/IR/Constants.cpp:2396: static llvm::Constant* llvm::ConstantExpr::getGetElementPtr(llvm::Type*, llvm::Constant*, llvm::ArrayRef<llvm::Value*>, bool, llvm::Optional<unsigned int>, llvm::Type*): Assertion `Ty == cast<PointerType>(C->getType()->getScalarType())->getElementType()' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:

and I wonder how I can fix it? In my LLVM version, this statement is defined as

Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx)
Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList)
Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList)

@fp_pointer has type %func_p** so the first type argument passed to a GEP based on it must be %func_p*.

But if @fp_pointer is declared as a struct array in another module (e.g. @fp_pointer = global [10 x %func_p] zeroinitializer, or func_p arr[10] in C terms) then you probably actually want to change the type of @fp_pointer in this module instead (to just @fp_pointer = external global %func_p).

Also, if you want to actually get at the i8* to store a pointer there, you’ll need another GEP index because the first one just acts over the array itself. If you haven’t seen it already this part of the docs is useful for understanding GEPs: The Often Misunderstood GEP Instruction — LLVM 16.0.0git documentation.