[Clang][CodeGen] Set the size of llvm.lifetime to unknown for scalable types.

If the memory object is scalable type, we do not know the exact size of
it at compile time. Set the size of lifetime marker to unknown if the
object is scalable one.

Differential Revision: https://reviews.llvm.org/D102822
This commit is contained in:
Hsiangkai Wang 2021-05-20 10:22:08 +08:00
parent cfcdebaf32
commit 2b13ff6979
5 changed files with 34 additions and 11 deletions

View File

@ -4683,7 +4683,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
} else {
SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
if (HaveInsertPoint() && ReturnValue.isUnused()) {
uint64_t size =
llvm::TypeSize size =
CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
UnusedReturnSizePtr = EmitLifetimeStart(size, SRetAlloca.getPointer());
}
@ -4844,7 +4844,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
IRCallArgs[FirstIRArg] = AI.getPointer();
// Emit lifetime markers for the temporary alloca.
uint64_t ByvalTempElementSize =
llvm::TypeSize ByvalTempElementSize =
CGM.getDataLayout().getTypeAllocSize(AI.getElementType());
llvm::Value *LifetimeSize =
EmitLifetimeStart(ByvalTempElementSize, AI.getPointer());

View File

@ -1318,7 +1318,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
/// Emit a lifetime.begin marker if some criteria are satisfied.
/// \return a pointer to the temporary size Value if a marker was emitted, null
/// otherwise
llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size,
llvm::Value *Addr) {
if (!ShouldEmitLifetimeMarkers)
return nullptr;
@ -1326,7 +1326,8 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
assert(Addr->getType()->getPointerAddressSpace() ==
CGM.getDataLayout().getAllocaAddrSpace() &&
"Pointer should be in alloca address space");
llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
llvm::Value *SizeV = llvm::ConstantInt::get(
Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue());
Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
llvm::CallInst *C =
Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
@ -1549,12 +1550,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// is rare.
if (!Bypasses.IsBypassed(&D) &&
!(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
llvm::TypeSize size =
CGM.getDataLayout().getTypeAllocSize(allocaTy);
llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
emission.SizeForLifetimeMarkers =
size.isScalable() ? EmitLifetimeStart(-1, AllocaAddr.getPointer())
: EmitLifetimeStart(size.getFixedSize(),
AllocaAddr.getPointer());
EmitLifetimeStart(Size, AllocaAddr.getPointer());
}
} else {
assert(!emission.useLifetimeMarkers());

View File

@ -276,7 +276,7 @@ void AggExprEmitter::withReturnValueSlot(
RetAddr = Dest.getAddress();
} else {
RetAddr = CGF.CreateMemTemp(RetTy, "tmp", &RetAllocaAddr);
uint64_t Size =
llvm::TypeSize Size =
CGF.CGM.getDataLayout().getTypeAllocSize(CGF.ConvertTypeForMem(RetTy));
LifetimeSizePtr = CGF.EmitLifetimeStart(Size, RetAllocaAddr.getPointer());
if (LifetimeSizePtr) {

View File

@ -2872,7 +2872,7 @@ public:
void EmitSehTryScopeBegin();
void EmitSehTryScopeEnd();
llvm::Value *EmitLifetimeStart(uint64_t Size, llvm::Value *Addr);
llvm::Value *EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr);
void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);
llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);

View File

@ -0,0 +1,25 @@
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -std=c++11 -triple riscv64 -target-feature +experimental-v \
// RUN: -O1 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
#include <riscv_vector.h>
vint32m1_t Baz();
// CHECK-LABEL: @_Z4Testv(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[A:%.*]] = alloca <vscale x 2 x i32>*, align 8
// CHECK-NEXT: [[REF_TMP:%.*]] = alloca <vscale x 2 x i32>, align 4
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <vscale x 2 x i32>** [[A]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP0]]) #[[ATTR3:[0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 2 x i32>* [[REF_TMP]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[TMP1]]) #[[ATTR3]]
// CHECK: [[TMP4:%.*]] = bitcast <vscale x 2 x i32>* [[REF_TMP]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[TMP4]]) #[[ATTR3]]
// CHECK-NEXT: [[TMP5:%.*]] = bitcast <vscale x 2 x i32>** [[A]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP5]]) #[[ATTR3]]
//
vint32m1_t Test() {
const vint32m1_t &a = Baz();
return a;
}