From: Easwaran Raman Date: Mon, 27 Jun 2016 22:31:53 +0000 (+0000) Subject: Fix size computation of array allocation in inline cost analysis X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a9324834d1b198935c756f1a08b9f51b85c22a6c;p=llvm Fix size computation of array allocation in inline cost analysis Differential revision: http://reviews.llvm.org/D21690 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273952 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp index 9382def0017..f6a9edae88d 100644 --- a/lib/Analysis/InlineCost.cpp +++ b/lib/Analysis/InlineCost.cpp @@ -339,9 +339,10 @@ bool CallAnalyzer::visitAlloca(AllocaInst &I) { if (I.isArrayAllocation()) { Constant *Size = SimplifiedValues.lookup(I.getArraySize()); if (auto *AllocSize = dyn_cast_or_null(Size)) { + const DataLayout &DL = F.getParent()->getDataLayout(); Type *Ty = I.getAllocatedType(); - // FIXME: This can't be right. AllocatedSize is in *bytes*. - AllocatedSize += Ty->getPrimitiveSizeInBits() * AllocSize->getZExtValue(); + AllocatedSize = SaturatingMultiplyAdd( + AllocSize->getLimitedValue(), DL.getTypeAllocSize(Ty), AllocatedSize); return Base::visitAlloca(I); } } @@ -350,7 +351,7 @@ bool CallAnalyzer::visitAlloca(AllocaInst &I) { if (I.isStaticAlloca()) { const DataLayout &DL = F.getParent()->getDataLayout(); Type *Ty = I.getAllocatedType(); - AllocatedSize += DL.getTypeAllocSize(Ty); + AllocatedSize = SaturatingAdd(DL.getTypeAllocSize(Ty), AllocatedSize); } // We will happily inline static alloca instructions. diff --git a/test/Transforms/Inline/array-alloca.ll b/test/Transforms/Inline/array-alloca.ll new file mode 100644 index 00000000000..57aecebd8ba --- /dev/null +++ b/test/Transforms/Inline/array-alloca.ll @@ -0,0 +1,36 @@ +; RUN: opt -inline -S < %s | FileCheck %s +%struct.A = type { i32 } + +define void @callee1(i32 %M) { +entry: + %vla = alloca i32, i32 %M, align 16 + ret void +} + +define void @callee2(i32 %M) { +entry: + %vla = alloca %struct.A, i32 %M, align 16 + ret void +} + +define void @callee3(i128 %M) { +entry: + %vla = alloca i32, i128 %M, align 16 + ret void +} + +; CHECK-LABEL: @caller +define void @caller() #0 { +entry: + call void @caller() +; CHECK-NOT: call void @callee1 + call void @callee1(i32 256) +; CHECK: call void @callee2 + call void @callee2(i32 4096) +; CHECK: call void @callee3 +; This is to test that there is no overflow in computing allocated size +; call void @callee3(i128 0x8000000000000000); + call void @callee3(i128 9223372036854775808); + ret void +} +