Query regarding function signature mismatch

Hi All,

During the opt phase the following mismatch is spitted from the verifier.cpp for the llvm-39

Fom the llvm-39 run

Call parameter type does not match function signature!

i8* getelementptr inbounds ([46 x i8], [46 x i8]* @instrname, i32 0, i32 0)

i8* %injectError = call i32 @myReferenceFunc(i32 %11, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @instrname, i32 0, i32 0), i32 -1)

As the snippet shows, it is issuing a function signature mismatch error.

Below is a corresponding snippet of a run from llvm-38 run

%injectError = call i32 @myReferenceFunc(i32 %4, i8* getelementptr inbounds ([45 x i8], [45 x i8]* @instrname, i32 0, i32 0), i32 -1)

In the llvm-39, it infers the return to be of type char pointer somehow unlike in llvm-38.

The original function definition hasn’t changed though.

We are using the current trunk of llvm.

Is there any related issue in the current trunk of llvm or if you could point us to something that has changed in llvm-39 that might be causing this difference ?

Note: For making our previous versions of passes compatible to llvm-39, we have replaced all the calls of getGlobalContext() by *unwrap(LLVMGetGlobalContext()).

We did try out a separate version modifying the llvm code to introduce the getGlobalContext() function as was available earlier to return the *GlobalContext. Even with that we are seeing the same log.

Regards,

Arnab Das

Hi All,

During the opt phase the following mismatch is spitted from the verifier.cpp for the llvm-39

Fom the llvm-39 run
Call parameter type does not match function signature!
i8* getelementptr inbounds ([46 x i8], [46 x i8]* @instrname, i32 0, i32 0)
i8* %injectError = call i32 @myReferenceFunc(i32 %11, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @instrname, i32 0, i32 0), i32 -1)

As the snippet shows, it is issuing a function signature mismatch error.

Below is a corresponding snippet of a run from llvm-38 run

%injectError = call i32 @myReferenceFunc(i32 %4, i8* getelementptr inbounds ([45 x i8], [45 x i8]* @instrname, i32 0, i32 0), i32 -1)

In the llvm-39, it infers the return to be of type char pointer somehow unlike in llvm-38.

I don’t believe the error you’re quoting indicates anything about the return type.
Here is the code with the assertion:

Assert(CS.getArgument(i)->getType() == FTy->getParamType(i),
“Call parameter type does not match function signature!”,
CS.getArgument(i), FTy->getParamType(i), I);

As you can see, it compares the type of the argument of the call to the type of the function declaration.
If you can print the IR before it fails, you can check how the function is declared.

The quote you’re copy pasting is a bit strange, it is supposed to be over three lines like that:

Call parameter type does not match function signature!
i8* getelementptr inbounds ([46 x i8], [46 x i8]* @instrname, i32 0, i32 0)
i8*

%injectError = call i32 @myReferenceFunc(i32 %11, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @instrname, i32 0, i32 0), i32 -1)

The original function definition hasn’t changed though.

We are using the current trunk of llvm.

Is there any related issue in the current trunk of llvm or if you could point us to something that has changed in llvm-39 that might be causing this difference ?

Note: For making our previous versions of passes compatible to llvm-39, we have replaced all the calls of getGlobalContext() by *unwrap(LLVMGetGlobalContext()).

We did try out a separate version modifying the llvm code to introduce the getGlobalContext() function as was available earlier to return the *GlobalContext. Even with that we are seeing the same log.

Since types are stored per context, it is very possible that it could be the source of the issue. However the change you are describing seems “OK” (the global context is not a great feature) providing it was working on 3.8 (and you’re initializing LLVM yourself, creating the module yourself in the global context, etc.). You can’t use you pass with opt with such a trick.

What you can do to verify if it is the source of the issue is to patch the code in the verifier from

// Verify that all arguments to the call match the function type.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
Assert(CS.getArgument(i)->getType() == FTy->getParamType(i),
“Call parameter type does not match function signature!”,
CS.getArgument(i), FTy->getParamType(i), I);

To

// Verify that all arguments to the call match the function type.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++I) {

Assert(&CS.getArgument(i)->getType()->getContext() == &FTy->getParamType(i)->getContext(),
“Context mismatch, internal error!",
CS.getArgument(i), FTy->getParamType(i), I);
Assert(CS.getArgument(i)->getType() == FTy->getParamType(i),
“Call parameter type does not match function signature!”,
CS.getArgument(i), FTy->getParamType(i), I);
}

If the first assertion mismatch, you have some context issue.