// Unknown builtin, for now just dump it out and return undef.
if (hasAggregateLLVMType(E->getType()))
- return RValue::getAggregate(CreateTempAlloca(ConvertTypeForMem(
- E->getType())));
+ return RValue::getAggregate(CreateMemTemp(E->getType()));
return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
}
// Create a temporary alloca to hold the argument; the rest of
// codegen expects to access aggregates & complex values by
// reference.
- V = CreateTempAlloca(ConvertTypeForMem(Ty));
+ V = CreateMemTemp(Ty);
Builder.CreateStore(AI, V);
} else {
if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
// If this structure was expanded into multiple arguments then
// we need to create a temporary and reconstruct it from the
// arguments.
- llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(Ty),
- Arg->getName() + ".addr");
+ llvm::Value *Temp = CreateMemTemp(Ty, Arg->getName() + ".addr");
// FIXME: What are the right qualifiers here?
llvm::Function::arg_iterator End =
ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI);
case ABIArgInfo::Ignore:
// Initialize the local variable appropriately.
if (hasAggregateLLVMType(Ty)) {
- EmitParmDecl(*Arg, CreateTempAlloca(ConvertTypeForMem(Ty)));
+ EmitParmDecl(*Arg, CreateMemTemp(Ty));
} else {
EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())));
}
// FIXME: This is very wasteful; EmitParmDecl is just going to drop the
// result in a new alloca anyway, so we could just store into that
// directly if we broke the abstraction down more.
- llvm::Value *V = CreateTempAlloca(ConvertTypeForMem(Ty), "coerce");
+ llvm::Value *V = CreateMemTemp(Ty, "coerce");
CreateCoercedStore(AI, V, /*DestIsVolatile=*/false, *this);
// Match to what EmitParmDecl is expecting for this type.
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
if (CGM.ReturnTypeUsesSret(CallInfo)) {
llvm::Value *Value = ReturnValue.getValue();
if (!Value)
- Value = CreateTempAlloca(ConvertTypeForMem(RetTy));
+ Value = CreateMemTemp(RetTy);
Args.push_back(Value);
}
case ABIArgInfo::Indirect:
if (RV.isScalar() || RV.isComplex()) {
// Make a temporary alloca to pass the argument.
- Args.push_back(CreateTempAlloca(ConvertTypeForMem(I->second)));
+ Args.push_back(CreateMemTemp(I->second));
if (RV.isScalar())
EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false, I->second);
else
// FIXME: Avoid the conversion through memory if possible.
llvm::Value *SrcPtr;
if (RV.isScalar()) {
- SrcPtr = CreateTempAlloca(ConvertTypeForMem(I->second), "coerce");
+ SrcPtr = CreateMemTemp(I->second, "coerce");
EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, I->second);
} else if (RV.isComplex()) {
- SrcPtr = CreateTempAlloca(ConvertTypeForMem(I->second), "coerce");
+ SrcPtr = CreateMemTemp(I->second, "coerce");
StoreComplexToAddr(RV.getComplexVal(), SrcPtr, false);
} else
SrcPtr = RV.getAggregateAddr();
bool DestIsVolatile = ReturnValue.isVolatile();
if (!DestPtr) {
- DestPtr = CreateTempAlloca(ConvertTypeForMem(RetTy), "agg.tmp");
+ DestPtr = CreateMemTemp(RetTy, "agg.tmp");
DestIsVolatile = false;
}
Builder.CreateStore(CI, DestPtr, DestIsVolatile);
bool DestIsVolatile = ReturnValue.isVolatile();
if (!DestPtr) {
- DestPtr = CreateTempAlloca(ConvertTypeForMem(RetTy), "coerce");
+ DestPtr = CreateMemTemp(RetTy, "coerce");
DestIsVolatile = false;
}
DeclPtr = Arg;
} else {
// Otherwise, create a temporary to hold the value.
- DeclPtr = CreateTempAlloca(ConvertTypeForMem(Ty));
- DeclPtr->setName(D.getName() + ".addr");
+ DeclPtr = CreateMemTemp(Ty, D.getName() + ".addr");
// Store the initial value into the alloca.
EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Ty);
return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
}
+llvm::Value *CodeGenFunction::CreateMemTemp(QualType Ty, const llvm::Twine &Name) {
+ llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty), Name);
+ // FIXME: Should we prefer the preferred type alignment here?
+ CharUnits Align = getContext().getTypeAlignInChars(Ty);
+ Alloc->setAlignment(Align.getQuantity());
+ return Alloc;
+}
+
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
Val = RValue::get(Val.getAggregateAddr());
} else {
// Create a temporary variable that we can bind the reference to.
- llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(E->getType()),
- "reftmp");
+ llvm::Value *Temp = CreateMemTemp(E->getType(), "reftmp");
if (Val.isScalar())
EmitStoreOfScalar(Val.getScalarVal(), Temp, false, E->getType());
else
llvm::Value *Vec = EmitScalarExpr(E->getBase());
// Store the vector to memory (because LValue wants an address).
- llvm::Value *VecMem = CreateTempAlloca(ConvertTypeForMem(
- E->getBase()->getType()));
+ llvm::Value *VecMem = CreateMemTemp(E->getBase()->getType());
Builder.CreateStore(Vec, VecMem);
Base = LValue::MakeAddr(VecMem, Qualifiers());
}
if (!LHS.isSimple())
return EmitUnsupportedLValue(E, "conditional operator");
+ // FIXME: We shouldn't need an alloca for this.
llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),"condtmp");
Builder.CreateStore(LHS.getAddress(), Temp);
EmitBranch(ContBlock);
LValue CodeGenFunction::EmitNullInitializationLValue(
const CXXZeroInitValueExpr *E) {
QualType Ty = E->getType();
- llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty));
- CharUnits Align = getContext().getTypeAlignInChars(Ty);
- Alloc->setAlignment(Align.getQuantity());
- LValue lvalue = LValue::MakeAddr(Alloc, Qualifiers());
- EmitMemSetToZero(lvalue.getAddress(), Ty);
- return lvalue;
+ LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
+ EmitMemSetToZero(LV.getAddress(), Ty);
+ return LV;
}
//===--------------------------------------------------------------------===//
}
LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
- llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(E->getType()), "tmp");
+ llvm::Value *Temp = CreateMemTemp(E->getType(), "tmp");
EmitCXXConstructExpr(Temp, E);
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
}
return;
// If the source is volatile, we must read from it; to do that, we need
// some place to put it.
- DestPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()), "agg.tmp");
+ DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
}
if (RequiresGCollection) {
case CastExpr::CK_BaseToDerivedMemberPointer: {
QualType SrcType = E->getSubExpr()->getType();
- llvm::Value *Src = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(SrcType),
- "tmp");
+ llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
if (LHS.isPropertyRef()) {
llvm::Value *AggLoc = DestPtr;
if (!AggLoc)
- AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType()));
+ AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
RValue::getAggregate(AggLoc, VolatileDest));
} else if (LHS.isKVCRef()) {
llvm::Value *AggLoc = DestPtr;
if (!AggLoc)
- AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType()));
+ AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
RValue::getAggregate(AggLoc, VolatileDest));
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
// FIXME: volatile
CGF.EmitAggExpr(E->getSubExpr(), Val, false);
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
if (E->requiresZeroInitialization())
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
}
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
LValue LV = LValue::MakeAddr(Val, Qualifiers());
EmitNullInitializationToLValue(LV, E->getType());
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
LValue LV = LValue::MakeAddr(Val, Qualifiers());
EmitNullInitializationToLValue(LV, E->getType());
LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
Qualifiers Q = MakeQualifiers(E->getType());
- llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(E->getType()));
+ llvm::Value *Temp = CreateMemTemp(E->getType());
EmitAggExpr(E, Temp, Q.hasVolatile());
return LValue::MakeAddr(Temp, Q);
}
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
// Get the member function pointer.
- llvm::Value *MemFnPtr =
- CreateTempAlloca(ConvertTypeForMem(MemFnExpr->getType()), "mem.fn");
+ llvm::Value *MemFnPtr = CreateMemTemp(MemFnExpr->getType(), "mem.fn");
EmitAggExpr(MemFnExpr, MemFnPtr, /*VolatileDest=*/false);
// Emit the 'this' pointer.
// Fast enumeration state.
QualType StateTy = getContext().getObjCFastEnumerationStateType();
- llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertTypeForMem(
- StateTy), "state.ptr");
- StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3);
+ llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
EmitMemSetToZero(StatePtr, StateTy);
// Number of elements in the items array.
getContext().getConstantArrayType(getContext().getObjCIdType(),
llvm::APInt(32, NumItems),
ArrayType::Normal, 0);
- llvm::Value *ItemsPtr = CreateTempAlloca(ConvertTypeForMem(
- ItemsTy), "items.ptr");
+ llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
llvm::Value *Collection = EmitScalarExpr(S.getCollection());
FastEnumSel,
Collection, false, Args);
- llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr");
+ llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
+ "limit.ptr");
Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
llvm::BasicBlock *NoElements = createBasicBlock("noelements");
EmitBlock(SetStartMutations);
- llvm::Value *StartMutationsPtr =
- CreateTempAlloca(UnsignedLongLTy);
+ llvm::Value *StartMutationsPtr = CreateMemTemp(getContext().UnsignedLongTy);
llvm::Value *StateMutationsPtrPtr =
Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
llvm::BasicBlock *LoopStart = createBasicBlock("loopstart");
EmitBlock(LoopStart);
- llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr");
+ llvm::Value *CounterPtr = CreateMemTemp(getContext().UnsignedLongTy,
+ "counter.ptr");
Builder.CreateStore(Zero, CounterPtr);
llvm::BasicBlock *LoopBody = createBasicBlock("loopbody");
}
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
- /// block.
+ /// block. The caller is responsible for setting an appropriate alignment on
+ /// the alloca.
llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty,
const llvm::Twine &Name = "tmp");
+ /// CreateMemTemp - Create a temporary memory object of the given type, with
+ /// appropriate alignment.
+ llvm::Value *CreateMemTemp(QualType T, const llvm::Twine &Name = "tmp");
+
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
llvm::Value *EvaluateExprAsBool(const Expr *E);
// RUN: %clang_cc1 -emit-llvm < %s -o - | FileCheck %s
// CHECK:%struct.S = type { i32, i32 }
// CHECK:define void @test_addrspace(%struct.S addrspace(1)* %p1, %struct.S addrspace(2)* %p2) nounwind
-// CHECK: [[p1addr:%.*]] = alloca %struct.S addrspace(1)* ; <%struct.S addrspace(1)**> [#uses=3]
-// CHECK: [[p2addr:%.*]] = alloca %struct.S addrspace(2)* ; <%struct.S addrspace(2)**> [#uses=3]
+// CHECK: [[p1addr:%.*]] = alloca %struct.S addrspace(1)*
+// CHECK: [[p2addr:%.*]] = alloca %struct.S addrspace(2)*
// CHECK: store %struct.S addrspace(1)* %p1, %struct.S addrspace(1)** [[p1addr]]
// CHECK: store %struct.S addrspace(2)* %p2, %struct.S addrspace(2)** [[p2addr]]
// CHECK: [[t0:%.*]] = load %struct.S addrspace(2)** [[p2addr]] ; <%struct.S addrspace(2)*> [#uses=1]
--- /dev/null
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+//
+// CHECK: alloca %struct.MemsetRange, align 16
+
+struct MemsetRange {
+ int Start, End;
+ unsigned Alignment;
+ int TheStores __attribute__((aligned(16)));
+};
+void foobar() {
+ (void) MemsetRange();
+}