Lib call triggers assertion during vectorization
pacxx opened this issue · comments
As a debugging feature i thought it would be nice to have printf enabled in PACXX kernels. However, having a simple call to puts("hello")
in the funktion results in the following assertion:
/llvm/include/llvm/Support/Casting.h:255: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::GetElementPtrInst; Y = llvm::Value; typename llvm::cast_retty<X, Y*>::ret_type = llvm::GetElementPtrInst*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
I set the vector shape of this call to varying and added a SIMD mapping so that puts
would not be vectorized.
The assertions call stack is as follows:
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007fffdf46df5d in __GI_abort () at abort.c:90
#2 0x00007fffdf463f17 in __assert_fail_base (fmt=<optimized out>,
assertion=assertion@entry=0x7ffff75aecb0 "isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"",
file=file@entry=0x7ffff75aec48 "/llvm/include/llvm/Support/Casting.h", line=line@entry=255,
function=function@entry=0x7ffff75ba940 <llvm::cast_retty<llvm::GetElementPtrInst, llvm::Value*>::ret_type llvm::cast<llvm::GetElementPtrInst, llvm::Value>(llvm::Value*)::__PRETTY_FUNCTION__> "typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::GetElementPtrInst; Y = llvm::Value; typename llvm::cast_retty<X, Y*>::ret_type = llvm::GetElementPtrInst*]") at assert.c:92
#3 0x00007fffdf463fc2 in __GI___assert_fail (
assertion=0x7ffff75aecb0 "isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"",
file=0x7ffff75aec48 "/llvm/include/llvm/Support/Casting.h", line=255,
function=0x7ffff75ba940 <llvm::cast_retty<llvm::GetElementPtrInst, llvm::Value*>::ret_type llvm::cast<llvm::GetElementPtrInst, llvm::Value>(llvm::Value*)::__PRETTY_FUNCTION__> "typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::GetElementPtrInst; Y = llvm::Value; typename llvm::cast_retty<X, Y*>::ret_type = llvm::GetElementPtrInst*]") at assert.c:101
#4 0x00007ffff752a0b1 in llvm::cast_retty<llvm::GetElementPtrInst, llvm::Value*>::ret_type llvm::cast<llvm::GetElementPtrInst, llvm::Value>(llvm::Value*) () from /local/lib/libRV.so
#5 0x00007ffff7537c47 in native::NatBuilder::buildGEP(llvm::GetElementPtrInst*, bool, unsigned int) ()
from /local/lib/libRV.so
#6 0x00007ffff7537de5 in native::NatBuilder::requestScalarGEP(llvm::GetElementPtrInst*, unsigned int, bool) ()
from /local/lib/libRV.so
#7 0x00007ffff7535163 in native::NatBuilder::vectorizeCallInstruction(llvm::CallInst*) () from /local/lib/libRV.so
#8 0x00007ffff753cc8f in native::NatBuilder::vectorize(llvm::BasicBlock*, llvm::BasicBlock*) ()
from /local/lib/libRV.so
#9 0x00007ffff753ea03 in native::NatBuilder::vectorize(bool, llvm::ValueMap<llvm::Value const*, llvm::WeakTrackingVH, llvm::ValueMapConfig<llvm::Value const*, llvm::sys::SmartMutex<false> > >*) () from /local/lib/libRV.so
It seems that there is a problem with the GEP to the global value holding the string.
The problem is in this line. IRBuilder returns a GetElementPtrConstExpr for the string used in puts
what triggers the assertion.
I managed to get it working with this little dirty hack:
// FIXME: This is a workaround for IRBuilder's ConstantFolder
// to prevent the IRBuilder from craeting a ConstantExpr
// instead of an instruction.
// We insert a noop bitcast to hide the constness of
// vecBasePtr here. Other passes (e.g., InstCombine)
// will remove this noop instruction later.
bool insert = false;
if (isa<Constant>(vecBasePtr)){
vecBasePtr = new BitCastInst(vecBasePtr, vecBasePtr->getType());
insert = true;
}
GetElementPtrInst *vecGEP = cast<GetElementPtrInst>(builder.CreateGEP(vecBasePtr, idxList, gep->getName()));
if (insert)
cast<Instruction>(vecBasePtr)->insertBefore(vecGEP)
It looks like this behavior is LLVM 6 specific, i can not reproduce this with the release_40 or the release_50 branch.
That being said: the backend should never assume that IRBuilder delivers instructions if the return type is llvm::Value. I'll look into that.
The bug should be fixed with comit 0fb0cea
IRBuilder no longer assumes the IRBuilder::CreateGEP returns an llvm::GetElementPtrInst.
If you verify that this is indeed fixed, we can close the bug.
Almost there:
Line 1809 in NatBuilder.cpp still carries the cast. Without the unnecessary cast in this line it works like a charm.
Value * vecGEP = cast<GetElementPtrInst>(builder.CreateGEP(vecBasePtr, idxList, gep->getName()));
Fixed by 3295119