[LLVMdev] Question about intrinsic function llvm.objectsize

Shuxin Yang shuxin.llvm at gmail.com
Tue Feb 26 15:09:27 PST 2013


Hi,

   In the following instruction sequence, llvm.objectsize.i64(p) returns 
6 (the entire *.ll is attached to the mail).
Is this correct? Shouldn't the "object" refer to the entire block of 
memory being allocated?

   (char*) p = malloc(56)
   llvm.objectisize.i32(p+50);

Thanks
Shuxin



   This question is related to PR14988 (failure in bootstrap build with 
LTO). Part of the reason is that
the compiler interpret the pretty vague team "object" in different ways 
-- the "object" suggested by
line 359 @ figure 1 is just a part of the "object" implied by Figure 2.

   I try to fix the problem PR14988 by replacing line 359 with "Size = 
Offset.getZextValue()"; It does fix the problem.
However, I'm wondering in what situations the Offset != 0. So I put an 
assertion right before line 359,
saying "assert(Offset != 0)". It catches two cases in SingleSource test 
suite. I investigate one of them,
the assertion is triggered when the llvm::getObjectSize() is called by 
instcombine (instead of alias analyizer)
in an attempt to replace llvm.objectsize() with a constant. I think the 
way  llvm::getObjectSize() interpret "object" is wrong.


Figure 1
cat -n lib/Analysis/MemoryBuiltins.cpp
   344 bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const 
DataLayout *TD,
   345                          const TargetLibraryInfo *TLI, bool 
RoundToAlign) {
   346   if (!TD)
   347     return false;
   348
   349   ObjectSizeOffsetVisitor Visitor(TD, TLI, Ptr->getContext(), 
RoundToAlign);
   350   SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
   351   if (!Visitor.bothKnown(Data))
   352     return false;
   353
   354   APInt ObjSize = Data.first, Offset = Data.second;
   355   // check for overflow
   356   if (Offset.slt(0) || ObjSize.ult(Offset))
   357     Size = 0;
   358   else
   359     Size = (ObjSize - Offset).getZExtValue(); ??? What the hack 
is "object"??????
   360   return true;
   361 }

Figure 2
cat -n lib/Analysis/BasicAliasAnalysis.cpp
1205   // If the size of one access is larger than the entire object on 
the other
1206   // side, then we know such behavior is undefined and can assume 
no alias.
1207   if (TD)
1208     if ((V1Size != UnknownSize && isObjectSmallerThan(O2, V1Size, 
*TD, *TLI)) ||
1209         (V2Size != UnknownSize && isObjectSmallerThan(O1, V2Size, 
*TD, *TLI)))
1210       return NoAlias;
-------------- next part --------------
; ModuleID = 'a.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"

define i64 @foo() #0 {
entry:
  %call = tail call i8* @malloc(i64 56) #3
  tail call void @bar1(i8* %call) #3
  tail call void @bar2(i8* %call) #3
  %t2 = getelementptr inbounds i8* %call, i64 50
  %t3 = tail call i64 @llvm.objectsize.i64(i8* %t2, i1 false)
  ret i64 %t3
}

declare i64 @llvm.objectsize.i64( i8*, i1)
declare noalias i8* @malloc(i64) #1

declare void @bar1(i8*) #2

declare void @bar2(i8*) #2

declare i32 @bar3(i8*) #2

attributes #0 = { nounwind ssp uwtable "target-cpu"="core2" "target-features"="-sse4a,-avx2,-xop,-fma4,-bmi2,-3dnow,-3dnowa,-pclmul,+sse,-avx,-sse41,+ssse3,+mmx,-rtm,-sse42,-lzcnt,-f16c,-popcnt,-bmi,-aes,-fma,-rdrand,+sse2,+sse3" }
attributes #1 = { nounwind "target-cpu"="core2" "target-features"="-sse4a,-avx2,-xop,-fma4,-bmi2,-3dnow,-3dnowa,-pclmul,+sse,-avx,-sse41,+ssse3,+mmx,-rtm,-sse42,-lzcnt,-f16c,-popcnt,-bmi,-aes,-fma,-rdrand,+sse2,+sse3" }
attributes #2 = { "target-cpu"="core2" "target-features"="-sse4a,-avx2,-xop,-fma4,-bmi2,-3dnow,-3dnowa,-pclmul,+sse,-avx,-sse41,+ssse3,+mmx,-rtm,-sse42,-lzcnt,-f16c,-popcnt,-bmi,-aes,-fma,-rdrand,+sse2,+sse3" }
attributes #3 = { nounwind }


More information about the llvm-dev mailing list