diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4679,7 +4679,7 @@ } 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()); } @@ -4840,7 +4840,7 @@ 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()); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1317,11 +1317,15 @@ /// 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; + // Use -1 as the unknown size. + if (Size.isScalable()) + Size = llvm::TypeSize::Fixed(-1); + assert(Addr->getType()->getPointerAddressSpace() == CGM.getDataLayout().getAllocaAddrSpace() && "Pointer should be in alloca address space"); @@ -1551,9 +1555,7 @@ 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()); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -276,7 +276,7 @@ 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) { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2872,7 +2872,7 @@ 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); diff --git a/clang/test/CodeGen/RISCV/riscv-v-lifetime.cpp b/clang/test/CodeGen/RISCV/riscv-v-lifetime.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-v-lifetime.cpp @@ -0,0 +1,30 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -std=c++11 -triple riscv64 -target-feature +experimental-v \ +// RUN: -emit-llvm -O1 -o - %s | FileCheck %s + +#include + +template +void Foo(T &&); + +template +T Baz(); + +// CHECK-LABEL: @_Z4Testv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca , align 8 +// CHECK-NEXT: [[TMP0:%.*]] = bitcast * [[REF_TMP]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull [[TMP0]]) #[[ATTR3:[0-9]+]] +// CHECK-NEXT: [[CALL:%.*]] = call @_Z3BazIu15__rvv_int32m1_tET_v() #[[ATTR3]] +// CHECK-NEXT: store [[CALL]], * [[REF_TMP]], align 8, !tbaa [[TBAA4:![0-9]+]] +// CHECK-NEXT: call void @_Z3FooIRKu15__rvv_int32m1_tEvOT_(* nonnull align 4 [[REF_TMP]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP1:%.*]] = load , * [[REF_TMP]], align 8, !tbaa [[TBAA4]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull [[TMP0]]) #[[ATTR3]] +// CHECK-NEXT: ret [[TMP1]] +// +vint32m1_t Test() { + const vint32m1_t &a = Baz(); + Foo(a); + return a; +}