CodeGen: Fix invalid bitcast for lifetime.start/end
lifetime.start/end expects pointer argument in alloca address space.
However in C++ a temporary variable is in default address space.
This patch changes API CreateMemTemp and CreateTempAlloca to
get the original alloca instruction and pass it lifetime.start/end.
It only affects targets with non-zero alloca address space.
Differential Revision: https://reviews.llvm.org/D45900
llvm-svn: 332593
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d22ac19..537f3a3 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3812,16 +3812,17 @@
// If the call returns a temporary with struct return, create a temporary
// alloca to hold the result, unless one is given to us.
Address SRetPtr = Address::invalid();
+ Address SRetAlloca = Address::invalid();
llvm::Value *UnusedReturnSizePtr = nullptr;
if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
if (!ReturnValue.isNull()) {
SRetPtr = ReturnValue.getValue();
} else {
- SRetPtr = CreateMemTemp(RetTy);
+ SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
if (HaveInsertPoint() && ReturnValue.isUnused()) {
uint64_t size =
CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
- UnusedReturnSizePtr = EmitLifetimeStart(size, SRetPtr.getPointer());
+ UnusedReturnSizePtr = EmitLifetimeStart(size, SRetAlloca.getPointer());
}
}
if (IRFunctionArgs.hasSRetArg()) {
@@ -3888,7 +3889,8 @@
if (!I->isAggregate()) {
// Make a temporary alloca to pass the argument.
Address Addr = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(),
- "indirect-arg-temp", false);
+ "indirect-arg-temp", /*Alloca=*/nullptr,
+ /*Cast=*/false);
IRCallArgs[FirstIRArg] = Addr.getPointer();
I->copyInto(*this, Addr);
@@ -3934,7 +3936,8 @@
if (NeedCopy) {
// Create an aligned temporary, and copy to it.
Address AI = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(),
- "byval-temp", false);
+ "byval-temp", /*Alloca=*/nullptr,
+ /*Cast=*/false);
IRCallArgs[FirstIRArg] = AI.getPointer();
I->copyInto(*this, AI);
} else {
@@ -4062,6 +4065,7 @@
llvm::Value *tempSize = nullptr;
Address addr = Address::invalid();
+ Address AllocaAddr = Address::invalid();
if (I->isAggregate()) {
addr = I->hasLValue() ? I->getKnownLValue().getAddress()
: I->getKnownRValue().getAggregateAddress();
@@ -4076,9 +4080,11 @@
// Materialize to a temporary.
addr = CreateTempAlloca(RV.getScalarVal()->getType(),
- CharUnits::fromQuantity(std::max(layout->getAlignment(),
- scalarAlign)));
- tempSize = EmitLifetimeStart(scalarSize, addr.getPointer());
+ CharUnits::fromQuantity(std::max(
+ layout->getAlignment(), scalarAlign)),
+ "tmp",
+ /*ArraySize=*/nullptr, &AllocaAddr);
+ tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer());
Builder.CreateStore(RV.getScalarVal(), addr);
}
@@ -4096,7 +4102,7 @@
assert(IRArgPos == FirstIRArg + NumIRArgs);
if (tempSize) {
- EmitLifetimeEnd(tempSize, addr.getPointer());
+ EmitLifetimeEnd(tempSize, AllocaAddr.getPointer());
}
break;
@@ -4258,7 +4264,7 @@
// pop this cleanup later on. Being eager about this is OK, since this
// temporary is 'invisible' outside of the callee.
if (UnusedReturnSizePtr)
- pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr,
+ pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetAlloca,
UnusedReturnSizePtr);
llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();