Skip to content

Cap the alignment of all types in Swift at 16 #15691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ enum class NominalTypeKind : uint32_t {
#include "MetadataKind.def"
};

/// The maximum supported type alignment.
const size_t MaximumAlignment = 16;

/// Flags stored in the value-witness table.
template <typename int_type>
class TargetValueWitnessFlags {
Expand All @@ -119,7 +122,7 @@ class TargetValueWitnessFlags {
// flags for the struct. (The "non-inline" and "has-extra-inhabitants" bits
// still require additional fixup.)
enum : int_type {
AlignmentMask = 0x0000FFFF,
AlignmentMask = 0x000000FF,
IsNonPOD = 0x00010000,
IsNonInline = 0x00020000,
HasExtraInhabitants = 0x00040000,
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsIRGen.def
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ ERROR(alignment_dynamic_type_layout_unsupported,none,
ERROR(alignment_less_than_natural,none,
"@_alignment cannot decrease alignment below natural alignment of %0",
(unsigned))
ERROR(alignment_more_than_maximum,none,
"@_alignment cannot increase alignment above maximum alignment of %0",
(unsigned))

#ifndef DIAG_NO_UNDEF
# if defined(DIAG)
Expand Down
8 changes: 8 additions & 0 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2512,6 +2512,10 @@ namespace {
return nullptr;
}

// Don't import nominal types that are over-aligned.
if (Impl.isOverAligned(decl))
return nullptr;

Optional<ImportedName> correctSwiftName;
auto importedName = getClangDeclName(decl, correctSwiftName);
if (!importedName)
Expand Down Expand Up @@ -2997,6 +3001,10 @@ namespace {
return nullptr;
}

// Don't import nominal types that are over-aligned.
if (Impl.isOverAligned(decl))
return nullptr;

// FIXME: We should actually support strong ARC references and similar in
// C structs. That'll require some SIL and IRGen work, though.
if (decl->isNonTrivialToPrimitiveCopy() ||
Expand Down
16 changes: 14 additions & 2 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "ImporterImpl.h"
#include "ClangDiagnosticConsumer.h"
#include "swift/Strings.h"
#include "swift/ABI/MetadataValues.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticEngine.h"
Expand Down Expand Up @@ -48,6 +49,16 @@ static bool isImportedCFPointer(clang::QualType clangType, Type type) {
(type->is<ClassType>() || type->isClassExistentialType()));
}

bool ClangImporter::Implementation::isOverAligned(const clang::TypeDecl *decl) {
auto type = getClangASTContext().getTypeDeclType(decl);
return isOverAligned(type);
}

bool ClangImporter::Implementation::isOverAligned(clang::QualType type) {
auto align = getClangASTContext().getTypeAlignInChars(type);
return align.getQuantity() > MaximumAlignment;
}

namespace {
/// Various types that we want to do something interesting to after
/// importing them.
Expand Down Expand Up @@ -377,9 +388,10 @@ namespace {
pointeeQualType, ImportTypeKind::Pointee, AllowNSUIntegerAsInt,
Bridgeability::None);

// If the pointed-to type is unrepresentable in Swift, import as
// If the pointed-to type is unrepresentable in Swift, or its C
// alignment is greater than the maximum Swift alignment, import as
// OpaquePointer.
if (!pointeeType) {
if (!pointeeType || Impl.isOverAligned(pointeeQualType)) {
auto opaquePointer = Impl.SwiftContext.getOpaquePointerDecl();
if (!opaquePointer)
return Type();
Expand Down
5 changes: 5 additions & 0 deletions lib/ClangImporter/ImporterImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,11 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
/// bound of "Hashable", which is used to validate NSDictionary/NSSet.
bool matchesHashableBound(Type type);

/// \brief Determines whether the type declared by the given declaration
/// is over-aligned.
bool isOverAligned(const clang::TypeDecl *typeDecl);
bool isOverAligned(clang::QualType type);

/// \brief Look up and attempt to import a Clang declaration with
/// the given name.
Decl *importDeclByName(StringRef name);
Expand Down
3 changes: 2 additions & 1 deletion lib/IRGen/GenStruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,8 @@ class ClangRecordLowering {
ClangDecl(clangDecl), ClangContext(clangDecl->getASTContext()),
ClangLayout(ClangContext.getASTRecordLayout(clangDecl)),
TotalStride(Size(ClangLayout.getSize().getQuantity())),
TotalAlignment(Alignment(ClangLayout.getAlignment().getQuantity())) {
TotalAlignment(IGM.getCappedAlignment(
Alignment(ClangLayout.getAlignment()))) {
SpareBits.reserve(TotalStride.getValue() * 8);
}

Expand Down
6 changes: 6 additions & 0 deletions lib/IRGen/GenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//
//===----------------------------------------------------------------------===//

#include "swift/ABI/MetadataValues.h"
#include "swift/AST/CanTypeVisitor.h"
#include "swift/AST/Decl.h"
#include "swift/AST/GenericEnvironment.h"
Expand Down Expand Up @@ -50,6 +51,10 @@
using namespace swift;
using namespace irgen;

Alignment IRGenModule::getCappedAlignment(Alignment align) {
return std::min(align, Alignment(MaximumAlignment));
}

llvm::DenseMap<TypeBase*, TypeCacheEntry> &
TypeConverter::Types_t::getCacheFor(bool isDependent, bool completelyFragile) {
if (completelyFragile) {
Expand Down Expand Up @@ -1638,6 +1643,7 @@ TypeCacheEntry TypeConverter::convertType(CanType ty) {
Size size;
Alignment align;
std::tie(llvmTy, size, align) = convertPrimitiveBuiltin(IGM, ty);
align = IGM.getCappedAlignment(align);
return createPrimitive(llvmTy, size, align);
}

Expand Down
1 change: 1 addition & 0 deletions lib/IRGen/IRGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class Alignment {

constexpr Alignment() : Value(0) {}
constexpr explicit Alignment(int_type Value) : Value(Value) {}
explicit Alignment(clang::CharUnits value) : Value(value.getQuantity()) {}

constexpr int_type getValue() const { return Value; }
constexpr int_type getMaskValue() const { return Value - 1; }
Expand Down
4 changes: 3 additions & 1 deletion lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ class IRGenModule {
clang::CanQual<clang::Type> getClangType(CanType type);
clang::CanQual<clang::Type> getClangType(SILType type);
clang::CanQual<clang::Type> getClangType(SILParameterInfo param);

const clang::ASTContext &getClangASTContext() {
assert(ClangASTContext &&
"requesting clang AST context without clang importer!");
Expand All @@ -761,6 +761,8 @@ class IRGenModule {
ResilienceExpansion getResilienceExpansionForLayout(NominalTypeDecl *decl);
ResilienceExpansion getResilienceExpansionForLayout(SILGlobalVariable *var);

Alignment getCappedAlignment(Alignment alignment);

SpareBitVector getSpareBitsForType(llvm::Type *scalarTy, Size size);

MetadataLayout &getMetadataLayout(NominalTypeDecl *decl);
Expand Down
10 changes: 8 additions & 2 deletions lib/IRGen/StructLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,14 @@ void irgen::applyLayoutAttributes(IRGenModule &IGM,
else if (value < MinimumAlign.getValue())
Diags.diagnose(alignment->getLocation(),
diag::alignment_less_than_natural, MinimumAlign.getValue());
else
MinimumAlign = Alignment(value);
else {
auto requestedAlignment = Alignment(value);
MinimumAlign = IGM.getCappedAlignment(requestedAlignment);
if (requestedAlignment > MinimumAlign)
Diags.diagnose(alignment->getLocation(),
diag::alignment_more_than_maximum,
MinimumAlign.getValue());
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion stdlib/public/SDK/simd/simd.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ cardinal = { 2:'two', 3:'three', 4:'four'}
% vectype = ctype[scalar] + str(count)
% llvm_vectype = "Vec" + str(count) + "x" + llvm_type[scalar]
% vecsize = (8 if scalar == 'Double' else 4) * (4 if count == 3 else count)
% vecalign = (16 if vecsize > 16 else vecsize)
% extractelement = "extractelement_" + llvm_vectype + "_Int32"
% insertelement = "insertelement_" + llvm_vectype + "_" + llvm_type[scalar] + "_Int32"
% is_floating = scalar in floating_types
Expand All @@ -40,7 +41,7 @@ cardinal = { 2:'two', 3:'three', 4:'four'}
/// A vector of ${cardinal[count]} `${scalar}`. This corresponds to the C and
/// Obj-C type `vector_${vectype}` and the C++ type `simd::${vectype}`.
@_fixed_layout
@_alignment(${vecsize})
@_alignment(${vecalign})
public struct ${vectype} {

public var _value: Builtin.${llvm_vectype}
Expand Down
10 changes: 5 additions & 5 deletions test/DebugInfo/alignment.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s

@_alignment(32)
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "S32"
// CHECK-SAME: align: 256,
struct S32 { var x, y, z, w: Float }
@_alignment(8)
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "S8"
// CHECK-SAME: align: 64,
struct S8 { var x, y, z, w: Float }

@_alignment(16)
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E16"
Expand All @@ -13,5 +13,5 @@ enum E16 {
case I(Int64)
}

var s: S32
var s: S8
var e: E16
2 changes: 1 addition & 1 deletion test/IRGen/builtins.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func generic_sizeof_alignof_test<T>(_: T) {
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
// CHECK-NEXT: [[T2:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK-NEXT: [[T3:%.*]] = and i64 [[T2]], 65535
// CHECK-NEXT: [[T3:%.*]] = and i64 [[T2]], 255
// CHECK-NEXT: [[ALIGN:%.*]] = add i64 [[T3]], 1
// CHECK-NEXT: store i64 [[ALIGN]], i64* [[A:%.*]]
var a = Builtin.alignof(T.self)
Expand Down
19 changes: 10 additions & 9 deletions test/IRGen/existentials_opaque_boxed.sil
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -emit-ir | %FileCheck %s
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -emit-ir | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-%target-ptrsize

sil_stage canonical

Expand Down Expand Up @@ -135,7 +135,7 @@ entry:
// CHECK: [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 8
// CHECK: [[VW2:%.*]] = load i8*, i8** [[VW_ADDR2]]
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[VW2]] to {{(i64|i32)}}
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 255
// CHECK: [[HEADERSIZEPLUSALIGN:%.*]] = add {{(i64 16|i32 8)}}, [[ALIGNMASK]]
// CHECK: [[NOTALIGNMASK:%.*]] = xor {{(i64|i32)}} [[ALIGNMASK]], -1
// CHECK: [[ALIGNEDSTART:%.*]] = and {{(i64|i32)}} [[HEADERSIZEPLUSALIGN]], [[NOTALIGNMASK]]
Expand Down Expand Up @@ -178,7 +178,7 @@ bb0(%0 : $*Existential):
// CHECK: boxed:
// CHECK: [[REFADDR:%.*]] = bitcast [{{(24|12)}} x i8]* %0 to %swift.refcounted**
// CHECK: [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[REFADDR]]
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 255
// CHECK: [[HEADERSIZEPLUSALIGN:%.*]] = add {{(i64 16|i32 8)}}, [[ALIGNMASK]]
// CHECK: [[NOTALIGNMASK:%.*]] = xor {{(i64|i32)}} [[ALIGNMASK]], -1
// CHECK: [[ALIGNEDSTART:%.*]] = and {{(i64|i32)}} [[HEADERSIZEPLUSALIGN]], [[NOTALIGNMASK]]
Expand Down Expand Up @@ -219,7 +219,7 @@ bb0(%0 : $*Existential):
// CHECK: ret %swift.opaque* [[VALUEADDRINLINE]]

// CHECK: boxed:
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 255
// CHECK: [[OPAQUE_ADDR:%.*]] = bitcast [{{(24|12)}} x i8]* %0 to %swift.opaque*
// CHECK: [[REFANDADDR:%.*]] = call swiftcc { %swift.refcounted*, %swift.opaque* } @swift_makeBoxUnique(%swift.opaque* [[OPAQUE_ADDR]], %swift.type* %1, {{(i64|i32)}} [[ALIGNMASK]])
// CHECK: [[REF:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[REFANDADDR]], 0
Expand Down Expand Up @@ -493,7 +493,7 @@ bb0(%0 : $*Existential):
return %t : $()
}

@_alignment(32)
@_alignment(16)
struct FixedOveralign : Existential {
var x : Int64
}
Expand All @@ -504,10 +504,11 @@ struct FixedOveralign : Existential {
// CHECK: [[CONTAINER:%.*]] = alloca %T25existentials_opaque_boxed11ExistentialP
// CHECK: [[INLINEBUFFER:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* [[CONTAINER]], i32 0, i32 0
// CHECK: [[INLINEBUFFER:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* [[CONTAINER]], i32 0, i32 0
// CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* getelementptr inbounds (%swift.full_boxmetadata, %swift.full_boxmetadata* @metadata.3, i32 0, i32 2), {{(i64|i32)}} 64, {{(i64|i32)}} 31)
// CHECK: [[BOX_ADDR:%.*]] = bitcast %swift.refcounted* [[BOX]] to <{ %swift.refcounted, [{{(16|24)}} x i8], [32 x i8] }>*
// CHECK: [[VALUE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [{{(16|24)}} x i8], [32 x i8] }>, <{ %swift.refcounted, [{{(16|24)}} x i8], [32 x i8] }>* [[BOX_ADDR]], i32 0, i32 {{(1|2)}}
// CHECK: [[INIT_EXIST_ADDR:%.*]] = bitcast [32 x i8]* [[VALUE_ADDR]] to %T25existentials_opaque_boxed14FixedOveralignV*
// CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* getelementptr inbounds (%swift.full_boxmetadata, %swift.full_boxmetadata* @metadata.3, i32 0, i32 2), {{(i64|i32)}} 32, {{(i64|i32)}} 15)
// CHECK-64: [[BOX_ADDR:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[BOX_TYPE:<{ %swift.refcounted, \[16 x i8\] }>]]*
// CHECK-32: [[BOX_ADDR:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[BOX_TYPE:<{ %swift.refcounted, \[8 x i8\], \[16 x i8\] }>]]*
// CHECK: [[VALUE_ADDR:%.*]] = getelementptr inbounds [[BOX_TYPE]], [[BOX_TYPE]]* [[BOX_ADDR]], i32 0, i32 {{(1|2)}}
// CHECK: [[INIT_EXIST_ADDR:%.*]] = bitcast [16 x i8]* [[VALUE_ADDR]] to %T25existentials_opaque_boxed14FixedOveralignV*
// CHECK: [[INLINEBUFFER_ADDR:%.*]] = bitcast [{{(24|12)}} x i8]* [[INLINEBUFFER]] to %swift.refcounted**
// CHECK: store %swift.refcounted* [[BOX]], %swift.refcounted** [[INLINEBUFFER_ADDR]]
// CHECK: ret void
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/global_resilience.sil
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ bb0:
// CHECK: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[SIZEWITNESS:%.*]] = load i8*, i8** [[SIZE_ADDR]]
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZEWITNESS]]
// CHECK: [[ALIGN:%.*]] = and {{.*}} [[FLAGS]], 65535
// CHECK: [[ALIGN:%.*]] = and {{.*}} [[FLAGS]], 255
// CHECK: [[PTR:%.*]] = call noalias i8* @swift_slowAlloc({{.*}} [[SIZE]], {{.*}} [[ALIGN]])
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* %1 to i8**
// CHECK: store i8* [[PTR]], i8** [[ADDR]]
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/indirect_argument.sil
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct Huge {
var x, y, z, w, v: Builtin.Word
}

@_alignment(32)
@_alignment(16)
struct HugeAlignment {
var x, y, z, w, v: Builtin.Word
}
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/int_to_fp.sil
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sil_stage canonical
import Builtin

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc float @test_large(i2048* noalias nocapture dereferenceable(256)
// CHECK: %1 = load i2048, i2048* %0, align 256
// CHECK: %1 = load i2048, i2048* %0, align 16
// CHECK: %2 = trunc i2048 %1 to i64
// CHECK: %3 = sitofp i64 %2 to float
// CHECK: ret float %3
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/partial_apply.sil
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ sil public_external @captured_fixed_and_dependent_params : $@convention(thin) <A
// CHECK: [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
// CHECK: [[T_FLAGS_PTR:%.*]] = load {{.*}} [[T_FLAGS_ADDR]]
// CHECK: [[T_FLAGS:%.*]] = ptrtoint {{.*}} [[T_FLAGS_PTR]] to [[WORD]]
// CHECK: [[T_ALIGN_MASK:%.*]] = and [[WORD]] [[T_FLAGS]], 65535
// CHECK: [[T_ALIGN_MASK:%.*]] = and [[WORD]] [[T_FLAGS]], 255
// CHECK: [[T_ALIGN_MASK_NOT:%.*]] = xor [[WORD]] [[T_ALIGN_MASK]], -1
// -- 32 is 64-bit offset of 'T' field, 16 for obj header + 8 for T metadata + 8 for SwiftClass field
// CHECK-64: [[T_UP_TO_ALIGN_1:%.*]] = add i64 32, [[T_ALIGN_MASK]]
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/struct_with_resilient_type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct ProtAndResilStruct {
fooImp.foo(ptr: bar)
}
// CHECK-LABEL: define{{.*}} @"$S26struct_with_resilient_type18ProtAndResilStructV3baryyFTc"(%T26struct_with_resilient_type18ProtAndResilStructV* noalias nocapture)
// CHECK: %flags.alignmentMask = and i64 %flags, 65535
// CHECK: %flags.alignmentMask = and i64 %flags, 255
// CHECK: [[XOR_ALIGN:%.*]] = xor i64 %flags.alignmentMask, -1
// CHECK: [[INIT_OFFSET:%.*]] = add i64 16, %flags.alignmentMask
// CHECK: [[T0:%.*]] = and i64 [[INIT_OFFSET]], [[XOR_ALIGN]]
Expand Down
17 changes: 9 additions & 8 deletions test/IRGen/typed_boxes.sil
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,23 @@ entry:
return undef : $()
}

@_alignment(32)
@_alignment(16)
struct OverAligned {
var x, y, z, w: Builtin.Int64
}

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @pod_box_32_32
sil @pod_box_32_32 : $@convention(thin) () -> () {
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @pod_box_32_16
sil @pod_box_32_16 : $@convention(thin) () -> () {
entry:
// CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* {{.*}} [[POD_32_32_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 64, [[WORD]] 31)
// CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* {{.*}} [[POD_32_16_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 48, [[WORD]] 15)
%a = alloc_box $<τ_0_0> { var τ_0_0 } <OverAligned>
// CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_32_LAYOUT:<\{ %swift.refcounted, \[24 x i8\], \[32 x i8\] \}>]]*
// CHECK-64: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_32_LAYOUT:<\{ %swift.refcounted, \[16 x i8\], \[32 x i8\] \}>]]*
// CHECK: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_32_32_LAYOUT]], [[POD_32_32_LAYOUT]]* [[BOX_RAW]], i32 0, i32 2
// CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_16_LAYOUT:<\{ %swift.refcounted, \[8 x i8\], \[32 x i8\] \}>]]*
// CHECK-32: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_32_16_LAYOUT]], [[POD_32_16_LAYOUT]]* [[BOX_RAW]], i32 0, i32 2
// CHECK-64: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_16_LAYOUT:<\{ %swift.refcounted, \[32 x i8\] \}>]]*
// CHECK-64: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_32_16_LAYOUT]], [[POD_32_16_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
// CHECK: [[BOX_DATA_1:%.*]] = bitcast [32 x i8]* [[BOX_DATA]] to %T11typed_boxes11OverAlignedV*
%b = project_box %a : $<τ_0_0> { var τ_0_0 } <OverAligned>, 0
// CHECK: call void @swift_deallocUninitializedObject(%swift.refcounted* [[BOX]], [[WORD]] 64, [[WORD]] 31)
// CHECK: call void @swift_deallocUninitializedObject(%swift.refcounted* [[BOX]], [[WORD]] 48, [[WORD]] 15)
dealloc_box %a : $<τ_0_0> { var τ_0_0 } <OverAligned>
return undef : $()
}
Expand Down