r354861 - CodeGen: Explicitly initialize structure padding in the -ftrivial-auto-var-init mode
Alexander Potapenko via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 26 02:46:21 PST 2019
Author: glider
Date: Tue Feb 26 02:46:21 2019
New Revision: 354861
URL: http://llvm.org/viewvc/llvm-project?rev=354861&view=rev
Log:
CodeGen: Explicitly initialize structure padding in the -ftrivial-auto-var-init mode
When generating initializers for local structures in the
-ftrivial-auto-var-init mode, explicitly wipe the padding bytes with
either 0x00 or 0xAA.
This will allow us to automatically handle the padding when splitting
the initialization stores (see https://reviews.llvm.org/D57898).
Reviewed at https://reviews.llvm.org/D58188
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/auto-var-init.cpp
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=354861&r1=354860&r2=354861&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Feb 26 02:46:21 2019
@@ -1048,6 +1048,98 @@ static llvm::Constant *patternFor(CodeGe
return llvm::ConstantStruct::get(StructTy, Struct);
}
+enum class IsPattern { No, Yes };
+
+/// Generate a constant filled with either a pattern or zeroes.
+static llvm::Constant *patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Type *Ty) {
+ if (isPattern == IsPattern::Yes)
+ return patternFor(CGM, Ty);
+ else
+ return llvm::Constant::getNullValue(Ty);
+}
+
+static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Constant *constant);
+
+/// Helper function for constWithPadding() to deal with padding in structures.
+static llvm::Constant *constStructWithPadding(CodeGenModule &CGM,
+ IsPattern isPattern,
+ llvm::StructType *STy,
+ llvm::Constant *constant) {
+ const llvm::DataLayout &DL = CGM.getDataLayout();
+ const llvm::StructLayout *Layout = DL.getStructLayout(STy);
+ llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());
+ unsigned SizeSoFar = 0;
+ SmallVector<llvm::Constant *, 8> Values;
+ bool NestedIntact = true;
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; i++) {
+ unsigned CurOff = Layout->getElementOffset(i);
+ if (SizeSoFar < CurOff) {
+ assert(!STy->isPacked());
+ auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar);
+ Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy));
+ }
+ llvm::Constant *CurOp;
+ if (constant->isZeroValue())
+ CurOp = llvm::Constant::getNullValue(STy->getElementType(i));
+ else
+ CurOp = cast<llvm::Constant>(constant->getAggregateElement(i));
+ auto *NewOp = constWithPadding(CGM, isPattern, CurOp);
+ if (CurOp != NewOp)
+ NestedIntact = false;
+ Values.push_back(NewOp);
+ SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());
+ }
+ unsigned TotalSize = Layout->getSizeInBytes();
+ if (SizeSoFar < TotalSize) {
+ auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);
+ Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy));
+ }
+ if (NestedIntact && Values.size() == STy->getNumElements())
+ return constant;
+ return llvm::ConstantStruct::getAnon(Values);
+}
+
+/// Replace all padding bytes in a given constant with either a pattern byte or
+/// 0x00.
+static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Constant *constant) {
+ llvm::Type *OrigTy = constant->getType();
+ if (const auto STy = dyn_cast<llvm::StructType>(OrigTy))
+ return constStructWithPadding(CGM, isPattern, STy, constant);
+ if (auto *STy = dyn_cast<llvm::SequentialType>(OrigTy)) {
+ llvm::SmallVector<llvm::Constant *, 8> Values;
+ unsigned Size = STy->getNumElements();
+ if (!Size)
+ return constant;
+ llvm::Type *ElemTy = STy->getElementType();
+ bool ZeroInitializer = constant->isZeroValue();
+ llvm::Constant *OpValue, *PaddedOp;
+ if (ZeroInitializer) {
+ OpValue = llvm::Constant::getNullValue(ElemTy);
+ PaddedOp = constWithPadding(CGM, isPattern, OpValue);
+ }
+ for (unsigned Op = 0; Op != Size; ++Op) {
+ if (!ZeroInitializer) {
+ OpValue = constant->getAggregateElement(Op);
+ PaddedOp = constWithPadding(CGM, isPattern, OpValue);
+ }
+ Values.push_back(PaddedOp);
+ }
+ auto *NewElemTy = Values[0]->getType();
+ if (NewElemTy == ElemTy)
+ return constant;
+ if (OrigTy->isArrayTy()) {
+ auto *ArrayTy = llvm::ArrayType::get(NewElemTy, Size);
+ return llvm::ConstantArray::get(ArrayTy, Values);
+ } else {
+ return llvm::ConstantVector::get(Values);
+ }
+ }
+ return constant;
+}
+
static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D,
CGBuilderTy &Builder,
llvm::Constant *Constant,
@@ -1146,7 +1238,8 @@ static void emitStoresForZeroInit(CodeGe
Address Loc, bool isVolatile,
CGBuilderTy &Builder) {
llvm::Type *ElTy = Loc.getElementType();
- llvm::Constant *constant = llvm::Constant::getNullValue(ElTy);
+ llvm::Constant *constant =
+ constWithPadding(CGM, IsPattern::No, llvm::Constant::getNullValue(ElTy));
emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
}
@@ -1154,7 +1247,8 @@ static void emitStoresForPatternInit(Cod
Address Loc, bool isVolatile,
CGBuilderTy &Builder) {
llvm::Type *ElTy = Loc.getElementType();
- llvm::Constant *constant = patternFor(CGM, ElTy);
+ llvm::Constant *constant =
+ constWithPadding(CGM, IsPattern::Yes, patternFor(CGM, ElTy));
assert(!isa<llvm::UndefValue>(constant));
emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
}
@@ -1170,13 +1264,11 @@ static bool containsUndef(llvm::Constant
return false;
}
-static llvm::Constant *replaceUndef(llvm::Constant *constant) {
- // FIXME: when doing pattern initialization, replace undef with 0xAA instead.
- // FIXME: also replace padding between values by creating a new struct type
- // which has no padding.
+static llvm::Constant *replaceUndef(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Constant *constant) {
auto *Ty = constant->getType();
if (isa<llvm::UndefValue>(constant))
- return llvm::Constant::getNullValue(Ty);
+ return patternOrZeroFor(CGM, isPattern, Ty);
if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
return constant;
if (!containsUndef(constant))
@@ -1184,7 +1276,7 @@ static llvm::Constant *replaceUndef(llvm
llvm::SmallVector<llvm::Constant *, 8> Values(constant->getNumOperands());
for (unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
auto *OpValue = cast<llvm::Constant>(constant->getOperand(Op));
- Values[Op] = replaceUndef(OpValue);
+ Values[Op] = replaceUndef(CGM, isPattern, OpValue);
}
if (Ty->isStructTy())
return llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Values);
@@ -1680,7 +1772,8 @@ void CodeGenFunction::EmitAutoVarInit(co
case LangOptions::TrivialAutoVarInitKind::Pattern: {
llvm::Type *ElTy = Loc.getElementType();
- llvm::Constant *Constant = patternFor(CGM, ElTy);
+ llvm::Constant *Constant =
+ constWithPadding(CGM, IsPattern::Yes, patternFor(CGM, ElTy));
CharUnits ConstantAlign = getContext().getTypeAlignInChars(VlaSize.Type);
llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop");
llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop");
@@ -1726,8 +1819,14 @@ void CodeGenFunction::EmitAutoVarInit(co
assert(!capturedByInit && "constant init contains a capturing block?");
constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
if (constant && trivialAutoVarInit !=
- LangOptions::TrivialAutoVarInitKind::Uninitialized)
- constant = replaceUndef(constant);
+ LangOptions::TrivialAutoVarInitKind::Uninitialized) {
+ IsPattern isPattern =
+ (trivialAutoVarInit == LangOptions::TrivialAutoVarInitKind::Pattern)
+ ? IsPattern::Yes
+ : IsPattern::No;
+ constant = constWithPadding(CGM, isPattern,
+ replaceUndef(CGM, isPattern, constant));
+ }
}
if (!constant) {
Modified: cfe/trunk/test/CodeGenCXX/auto-var-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/auto-var-init.cpp?rev=354861&r1=354860&r2=354861&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/auto-var-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/auto-var-init.cpp Tue Feb 26 02:46:21 2019
@@ -48,20 +48,36 @@ struct smallpartinit { char c = 42, d; }
// PATTERN: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
// PATTERN: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
struct nullinit { char* null = nullptr; };
-// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
-// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] c"\AA\AA\AA", i32 13371337 }, align 4
+// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
struct padded { char c; int i; };
-// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
struct paddednullinit { char c = 0; int i = 0; };
+// PATTERN: @__const.test_paddedpacked_uninit.uninit = private unnamed_addr constant %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, align 1
+// PATTERN: @__const.test_paddedpacked_custom.custom = private unnamed_addr constant %struct.paddedpacked <{ i8 42, i32 13371337 }>, align 1
+// ZERO: @__const.test_paddedpacked_custom.custom = private unnamed_addr constant %struct.paddedpacked <{ i8 42, i32 13371337 }>, align 1
+struct paddedpacked { char c; int i; } __attribute__((packed));
+// PATTERN: @__const.test_paddedpackedarray_uninit.uninit = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>] }, align 1
+// PATTERN: @__const.test_paddedpackedarray_custom.custom = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }>] }, align 1
+// ZERO: @__const.test_paddedpackedarray_custom.custom = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }>] }, align 1
+struct paddedpackedarray { struct paddedpacked p[2]; };
+// PATTERN: @__const.test_paddednested_uninit.uninit = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 } }, align 4
+// PATTERN: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] c"\AA\AA\AA", i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] c"\AA\AA\AA", i32 13371338 } }, align 4
+// ZERO: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
+struct paddednested { struct padded p1, p2; };
+// PATTERN: @__const.test_paddedpackednested_uninit.uninit = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }> }, align 1
+// PATTERN: @__const.test_paddedpackednested_custom.custom = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }> }, align 1
+// ZERO: @__const.test_paddedpackednested_custom.custom = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }> }, align 1
+struct paddedpackednested { struct paddedpacked p1, p2; };
// PATTERN: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
-// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] c"\AA\AA\AA" }, align 4
// ZERO: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
struct bitfield { int i : 4; int j : 2; };
// PATTERN: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
-// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] c"\AA\AA\AA", i8 1, [3 x i8] c"\AA\AA\AA" }, align 4
// ZERO: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
struct bitfieldaligned { int i : 4; int : 0; int j : 2; };
struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; };
@@ -78,14 +94,14 @@ struct arraytail { int i; int arr[]; };
// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
-// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }], align 16
-// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
-// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }], align 16
+// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }], align 16
+// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
struct tailpad { short s; char c; };
// PATTERN: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
struct notlockfree { long long a[4]; };
-// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 8
-// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant %struct.tailpad { i16 -21846, i8 -86 }, align 4
+// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 8
+// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, align 4
// PATTERN: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
// PATTERN: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
// PATTERN: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
@@ -122,7 +138,7 @@ union matchingreverse { float f; int i;
// ZERO: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
union unmatched { char c; int i; };
// PATTERN: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] c"\AA\AA\AA" }, align 4
// ZERO: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
union unmatchedreverse { int i; char c; };
// PATTERN: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
@@ -625,6 +641,98 @@ TEST_CUSTOM(paddednullinit, paddednullin
// CHECK-NEXT: store i32 13371337, i32* %[[I]], align [[ALIGN]]
// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+TEST_UNINIT(paddedpacked, paddedpacked);
+// CHECK-LABEL: @test_paddedpacked_uninit()
+// CHECK: %uninit = alloca %struct.paddedpacked, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpacked_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddedpacked_uninit.uninit
+// ZERO-LABEL: @test_paddedpacked_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpacked, paddedpacked);
+// CHECK-LABEL: @test_paddedpacked_braces()
+// CHECK: %braces = alloca %struct.paddedpacked, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 5, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpacked, paddedpacked, { 42, 13371337 });
+// CHECK-LABEL: @test_paddedpacked_custom()
+// CHECK: %custom = alloca %struct.paddedpacked, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddedpackedarray, paddedpackedarray);
+// CHECK-LABEL: @test_paddedpackedarray_uninit()
+// CHECK: %uninit = alloca %struct.paddedpackedarray, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpackedarray_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddedpackedarray_uninit.uninit
+// ZERO-LABEL: @test_paddedpackedarray_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpackedarray, paddedpackedarray);
+// CHECK-LABEL: @test_paddedpackedarray_braces()
+// CHECK: %braces = alloca %struct.paddedpackedarray, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 10, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpackedarray, paddedpackedarray, { {{ 42, 13371337 }, { 43, 13371338 }} });
+// CHECK-LABEL: @test_paddedpackedarray_custom()
+// CHECK: %custom = alloca %struct.paddedpackedarray, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddednested, paddednested);
+// CHECK-LABEL: @test_paddednested_uninit()
+// CHECK: %uninit = alloca %struct.paddednested, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddednested_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddednested_uninit.uninit
+// ZERO-LABEL: @test_paddednested_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddednested, paddednested);
+// CHECK-LABEL: @test_paddednested_braces()
+// CHECK: %braces = alloca %struct.paddednested, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddednested, paddednested, { { 42, 13371337 }, { 43, 13371338 } });
+// CHECK-LABEL: @test_paddednested_custom()
+// CHECK: %custom = alloca %struct.paddednested, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddedpackednested, paddedpackednested);
+// CHECK-LABEL: @test_paddedpackednested_uninit()
+// CHECK: %uninit = alloca %struct.paddedpackednested, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpackednested_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddedpackednested_uninit.uninit
+// ZERO-LABEL: @test_paddedpackednested_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpackednested, paddedpackednested);
+// CHECK-LABEL: @test_paddedpackednested_braces()
+// CHECK: %braces = alloca %struct.paddedpackednested, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 10, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpackednested, paddedpackednested, { { 42, 13371337 }, { 43, 13371338 } });
+// CHECK-LABEL: @test_paddedpackednested_custom()
+// CHECK: %custom = alloca %struct.paddedpackednested, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
TEST_UNINIT(bitfield, bitfield);
// CHECK-LABEL: @test_bitfield_uninit()
// CHECK: %uninit = alloca %struct.bitfield, align
More information about the cfe-commits
mailing list