// TODO: Handle "int posix_memalign(void **, size_t, size_t)"
};
-
-static Function *getCalledFunction(const Value *V, bool LookThroughBitCast) {
+static Function *getCalledFunction(const Value *V, bool LookThroughBitCast,
+ bool &IsNoBuiltin) {
// Don't care about intrinsics in this case.
if (isa<IntrinsicInst>(V))
return nullptr;
if (!CS.getInstruction())
return nullptr;
- if (CS.isNoBuiltin())
- return nullptr;
+ IsNoBuiltin = CS.isNoBuiltin();
Function *Callee = CS.getCalledFunction();
if (!Callee || !Callee->isDeclaration())
static Optional<AllocFnsTy> getAllocationData(const Value *V, AllocType AllocTy,
const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false) {
- if (const Function *Callee = getCalledFunction(V, LookThroughBitCast))
- return getAllocationDataForFunction(Callee, AllocTy, TLI);
+ bool IsNoBuiltinCall;
+ if (const Function *Callee =
+ getCalledFunction(V, LookThroughBitCast, IsNoBuiltinCall))
+ if (!IsNoBuiltinCall)
+ return getAllocationDataForFunction(Callee, AllocTy, TLI);
return None;
}
static Optional<AllocFnsTy> getAllocationSize(const Value *V,
const TargetLibraryInfo *TLI) {
- const Function *Callee = getCalledFunction(V, /*LookThroughBitCast=*/false);
+ bool IsNoBuiltinCall;
+ const Function *Callee =
+ getCalledFunction(V, /*LookThroughBitCast=*/false, IsNoBuiltinCall);
if (!Callee)
return None;
// Prefer to use existing information over allocsize. This will give us an
// accurate AllocTy.
- if (Optional<AllocFnsTy> Data =
- getAllocationDataForFunction(Callee, AnyAlloc, TLI))
- return Data;
+ if (!IsNoBuiltinCall)
+ if (Optional<AllocFnsTy> Data =
+ getAllocationDataForFunction(Callee, AnyAlloc, TLI))
+ return Data;
Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
if (Attr == Attribute())
ret void
}
+; CHECK-LABEL: define void @test_nobuiltin
+; We had a bug where `nobuiltin` would cause `allocsize` to be ignored in
+; @llvm.objectsize calculations.
+define void @test_nobuiltin(i8** %p, i64* %r) {
+ %1 = call i8* @my_malloc(i8* null, i32 100) nobuiltin
+ store i8* %1, i8** %p, align 8
+
+ %2 = call i64 @llvm.objectsize.i64.p0i8(i8* %1, i1 false)
+ ; CHECK: store i64 100
+ store i64 %2, i64* %r, align 8
+ ret void
+}
+
attributes #0 = { allocsize(1) }
attributes #1 = { allocsize(2, 3) }