[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