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,7 +1317,7 @@ /// 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; @@ -1325,7 +1325,7 @@ 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}); @@ -1548,12 +1548,10 @@ // is rare. if (!Bypasses.IsBypassed(&D) && !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) { - llvm::TypeSize size = + 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,32 @@ +// 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: -O1 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s + +#include + +vint32m1_t Baz(); + +// CHECK-LABEL: @_Z4Testv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A:%.*]] = alloca *, align 8 +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca , align 4 +// CHECK-NEXT: [[TMP0:%.*]] = bitcast ** [[A]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP0]]) #[[ATTR3:[0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast * [[REF_TMP]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[TMP1]]) #[[ATTR3]] +// CHECK-NEXT: [[CALL:%.*]] = call @_Z3Bazv() +// CHECK-NEXT: store [[CALL]], * [[REF_TMP]], align 4, !tbaa [[TBAA4:![0-9]+]] +// CHECK-NEXT: store * [[REF_TMP]], ** [[A]], align 8, !tbaa [[TBAA8:![0-9]+]] +// CHECK-NEXT: [[TMP2:%.*]] = load *, ** [[A]], align 8, !tbaa [[TBAA8]] +// CHECK-NEXT: [[TMP3:%.*]] = load , * [[TMP2]], align 4, !tbaa [[TBAA4]] +// CHECK-NEXT: [[TMP4:%.*]] = bitcast * [[REF_TMP]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[TMP4]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP5:%.*]] = bitcast ** [[A]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP5]]) #[[ATTR3]] +// CHECK-NEXT: ret [[TMP3]] +// +vint32m1_t Test() { + const vint32m1_t &a = Baz(); + return a; +}