Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -3888,9 +3888,8 @@ assert(NumIRArgs == 1); if (!I->isAggregate()) { // Make a temporary alloca to pass the argument. - Address Addr = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(), - "indirect-arg-temp", /*Alloca=*/nullptr, - /*Cast=*/false); + Address Addr = CreateMemTempWithoutCast( + I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp"); IRCallArgs[FirstIRArg] = Addr.getPointer(); I->copyInto(*this, Addr); @@ -3935,9 +3934,8 @@ } if (NeedCopy) { // Create an aligned temporary, and copy to it. - Address AI = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(), - "byval-temp", /*Alloca=*/nullptr, - /*Cast=*/false); + Address AI = CreateMemTempWithoutCast( + I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); IRCallArgs[FirstIRArg] = AI.getPointer(); I->copyInto(*this, AI); } else { Index: lib/CodeGen/CGCleanup.cpp =================================================================== --- lib/CodeGen/CGCleanup.cpp +++ lib/CodeGen/CGCleanup.cpp @@ -283,8 +283,8 @@ void CodeGenFunction::initFullExprCleanup() { // Create a variable to decide whether the cleanup needs to be run. - Address active = CreateTempAlloca(Builder.getInt1Ty(), CharUnits::One(), - "cleanup.cond"); + Address active = CreateTempAllocaWithoutCast( + Builder.getInt1Ty(), CharUnits::One(), "cleanup.cond"); // Initialize it to false at a site that's guaranteed to be run // before each evaluation. Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -61,21 +61,30 @@ /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. +Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, + CharUnits Align, + const Twine &Name, + llvm::Value *ArraySize) { + auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); + Alloca->setAlignment(Align.getQuantity()); + return Address(Alloca, Align); +} + +/// CreateTempAlloca - This creates a alloca and inserts it into the entry +/// block. The alloca is casted to default address space if necessary. Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, const Twine &Name, llvm::Value *ArraySize, - Address *AllocaAddr, - bool CastToDefaultAddrSpace) { - auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); - Alloca->setAlignment(Align.getQuantity()); + Address *AllocaAddr) { + auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize); if (AllocaAddr) - *AllocaAddr = Address(Alloca, Align); - llvm::Value *V = Alloca; + *AllocaAddr = Alloca; + llvm::Value *V = Alloca.getPointer(); // Alloca always returns a pointer in alloca address space, which may // be different from the type defined by the language. For example, // in C++ the auto variables are in the default address space. Therefore // cast alloca to the default address space when necessary. - if (CastToDefaultAddrSpace && getASTAllocaAddressSpace() != LangAS::Default) { + if (getASTAllocaAddressSpace() != LangAS::Default) { auto DestAddrSpace = getContext().getTargetAddressSpace(LangAS::Default); llvm::IRBuilderBase::InsertPointGuard IPG(Builder); // When ArraySize is nullptr, alloca is inserted at AllocaInsertPt, @@ -128,19 +137,26 @@ } Address CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, - Address *Alloca, - bool CastToDefaultAddrSpace) { + Address *Alloca) { // FIXME: Should we prefer the preferred type alignment here? - return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca, - CastToDefaultAddrSpace); + return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca); } Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, - const Twine &Name, Address *Alloca, - bool CastToDefaultAddrSpace) { + const Twine &Name, Address *Alloca) { return CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, - /*ArraySize=*/nullptr, Alloca, - CastToDefaultAddrSpace); + /*ArraySize=*/nullptr, Alloca); +} + +Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, CharUnits Align, + const Twine &Name) { + return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty), Align, Name); +} + +Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, + const Twine &Name) { + return CreateMemTempWithoutCast(Ty, getContext().getTypeAlignInChars(Ty), + Name); } /// EvaluateExprAsBool - Perform the usual unary conversions on the specified Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2020,18 +2020,20 @@ /// to the stack. /// /// Because the address of a temporary is often exposed to the program in - /// various ways, this function will perform the cast by default. The cast - /// may be avoided by passing false as \p CastToDefaultAddrSpace; this is + /// various ways, this function will perform the cast. The original alloca + /// instruction is returned through \p Alloca if it is not nullptr. + /// + /// The cast is not performaed in CreateTempAllocaWithoutCast. This is /// more efficient if the caller knows that the address will not be exposed. - /// The original alloca instruction is returned through \p Alloca if it is - /// not nullptr. llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp", llvm::Value *ArraySize = nullptr); Address CreateTempAlloca(llvm::Type *Ty, CharUnits align, const Twine &Name = "tmp", llvm::Value *ArraySize = nullptr, - Address *Alloca = nullptr, - bool CastToDefaultAddrSpace = true); + Address *Alloca = nullptr); + Address CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, + const Twine &Name = "tmp", + llvm::Value *ArraySize = nullptr); /// CreateDefaultAlignedTempAlloca - This creates an alloca with the /// default ABI alignment of the given LLVM type. @@ -2066,15 +2068,18 @@ Address CreateIRTemp(QualType T, const Twine &Name = "tmp"); /// CreateMemTemp - Create a temporary memory object of the given type, with - /// appropriate alignment. Cast it to the default address space if - /// \p CastToDefaultAddrSpace is true. Returns the original alloca - /// instruction by \p Alloca if it is not nullptr. + /// appropriate alignmen and cast it to the default address space. Returns + /// the original alloca instruction by \p Alloca if it is not nullptr. Address CreateMemTemp(QualType T, const Twine &Name = "tmp", - Address *Alloca = nullptr, - bool CastToDefaultAddrSpace = true); + Address *Alloca = nullptr); Address CreateMemTemp(QualType T, CharUnits Align, const Twine &Name = "tmp", - Address *Alloca = nullptr, - bool CastToDefaultAddrSpace = true); + Address *Alloca = nullptr); + + /// CreateMemTemp - Create a temporary memory object of the given type, with + /// appropriate alignmen without casting it to the default address space. + Address CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); + Address CreateMemTempWithoutCast(QualType T, CharUnits Align, + const Twine &Name = "tmp"); /// CreateAggTemp - Create a temporary memory object for the given /// aggregate type. Index: test/CodeGenCXX/conditional-temporaries.cpp =================================================================== --- test/CodeGenCXX/conditional-temporaries.cpp +++ test/CodeGenCXX/conditional-temporaries.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O3 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=amdgcn-amd-amdhsa -O3 | FileCheck %s namespace {