From a06789138987d1f64bb2f97d3a5c0f39eaf94715 Mon Sep 17 00:00:00 2001 From: Michael Liao Date: Sun, 9 Feb 2020 13:09:19 -0500 Subject: [PATCH] [clang][codegen] Fix another lifetime emission on alloca on non-default address space. - Lifetime intrinsics expect the pointer directly from alloca. Need extra handling for targets with alloca on non-default (or non-zero) address space. --- clang/lib/CodeGen/CGCall.cpp | 8 +++++--- clang/lib/CodeGen/CodeGenFunction.h | 5 +++-- clang/test/CodeGenCXX/amdgcn-call-with-aggarg.cpp | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenCXX/amdgcn-call-with-aggarg.cpp diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3edcfb2..9ef2a3b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3690,8 +3690,9 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, } AggValueSlot ArgSlot = AggValueSlot::ignored(); + Address ArgSlotAlloca = Address::invalid(); if (hasAggregateEvaluationKind(E->getType())) { - ArgSlot = CreateAggTemp(E->getType(), "agg.tmp"); + ArgSlot = CreateAggTemp(E->getType(), "agg.tmp", &ArgSlotAlloca); // Emit a lifetime start/end for this temporary. If the type has a // destructor, then we need to keep it alive. FIXME: We should still be able @@ -3699,8 +3700,9 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, if (!E->getType().isDestructedType()) { uint64_t size = CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(E->getType())); - if (auto *lifetimeSize = EmitLifetimeStart(size, ArgSlot.getPointer())) - args.addLifetimeCleanup({ArgSlot.getPointer(), lifetimeSize}); + if (auto *lifetimeSize = + EmitLifetimeStart(size, ArgSlotAlloca.getPointer())) + args.addLifetimeCleanup({ArgSlotAlloca.getPointer(), lifetimeSize}); } } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index f48d8a4..7ddd38c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2264,8 +2264,9 @@ public: /// CreateAggTemp - Create a temporary memory object for the given /// aggregate type. - AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp") { - return AggValueSlot::forAddr(CreateMemTemp(T, Name), + AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp", + Address *Alloca = nullptr) { + return AggValueSlot::forAddr(CreateMemTemp(T, Name, Alloca), T.getQualifiers(), AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, diff --git a/clang/test/CodeGenCXX/amdgcn-call-with-aggarg.cpp b/clang/test/CodeGenCXX/amdgcn-call-with-aggarg.cpp new file mode 100644 index 0000000..e9d3683 --- /dev/null +++ b/clang/test/CodeGenCXX/amdgcn-call-with-aggarg.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm -O3 -disable-llvm-passes -o - %s | FileCheck %s + +struct A { + float x, y, z, w; +}; + +void foo(A a); + +// CHECK-LABEL: @_Z4testv +// CHECK: %[[lvar:.*]] = alloca %struct.A, align 4, addrspace(5) +// CHECK: %[[atmp:.*]] = alloca %struct.A, align 4, addrspace(5) +// CHECK: %[[lcst:.*]] = bitcast %struct.A addrspace(5)* %[[lvar]] to i8 addrspace(5)* +// CHECK: call void @llvm.lifetime.start.p5i8(i64 16, i8 addrspace(5)* %[[lcst]] +// CHECK: %[[acst:.*]] = bitcast %struct.A addrspace(5)* %[[atmp]] to i8 addrspace(5)* +// CHECK: call void @llvm.lifetime.start.p5i8(i64 16, i8 addrspace(5)* %[[acst]] +void test() { + A a; + foo(a); +} -- 2.7.4