cdl-saarland / rv

RV: A Unified Region Vectorizer for LLVM

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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