mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
IRGen: Remove initializeBufferWithTakeOfBuffer in favor of memcpy
And update the existential container's initializeWithTake implementation in the runtime. After only allowing bitwise takable values in the inline buffer we can use memcpy to move existential container values. rdar://31414907 SR-343
This commit is contained in:
@@ -172,14 +172,6 @@ FUNCTION_VALUE_WITNESS(assignWithTake,
|
|||||||
MUTABLE_VALUE_TYPE,
|
MUTABLE_VALUE_TYPE,
|
||||||
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
|
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
|
||||||
|
|
||||||
/// T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self);
|
|
||||||
/// Given an invalid buffer, initialize it by taking the value out of
|
|
||||||
/// the source buffer.
|
|
||||||
FUNCTION_VALUE_WITNESS(initializeBufferWithTakeOfBuffer,
|
|
||||||
InitializeBufferWithTakeOfBuffer,
|
|
||||||
MUTABLE_VALUE_TYPE,
|
|
||||||
(MUTABLE_BUFFER_TYPE, MUTABLE_BUFFER_TYPE, TYPE_TYPE))
|
|
||||||
|
|
||||||
/// unsigned (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases)
|
/// unsigned (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases)
|
||||||
/// Given an instance of valid single payload enum with a payload of this
|
/// Given an instance of valid single payload enum with a payload of this
|
||||||
/// witness table's type (e.g Optional<ThisType>) , get the tag of the enum.
|
/// witness table's type (e.g Optional<ThisType>) , get the tag of the enum.
|
||||||
|
|||||||
@@ -343,16 +343,11 @@ public:
|
|||||||
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
|
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
|
||||||
SILType T, bool isOutlined) const override {
|
SILType T, bool isOutlined) const override {
|
||||||
if (isOutlined) {
|
if (isOutlined) {
|
||||||
llvm::Value *metadata = copyType(IGF, dest, src);
|
// memcpy the existential container. This is safe because: either the
|
||||||
|
// value is stored inline and is therefore by convention bitwise takable
|
||||||
auto layout = getLayout();
|
// or the value is stored in a reference counted heap buffer, in which
|
||||||
|
// case a memcpy of the reference is also correct.
|
||||||
// Project down to the buffers and ask the witnesses to do a
|
IGF.emitMemCpy(dest, src, getLayout().getSize(IGF.IGM));
|
||||||
// take-initialize.
|
|
||||||
Address srcBuffer = layout.projectExistentialBuffer(IGF, src);
|
|
||||||
Address destBuffer = layout.projectExistentialBuffer(IGF, dest);
|
|
||||||
emitInitializeBufferWithTakeOfBufferCall(IGF, metadata, destBuffer,
|
|
||||||
srcBuffer);
|
|
||||||
} else {
|
} else {
|
||||||
// Create an outlined function to avoid explosion
|
// Create an outlined function to avoid explosion
|
||||||
OutliningMetadataCollector collector(IGF);
|
OutliningMetadataCollector collector(IGF);
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ static llvm::Type *createWitnessType(IRGenModule &IGM, ValueWitness index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self);
|
// T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self);
|
||||||
// T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self);
|
case ValueWitness::InitializeBufferWithCopyOfBuffer: {
|
||||||
case ValueWitness::InitializeBufferWithCopyOfBuffer:
|
|
||||||
case ValueWitness::InitializeBufferWithTakeOfBuffer: {
|
|
||||||
llvm::Type *bufPtrTy = IGM.getFixedBufferTy()->getPointerTo(0);
|
llvm::Type *bufPtrTy = IGM.getFixedBufferTy()->getPointerTo(0);
|
||||||
llvm::Type *args[] = { bufPtrTy, bufPtrTy, IGM.TypeMetadataPtrTy };
|
llvm::Type *args[] = { bufPtrTy, bufPtrTy, IGM.TypeMetadataPtrTy };
|
||||||
return llvm::FunctionType::get(IGM.OpaquePtrTy, args, /*isVarArg*/ false);
|
return llvm::FunctionType::get(IGM.OpaquePtrTy, args, /*isVarArg*/ false);
|
||||||
@@ -212,7 +210,6 @@ static llvm::AttributeList getValueWitnessAttrs(IRGenModule &IGM,
|
|||||||
// These have two arguments and they don't alias each other.
|
// These have two arguments and they don't alias each other.
|
||||||
case ValueWitness::AssignWithTake:
|
case ValueWitness::AssignWithTake:
|
||||||
case ValueWitness::InitializeBufferWithCopyOfBuffer:
|
case ValueWitness::InitializeBufferWithCopyOfBuffer:
|
||||||
case ValueWitness::InitializeBufferWithTakeOfBuffer:
|
|
||||||
case ValueWitness::InitializeWithCopy:
|
case ValueWitness::InitializeWithCopy:
|
||||||
case ValueWitness::InitializeWithTake:
|
case ValueWitness::InitializeWithTake:
|
||||||
return attrs.addAttribute(ctx, 1, llvm::Attribute::NoAlias)
|
return attrs.addAttribute(ctx, 1, llvm::Attribute::NoAlias)
|
||||||
@@ -259,8 +256,6 @@ static StringRef getValueWitnessLabel(ValueWitness index) {
|
|||||||
return "initializeWithCopy";
|
return "initializeWithCopy";
|
||||||
case ValueWitness::InitializeWithTake:
|
case ValueWitness::InitializeWithTake:
|
||||||
return "initializeWithTake";
|
return "initializeWithTake";
|
||||||
case ValueWitness::InitializeBufferWithTakeOfBuffer:
|
|
||||||
return "initializeBufferWithTakeOfBuffer";
|
|
||||||
case ValueWitness::Size:
|
case ValueWitness::Size:
|
||||||
return "size";
|
return "size";
|
||||||
case ValueWitness::Flags:
|
case ValueWitness::Flags:
|
||||||
@@ -417,31 +412,6 @@ irgen::emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF,
|
|||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *
|
|
||||||
irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
|
|
||||||
SILType T,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer) {
|
|
||||||
auto metadata = IGF.emitTypeMetadataRefForLayout(T);
|
|
||||||
return emitInitializeBufferWithTakeOfBufferCall(IGF, metadata,
|
|
||||||
destBuffer, srcBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
|
|
||||||
llvm::Value *
|
|
||||||
irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
|
|
||||||
llvm::Value *metadata,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer) {
|
|
||||||
auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
|
|
||||||
ValueWitness::InitializeBufferWithTakeOfBuffer);
|
|
||||||
llvm::CallInst *call =
|
|
||||||
IGF.Builder.CreateCall(copyFn,
|
|
||||||
{destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
|
|
||||||
|
|
||||||
return call;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit a dynamic alloca call to allocate enough memory to hold an object of
|
/// Emit a dynamic alloca call to allocate enough memory to hold an object of
|
||||||
/// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
|
/// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
|
||||||
/// false.
|
/// false.
|
||||||
|
|||||||
@@ -58,18 +58,6 @@ namespace irgen {
|
|||||||
Address destBuffer,
|
Address destBuffer,
|
||||||
Address srcBuffer);
|
Address srcBuffer);
|
||||||
|
|
||||||
/// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
|
|
||||||
llvm::Value *emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
|
|
||||||
llvm::Value *metadata,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer);
|
|
||||||
|
|
||||||
/// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
|
|
||||||
llvm::Value *emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
|
|
||||||
SILType T,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer);
|
|
||||||
|
|
||||||
/// Emit a call to do an 'initializeWithCopy' operation.
|
/// Emit a call to do an 'initializeWithCopy' operation.
|
||||||
void emitInitializeWithCopyCall(IRGenFunction &IGF,
|
void emitInitializeWithCopyCall(IRGenFunction &IGF,
|
||||||
SILType T,
|
SILType T,
|
||||||
|
|||||||
@@ -323,22 +323,6 @@ protected:
|
|||||||
public:
|
public:
|
||||||
using super::getStorageType;
|
using super::getStorageType;
|
||||||
|
|
||||||
Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer,
|
|
||||||
SILType type) const override {
|
|
||||||
if (auto field = getUniqueNonEmptyField()) {
|
|
||||||
auto &fieldTI = field->getTypeInfo();
|
|
||||||
Address fieldResult =
|
|
||||||
fieldTI.initializeBufferWithTakeOfBuffer(IGF, destBuffer, srcBuffer,
|
|
||||||
field->getType(IGF.IGM, type));
|
|
||||||
return IGF.Builder.CreateElementBitCast(fieldResult, getStorageType());
|
|
||||||
} else {
|
|
||||||
return super::initializeBufferWithTakeOfBuffer(IGF, destBuffer,
|
|
||||||
srcBuffer, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Address initializeBufferWithCopyOfBuffer(IRGenFunction &IGF,
|
Address initializeBufferWithCopyOfBuffer(IRGenFunction &IGF,
|
||||||
Address destBuffer,
|
Address destBuffer,
|
||||||
Address srcBuffer,
|
Address srcBuffer,
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ const char *irgen::getValueWitnessName(ValueWitness witness) {
|
|||||||
CASE(InitializeBufferWithCopyOfBuffer)
|
CASE(InitializeBufferWithCopyOfBuffer)
|
||||||
CASE(InitializeWithCopy)
|
CASE(InitializeWithCopy)
|
||||||
CASE(InitializeWithTake)
|
CASE(InitializeWithTake)
|
||||||
CASE(InitializeBufferWithTakeOfBuffer)
|
|
||||||
CASE(StoreExtraInhabitant)
|
CASE(StoreExtraInhabitant)
|
||||||
CASE(GetExtraInhabitantIndex)
|
CASE(GetExtraInhabitantIndex)
|
||||||
CASE(GetEnumTag)
|
CASE(GetEnumTag)
|
||||||
@@ -331,47 +330,6 @@ static Address emitDefaultInitializeBufferWithCopyOfBuffer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit an 'initializeBufferWithTakeOfBuffer' operation.
|
|
||||||
/// Returns the address of the destination object.
|
|
||||||
static Address
|
|
||||||
emitDefaultInitializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer,
|
|
||||||
SILType T,
|
|
||||||
const TypeInfo &type,
|
|
||||||
FixedPacking packing) {
|
|
||||||
switch (packing) {
|
|
||||||
|
|
||||||
case FixedPacking::Dynamic:
|
|
||||||
// Special-case dynamic packing in order to thread the jumps.
|
|
||||||
return emitForDynamicPacking(IGF,
|
|
||||||
&emitDefaultInitializeBufferWithTakeOfBuffer,
|
|
||||||
T, type, destBuffer, srcBuffer);
|
|
||||||
|
|
||||||
case FixedPacking::OffsetZero: {
|
|
||||||
// Both of these allocations/projections should be no-ops.
|
|
||||||
Address destObject =
|
|
||||||
emitDefaultAllocateBuffer(IGF, destBuffer, T, type, packing);
|
|
||||||
Address srcObject =
|
|
||||||
emitDefaultProjectBuffer(IGF, srcBuffer, T, type, packing);
|
|
||||||
type.initializeWithTake(IGF, destObject, srcObject, T, true);
|
|
||||||
return destObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
case FixedPacking::Allocate: {
|
|
||||||
// Just copy the out-of-line storage pointers.
|
|
||||||
srcBuffer = IGF.Builder.CreateBitCast(
|
|
||||||
srcBuffer, IGF.IGM.RefCountedPtrTy->getPointerTo());
|
|
||||||
llvm::Value *addr = IGF.Builder.CreateLoad(srcBuffer);
|
|
||||||
destBuffer = IGF.Builder.CreateBitCast(
|
|
||||||
destBuffer, IGF.IGM.RefCountedPtrTy->getPointerTo());
|
|
||||||
IGF.Builder.CreateStore(addr, destBuffer);
|
|
||||||
return emitDefaultProjectBuffer(IGF, destBuffer, T, type, packing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
llvm_unreachable("bad fixed packing");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Metaprogram some of the common boilerplate here:
|
// Metaprogram some of the common boilerplate here:
|
||||||
// - the default implementation in TypeInfo
|
// - the default implementation in TypeInfo
|
||||||
// - the value-witness emitter which tries to avoid some dynamic
|
// - the value-witness emitter which tries to avoid some dynamic
|
||||||
@@ -392,8 +350,6 @@ static Address emit##TITLE(IRGenFunction &IGF, Address dest, Address src, \
|
|||||||
}
|
}
|
||||||
DEFINE_BINARY_BUFFER_OP(initializeBufferWithCopyOfBuffer,
|
DEFINE_BINARY_BUFFER_OP(initializeBufferWithCopyOfBuffer,
|
||||||
InitializeBufferWithCopyOfBuffer)
|
InitializeBufferWithCopyOfBuffer)
|
||||||
DEFINE_BINARY_BUFFER_OP(initializeBufferWithTakeOfBuffer,
|
|
||||||
InitializeBufferWithTakeOfBuffer)
|
|
||||||
#undef DEFINE_BINARY_BUFFER_OP
|
#undef DEFINE_BINARY_BUFFER_OP
|
||||||
|
|
||||||
|
|
||||||
@@ -532,19 +488,6 @@ static void buildValueWitnessFunction(IRGenModule &IGM,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ValueWitness::InitializeBufferWithTakeOfBuffer: {
|
|
||||||
Address dest = getArgAsBuffer(IGF, argv, "dest");
|
|
||||||
Address src = getArgAsBuffer(IGF, argv, "src");
|
|
||||||
getArgAsLocalSelfTypeMetadata(IGF, argv, abstractType);
|
|
||||||
|
|
||||||
Address result =
|
|
||||||
emitInitializeBufferWithTakeOfBuffer(IGF, dest, src, concreteType,
|
|
||||||
type, packing);
|
|
||||||
result = IGF.Builder.CreateBitCast(result, IGF.IGM.OpaquePtrTy);
|
|
||||||
IGF.Builder.CreateRet(result.getAddress());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ValueWitness::InitializeWithCopy: {
|
case ValueWitness::InitializeWithCopy: {
|
||||||
Address dest = getArgAs(IGF, argv, type, "dest");
|
Address dest = getArgAs(IGF, argv, type, "dest");
|
||||||
Address src = getArgAs(IGF, argv, type, "src");
|
Address src = getArgAs(IGF, argv, type, "src");
|
||||||
@@ -805,38 +748,6 @@ static llvm::Constant *getMemCpyFunction(IRGenModule &IGM,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a function which takes two buffer arguments, copies
|
|
||||||
/// a pointer from the second to the first, and returns the pointer.
|
|
||||||
static llvm::Constant *
|
|
||||||
getCopyOutOfLineBoxPointerFunction(IRGenModule &IGM,
|
|
||||||
const FixedTypeInfo &fixedTI) {
|
|
||||||
llvm::Type *argTys[] = { IGM.Int8PtrPtrTy, IGM.Int8PtrPtrTy,
|
|
||||||
IGM.TypeMetadataPtrTy };
|
|
||||||
llvm::SmallString<40> name;
|
|
||||||
{
|
|
||||||
llvm::raw_svector_ostream nameStream(name);
|
|
||||||
nameStream << "__swift_copy_outline_existential_box_pointer";
|
|
||||||
nameStream << fixedTI.getFixedAlignment().getValue();
|
|
||||||
}
|
|
||||||
return IGM.getOrCreateHelperFunction(
|
|
||||||
name, IGM.Int8PtrTy, argTys, [&](IRGenFunction &IGF) {
|
|
||||||
auto it = IGF.CurFn->arg_begin();
|
|
||||||
Address dest(&*it++, IGM.getPointerAlignment());
|
|
||||||
Address src(&*it++, IGM.getPointerAlignment());
|
|
||||||
auto *ptr = IGF.Builder.CreateLoad(src);
|
|
||||||
IGF.Builder.CreateStore(ptr, dest);
|
|
||||||
auto *alignmentMask = fixedTI.getStaticAlignmentMask(IGM);
|
|
||||||
auto *heapHeaderSize = llvm::ConstantInt::get(
|
|
||||||
IGM.SizeTy, IGM.RefCountedStructSize.getValue());
|
|
||||||
auto *startOffset = IGF.Builder.CreateAnd(
|
|
||||||
IGF.Builder.CreateAdd(heapHeaderSize, alignmentMask),
|
|
||||||
IGF.Builder.CreateNot(alignmentMask));
|
|
||||||
auto *objectAddr =
|
|
||||||
IGF.emitByteOffsetGEP(ptr, startOffset, IGM.Int8Ty);
|
|
||||||
IGF.Builder.CreateRet(objectAddr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find a witness to the fact that a type is a value type.
|
/// Find a witness to the fact that a type is a value type.
|
||||||
/// Always adds an i8*.
|
/// Always adds an i8*.
|
||||||
static void addValueWitness(IRGenModule &IGM,
|
static void addValueWitness(IRGenModule &IGM,
|
||||||
@@ -870,17 +781,6 @@ static void addValueWitness(IRGenModule &IGM,
|
|||||||
}
|
}
|
||||||
goto standard;
|
goto standard;
|
||||||
|
|
||||||
case ValueWitness::InitializeBufferWithTakeOfBuffer:
|
|
||||||
if (packing == FixedPacking::Allocate) {
|
|
||||||
return addFunction(getCopyOutOfLineBoxPointerFunction(
|
|
||||||
IGM, cast<FixedTypeInfo>(concreteTI)));
|
|
||||||
} else
|
|
||||||
if (packing == FixedPacking::OffsetZero &&
|
|
||||||
concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
|
|
||||||
return addFunction(getMemCpyFunction(IGM, concreteTI));
|
|
||||||
}
|
|
||||||
goto standard;
|
|
||||||
|
|
||||||
case ValueWitness::InitializeWithTake:
|
case ValueWitness::InitializeWithTake:
|
||||||
if (concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
|
if (concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
|
||||||
return addFunction(getMemCpyFunction(IGM, concreteTI));
|
return addFunction(getMemCpyFunction(IGM, concreteTI));
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ std::string IRGenMangler::mangleValueWitness(Type type, ValueWitness witness) {
|
|||||||
GET_MANGLING(AssignWithCopy) \
|
GET_MANGLING(AssignWithCopy) \
|
||||||
GET_MANGLING(InitializeWithTake) \
|
GET_MANGLING(InitializeWithTake) \
|
||||||
GET_MANGLING(AssignWithTake) \
|
GET_MANGLING(AssignWithTake) \
|
||||||
GET_MANGLING(InitializeBufferWithTakeOfBuffer) \
|
|
||||||
GET_MANGLING(GetEnumTagSinglePayload) \
|
GET_MANGLING(GetEnumTagSinglePayload) \
|
||||||
GET_MANGLING(StoreEnumTagSinglePayload) \
|
GET_MANGLING(StoreEnumTagSinglePayload) \
|
||||||
GET_MANGLING(StoreExtraInhabitant) \
|
GET_MANGLING(StoreExtraInhabitant) \
|
||||||
|
|||||||
@@ -88,13 +88,6 @@ public:
|
|||||||
return this->getAddressForPointer(addr);
|
return this->getAddressForPointer(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
|
|
||||||
Address dest, Address src,
|
|
||||||
SILType T) const override {
|
|
||||||
auto addr = emitInitializeBufferWithTakeOfBufferCall(IGF, T, dest, src);
|
|
||||||
return this->getAddressForPointer(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
|
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
|
||||||
SILType T, bool isOutlined) const override {
|
SILType T, bool isOutlined) const override {
|
||||||
emitInitializeWithCopyCall(IGF, T, dest, src);
|
emitInitializeWithCopyCall(IGF, T, dest, src);
|
||||||
|
|||||||
@@ -370,23 +370,6 @@ public:
|
|||||||
Address srcBuffer,
|
Address srcBuffer,
|
||||||
SILType T) const;
|
SILType T) const;
|
||||||
|
|
||||||
/// Perform a take-initialization from the given fixed-size buffer
|
|
||||||
/// into an uninitialized fixed-size buffer, allocating the buffer if
|
|
||||||
/// necessary and deallocating the destination buffer. Returns the
|
|
||||||
/// address of the value inside the destination buffer.
|
|
||||||
///
|
|
||||||
/// This is equivalent to:
|
|
||||||
/// auto srcAddress = projectBuffer(IGF, srcBuffer, T);
|
|
||||||
/// initializeBufferWithTake(IGF, destBuffer, srcAddress, T);
|
|
||||||
/// deallocateBuffer(IGF, srcBuffer, T);
|
|
||||||
/// but may be able to re-use the buffer from the source buffer, and may
|
|
||||||
/// be more efficient for dynamic types, since it uses a single
|
|
||||||
/// value witness call.
|
|
||||||
virtual Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
|
|
||||||
Address destBuffer,
|
|
||||||
Address srcBuffer,
|
|
||||||
SILType T) const;
|
|
||||||
|
|
||||||
/// Take-initialize an address from a parameter explosion.
|
/// Take-initialize an address from a parameter explosion.
|
||||||
virtual void initializeFromParams(IRGenFunction &IGF, Explosion ¶ms,
|
virtual void initializeFromParams(IRGenFunction &IGF, Explosion ¶ms,
|
||||||
Address src, SILType T,
|
Address src, SILType T,
|
||||||
|
|||||||
@@ -107,20 +107,9 @@ struct LLVM_LIBRARY_VISIBILITY OpaqueExistentialBoxBase
|
|||||||
static Container *initializeWithTake(Container *dest, Container *src,
|
static Container *initializeWithTake(Container *dest, Container *src,
|
||||||
A... args) {
|
A... args) {
|
||||||
src->copyTypeInto(dest, args...);
|
src->copyTypeInto(dest, args...);
|
||||||
auto *type = src->getType();
|
auto from = src->getBuffer(args...);
|
||||||
auto *vwt = type->getValueWitnesses();
|
auto to = dest->getBuffer(args...);
|
||||||
|
memcpy(to, from, sizeof(ValueBuffer));
|
||||||
if (vwt->isValueInline()) {
|
|
||||||
auto *destValue =
|
|
||||||
reinterpret_cast<OpaqueValue *>(dest->getBuffer(args...));
|
|
||||||
auto *srcValue =
|
|
||||||
reinterpret_cast<OpaqueValue *>(src->getBuffer(args...));
|
|
||||||
|
|
||||||
type->vw_initializeWithTake(destValue, srcValue);
|
|
||||||
} else {
|
|
||||||
// initWithTake of the reference to the cow box.
|
|
||||||
copyReference(dest, src, Dest::Init, Source::Take, args...);
|
|
||||||
}
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1057,23 +1057,6 @@ static OpaqueValue *tuple_initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
|||||||
return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
|
return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic tuple value witness for 'initializeBufferWithTakeOfBuffer'.
|
|
||||||
template <bool IsPOD, bool IsInline>
|
|
||||||
static OpaqueValue *tuple_initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
|
|
||||||
ValueBuffer *src,
|
|
||||||
const Metadata *metatype) {
|
|
||||||
assert(IsPOD == tuple_getValueWitnesses(metatype)->isPOD());
|
|
||||||
assert(IsInline == tuple_getValueWitnesses(metatype)->isValueInline());
|
|
||||||
if (IsInline) {
|
|
||||||
return tuple_initializeWithTake<IsPOD, IsInline>(
|
|
||||||
tuple_projectBuffer<IsPOD, IsInline>(dest, metatype),
|
|
||||||
tuple_projectBuffer<IsPOD, IsInline>(src, metatype), metatype);
|
|
||||||
}
|
|
||||||
auto *srcReference = *reinterpret_cast<HeapObject**>(src);
|
|
||||||
*reinterpret_cast<HeapObject**>(dest) = srcReference;
|
|
||||||
return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool IsPOD, bool IsInline>
|
template <bool IsPOD, bool IsInline>
|
||||||
static unsigned tuple_getEnumTagSinglePayload(const OpaqueValue *enumAddr,
|
static unsigned tuple_getEnumTagSinglePayload(const OpaqueValue *enumAddr,
|
||||||
unsigned numEmptyCases,
|
unsigned numEmptyCases,
|
||||||
@@ -1560,20 +1543,6 @@ static OpaqueValue *pod_indirect_initializeBufferWithCopyOfBuffer(
|
|||||||
return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
|
return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static OpaqueValue *pod_indirect_initializeBufferWithTakeOfBuffer(
|
|
||||||
ValueBuffer *dest, ValueBuffer *src, const Metadata *self) {
|
|
||||||
auto wtable = self->getValueWitnesses();
|
|
||||||
auto *srcReference = *reinterpret_cast<HeapObject**>(src);
|
|
||||||
*reinterpret_cast<HeapObject**>(dest) = srcReference;
|
|
||||||
|
|
||||||
// Project the address of the value in the buffer.
|
|
||||||
unsigned alignMask = wtable->getAlignmentMask();
|
|
||||||
// Compute the byte offset of the object in the box.
|
|
||||||
unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
|
|
||||||
auto *bytePtr = reinterpret_cast<char *>(srcReference);
|
|
||||||
return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pod_noop(void *object, const Metadata *self) {
|
static void pod_noop(void *object, const Metadata *self) {
|
||||||
}
|
}
|
||||||
#define pod_direct_destroy \
|
#define pod_direct_destroy \
|
||||||
@@ -1590,9 +1559,6 @@ static OpaqueValue *pod_direct_initializeWithCopy(OpaqueValue *dest,
|
|||||||
#define pod_direct_initializeBufferWithCopyOfBuffer \
|
#define pod_direct_initializeBufferWithCopyOfBuffer \
|
||||||
pointer_function_cast<value_witness_types::initializeBufferWithCopyOfBuffer> \
|
pointer_function_cast<value_witness_types::initializeBufferWithCopyOfBuffer> \
|
||||||
(pod_direct_initializeWithCopy)
|
(pod_direct_initializeWithCopy)
|
||||||
#define pod_direct_initializeBufferWithTakeOfBuffer \
|
|
||||||
pointer_function_cast<value_witness_types::initializeBufferWithTakeOfBuffer> \
|
|
||||||
(pod_direct_initializeWithCopy)
|
|
||||||
#define pod_direct_assignWithCopy pod_direct_initializeWithCopy
|
#define pod_direct_assignWithCopy pod_direct_initializeWithCopy
|
||||||
#define pod_indirect_assignWithCopy pod_direct_initializeWithCopy
|
#define pod_indirect_assignWithCopy pod_direct_initializeWithCopy
|
||||||
#define pod_direct_initializeWithTake pod_direct_initializeWithCopy
|
#define pod_direct_initializeWithTake pod_direct_initializeWithCopy
|
||||||
@@ -1705,23 +1671,12 @@ void swift::installCommonValueWitnesses(const TypeLayout &layout,
|
|||||||
// Use POD value witnesses for operations that do an initializeWithTake.
|
// Use POD value witnesses for operations that do an initializeWithTake.
|
||||||
if (flags.isInlineStorage()) {
|
if (flags.isInlineStorage()) {
|
||||||
vwtable->initializeWithTake = pod_direct_initializeWithTake;
|
vwtable->initializeWithTake = pod_direct_initializeWithTake;
|
||||||
vwtable->initializeBufferWithTakeOfBuffer
|
|
||||||
= pod_direct_initializeBufferWithTakeOfBuffer;
|
|
||||||
} else {
|
} else {
|
||||||
vwtable->initializeWithTake = pod_indirect_initializeWithTake;
|
vwtable->initializeWithTake = pod_indirect_initializeWithTake;
|
||||||
vwtable->initializeBufferWithTakeOfBuffer
|
|
||||||
= pod_indirect_initializeBufferWithTakeOfBuffer;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flags.isInlineStorage()) {
|
|
||||||
// For values stored out-of-line, initializeBufferWithTakeOfBuffer is
|
|
||||||
// always a memcpy.
|
|
||||||
vwtable->initializeBufferWithTakeOfBuffer
|
|
||||||
= pod_indirect_initializeBufferWithTakeOfBuffer;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|||||||
@@ -642,13 +642,6 @@ struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
|
|||||||
: BufferValueWitnessesBase<Impl> {
|
: BufferValueWitnessesBase<Impl> {
|
||||||
static constexpr bool isInline = true;
|
static constexpr bool isInline = true;
|
||||||
|
|
||||||
static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
|
|
||||||
ValueBuffer *src,
|
|
||||||
const Metadata *self) {
|
|
||||||
return Impl::initializeWithTake(reinterpret_cast<OpaqueValue*>(dest),
|
|
||||||
reinterpret_cast<OpaqueValue*>(src),
|
|
||||||
self);
|
|
||||||
}
|
|
||||||
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
||||||
ValueBuffer *src,
|
ValueBuffer *src,
|
||||||
const Metadata *self) {
|
const Metadata *self) {
|
||||||
@@ -665,21 +658,6 @@ struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
|
|||||||
: BufferValueWitnessesBase<Impl> {
|
: BufferValueWitnessesBase<Impl> {
|
||||||
static constexpr bool isInline = false;
|
static constexpr bool isInline = false;
|
||||||
|
|
||||||
static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
|
|
||||||
ValueBuffer *src,
|
|
||||||
const Metadata *self) {
|
|
||||||
auto wtable = self->getValueWitnesses();
|
|
||||||
auto *srcReference = *reinterpret_cast<HeapObject **>(src);
|
|
||||||
*reinterpret_cast<HeapObject **>(dest) = srcReference;
|
|
||||||
|
|
||||||
// Project the address of the value in the buffer.
|
|
||||||
unsigned alignMask = wtable->getAlignmentMask();
|
|
||||||
// Compute the byte offset of the object in the box.
|
|
||||||
unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
|
|
||||||
auto *bytePtr = reinterpret_cast<char *>(srcReference);
|
|
||||||
return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
||||||
ValueBuffer *src,
|
ValueBuffer *src,
|
||||||
const Metadata *self) {
|
const Metadata *self) {
|
||||||
@@ -700,26 +678,6 @@ struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
|
|||||||
/// fixed in size.
|
/// fixed in size.
|
||||||
template <class Impl, bool IsKnownAllocated>
|
template <class Impl, bool IsKnownAllocated>
|
||||||
struct NonFixedBufferValueWitnesses : BufferValueWitnessesBase<Impl> {
|
struct NonFixedBufferValueWitnesses : BufferValueWitnessesBase<Impl> {
|
||||||
static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
|
|
||||||
ValueBuffer *src,
|
|
||||||
const Metadata *self) {
|
|
||||||
auto vwtable = self->getValueWitnesses();
|
|
||||||
(void)vwtable;
|
|
||||||
if (!IsKnownAllocated && vwtable->isValueInline()) {
|
|
||||||
return Impl::initializeWithTake(reinterpret_cast<OpaqueValue *>(dest),
|
|
||||||
reinterpret_cast<OpaqueValue *>(src),
|
|
||||||
self);
|
|
||||||
} else {
|
|
||||||
auto reference = src->PrivateData[0];
|
|
||||||
dest->PrivateData[0] = reference;
|
|
||||||
// Project the address of the value in the buffer.
|
|
||||||
unsigned alignMask = vwtable->getAlignmentMask();
|
|
||||||
// Compute the byte offset of the object in the box.
|
|
||||||
unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
|
|
||||||
auto *bytePtr = reinterpret_cast<char *>(reference);
|
|
||||||
return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
|
||||||
ValueBuffer *src,
|
ValueBuffer *src,
|
||||||
|
|||||||
@@ -225,12 +225,12 @@ func sizeof_alignof_test() {
|
|||||||
|
|
||||||
// CHECK: define hidden {{.*}}void @"$S8builtins27generic_sizeof_alignof_testyyxlF"
|
// CHECK: define hidden {{.*}}void @"$S8builtins27generic_sizeof_alignof_testyyxlF"
|
||||||
func generic_sizeof_alignof_test<T>(_: T) {
|
func generic_sizeof_alignof_test<T>(_: T) {
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 8
|
||||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
||||||
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to i64
|
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to i64
|
||||||
// CHECK-NEXT: store i64 [[SIZE]], i64* [[S:%.*]]
|
// CHECK-NEXT: store i64 [[SIZE]], i64* [[S:%.*]]
|
||||||
var s = Builtin.sizeof(T.self)
|
var s = Builtin.sizeof(T.self)
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
|
||||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
||||||
// CHECK-NEXT: [[T2:%.*]] = ptrtoint i8* [[T1]] to i64
|
// CHECK-NEXT: [[T2:%.*]] = ptrtoint i8* [[T1]] to i64
|
||||||
// CHECK-NEXT: [[T3:%.*]] = and i64 [[T2]], 65535
|
// CHECK-NEXT: [[T3:%.*]] = and i64 [[T2]], 65535
|
||||||
@@ -241,7 +241,7 @@ func generic_sizeof_alignof_test<T>(_: T) {
|
|||||||
|
|
||||||
// CHECK: define hidden {{.*}}void @"$S8builtins21generic_strideof_testyyxlF"
|
// CHECK: define hidden {{.*}}void @"$S8builtins21generic_strideof_testyyxlF"
|
||||||
func generic_strideof_test<T>(_: T) {
|
func generic_strideof_test<T>(_: T) {
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 11
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
|
||||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
||||||
// CHECK-NEXT: [[STRIDE:%.*]] = ptrtoint i8* [[T1]] to i64
|
// CHECK-NEXT: [[STRIDE:%.*]] = ptrtoint i8* [[T1]] to i64
|
||||||
// CHECK-NEXT: store i64 [[STRIDE]], i64* [[S:%.*]]
|
// CHECK-NEXT: store i64 [[STRIDE]], i64* [[S:%.*]]
|
||||||
@@ -771,7 +771,7 @@ func isUniqueIUO(_ ref: inout Builtin.NativeObject?) -> Bool {
|
|||||||
|
|
||||||
// CHECK-LABEL: define {{.*}} @{{.*}}generic_ispod_test
|
// CHECK-LABEL: define {{.*}} @{{.*}}generic_ispod_test
|
||||||
func generic_ispod_test<T>(_: T) {
|
func generic_ispod_test<T>(_: T) {
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
|
||||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
|
||||||
// CHECK-NEXT: [[FLAGS:%.*]] = ptrtoint i8* [[T1]] to i64
|
// CHECK-NEXT: [[FLAGS:%.*]] = ptrtoint i8* [[T1]] to i64
|
||||||
// CHECK-NEXT: [[ISNOTPOD:%.*]] = and i64 [[FLAGS]], 65536
|
// CHECK-NEXT: [[ISNOTPOD:%.*]] = and i64 [[FLAGS]], 65536
|
||||||
|
|||||||
@@ -127,11 +127,11 @@ import Swift
|
|||||||
|
|
||||||
// CHECK: @"$S4enum16DynamicSingletonOMP" = internal constant <{ {{.*}} }> <{
|
// CHECK: @"$S4enum16DynamicSingletonOMP" = internal constant <{ {{.*}} }> <{
|
||||||
// CHECK-SAME: @"$S4enum16DynamicSingletonOMi"
|
// CHECK-SAME: @"$S4enum16DynamicSingletonOMi"
|
||||||
// CHECK-SAME: [18 x i8*]* @"$S4enum16DynamicSingletonOWV"
|
// CHECK-SAME: [17 x i8*]* @"$S4enum16DynamicSingletonOWV"
|
||||||
|
|
||||||
// -- No-payload enums have extra inhabitants in
|
// -- No-payload enums have extra inhabitants in
|
||||||
// their value witness table.
|
// their value witness table.
|
||||||
// CHECK: @"$S4enum10NoPayloadsOWV" = internal constant [18 x i8*] [
|
// CHECK: @"$S4enum10NoPayloadsOWV" = internal constant [17 x i8*] [
|
||||||
// -- ...
|
// -- ...
|
||||||
// -- size
|
// -- size
|
||||||
// CHECK-SAME: i8* inttoptr ([[WORD:i32|i64]] 1 to i8*),
|
// CHECK-SAME: i8* inttoptr ([[WORD:i32|i64]] 1 to i8*),
|
||||||
@@ -149,7 +149,7 @@ import Swift
|
|||||||
|
|
||||||
// -- Single-payload enums take unused extra inhabitants from their payload
|
// -- Single-payload enums take unused extra inhabitants from their payload
|
||||||
// as their own.
|
// as their own.
|
||||||
// CHECK: @"$S4enum19SinglePayloadNestedOWV" = internal constant [18 x i8*] [
|
// CHECK: @"$S4enum19SinglePayloadNestedOWV" = internal constant [17 x i8*] [
|
||||||
// -- ...
|
// -- ...
|
||||||
// -- size
|
// -- size
|
||||||
// CHECK-SAME: i8* inttoptr ([[WORD]] 1 to i8*),
|
// CHECK-SAME: i8* inttoptr ([[WORD]] 1 to i8*),
|
||||||
@@ -165,16 +165,16 @@ import Swift
|
|||||||
// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum19SinglePayloadNestedOwxg" to i8*)
|
// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum19SinglePayloadNestedOwxg" to i8*)
|
||||||
// CHECK-SAME: ]
|
// CHECK-SAME: ]
|
||||||
|
|
||||||
// CHECK: @"$S4enum20DynamicSinglePayloadOWV" = internal constant [18 x i8*] [
|
// CHECK: @"$S4enum20DynamicSinglePayloadOWV" = internal constant [17 x i8*] [
|
||||||
// CHECK-SAME: i8* null
|
// CHECK-SAME: i8* null
|
||||||
// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxs" to i8*)
|
// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxs" to i8*)
|
||||||
// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxg" to i8*)
|
// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxg" to i8*)
|
||||||
|
|
||||||
// CHECK: @"$S4enum20DynamicSinglePayloadOMP" = internal constant <{ {{.*}} }> <{
|
// CHECK: @"$S4enum20DynamicSinglePayloadOMP" = internal constant <{ {{.*}} }> <{
|
||||||
// CHECK-SAME: @"$S4enum20DynamicSinglePayloadOMi"
|
// CHECK-SAME: @"$S4enum20DynamicSinglePayloadOMi"
|
||||||
// CHECK-SAME: [18 x i8*]* @"$S4enum20DynamicSinglePayloadOWV"
|
// CHECK-SAME: [17 x i8*]* @"$S4enum20DynamicSinglePayloadOWV"
|
||||||
|
|
||||||
// CHECK: @"$S4enum18MultiPayloadNestedOWV" = internal constant [18 x i8*] [
|
// CHECK: @"$S4enum18MultiPayloadNestedOWV" = internal constant [17 x i8*] [
|
||||||
// -- size
|
// -- size
|
||||||
// CHECK-32-SAME: i8* inttoptr ([[WORD]] 5 to i8*),
|
// CHECK-32-SAME: i8* inttoptr ([[WORD]] 5 to i8*),
|
||||||
// CHECK-64-SAME: i8* inttoptr ([[WORD]] 9 to i8*),
|
// CHECK-64-SAME: i8* inttoptr ([[WORD]] 9 to i8*),
|
||||||
@@ -1209,7 +1209,7 @@ enum DynamicSinglePayload<T> {
|
|||||||
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
|
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
|
||||||
// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
|
// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
|
||||||
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
|
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
|
||||||
// CHECK: %getEnumTagSinglePayload = bitcast i8* [[WITNESS]] to i32 (%swift.opaque*, i32, %swift.type*)*
|
// CHECK: %getEnumTagSinglePayload = bitcast i8* [[WITNESS]] to i32 (%swift.opaque*, i32, %swift.type*)*
|
||||||
// CHECK: [[CASE_INDEX:%.*]] = call i32 %getEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 3, %swift.type* %T)
|
// CHECK: [[CASE_INDEX:%.*]] = call i32 %getEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 3, %swift.type* %T)
|
||||||
@@ -1240,7 +1240,7 @@ end:
|
|||||||
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
|
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
|
||||||
// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
|
||||||
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
|
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
|
||||||
// CHECK: %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
|
// CHECK: %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
|
||||||
// CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 0, i32 3, %swift.type* %T)
|
// CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 0, i32 3, %swift.type* %T)
|
||||||
@@ -1256,7 +1256,7 @@ entry(%r : $*DynamicSinglePayload<T>, %t : $*T):
|
|||||||
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
|
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
|
||||||
// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
|
||||||
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
|
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
|
||||||
// CHECK: %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
|
// CHECK: %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
|
||||||
// CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 1, i32 3, %swift.type* %T)
|
// CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 1, i32 3, %swift.type* %T)
|
||||||
@@ -2640,7 +2640,7 @@ entry(%x : $*MyOptional):
|
|||||||
// CHECK: [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
// CHECK: [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
||||||
// CHECK: [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
|
// CHECK: [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
|
||||||
// CHECK: [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
|
// CHECK: [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
|
||||||
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
|
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
|
||||||
// CHECK: call void @swift_initEnumMetadataSingleCase(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]])
|
// CHECK: call void @swift_initEnumMetadataSingleCase(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]])
|
||||||
// CHECK: ret %swift.metadata_response
|
// CHECK: ret %swift.metadata_response
|
||||||
|
|
||||||
@@ -2659,7 +2659,7 @@ entry(%x : $*MyOptional):
|
|||||||
// CHECK: [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
// CHECK: [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
||||||
// CHECK: [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
|
// CHECK: [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
|
||||||
// CHECK: [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
|
// CHECK: [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
|
||||||
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
|
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
|
||||||
// CHECK: call void @swift_initEnumMetadataSinglePayload(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]], i32 3)
|
// CHECK: call void @swift_initEnumMetadataSinglePayload(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]], i32 3)
|
||||||
|
|
||||||
// CHECK-64-LABEL: define linkonce_odr hidden void @"$S4enum17StructWithWeakVarVwxs"(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
|
// CHECK-64-LABEL: define linkonce_odr hidden void @"$S4enum17StructWithWeakVarVwxs"(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
|
||||||
|
|||||||
@@ -433,7 +433,7 @@ entry(%a : $*EitherOr<T, C>, %b : $*EitherOr<T, C>):
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
|
||||||
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
||||||
// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
|
// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
|
||||||
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF0]]
|
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF0]]
|
||||||
|
|
||||||
// CHECK: [[BUF1:%.*]] = getelementptr {{.*}} [[BUF]], i32 0, i32 1
|
// CHECK: [[BUF1:%.*]] = getelementptr {{.*}} [[BUF]], i32 0, i32 1
|
||||||
@@ -445,7 +445,7 @@ entry(%a : $*EitherOr<T, C>, %b : $*EitherOr<T, C>):
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[U_CHECKED]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[U_CHECKED]] to i8***
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
|
||||||
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
||||||
// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
|
// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
|
||||||
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF1]]
|
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF1]]
|
||||||
|
|
||||||
// CHECK: call void @swift_initEnumMetadataMultiPayload(%swift.type* [[METADATA]], {{i(32|64)}} 0, {{i(32|64)}} 2, i8*** [[BUF0]])
|
// CHECK: call void @swift_initEnumMetadataMultiPayload(%swift.type* [[METADATA]], {{i(32|64)}} 0, {{i(32|64)}} 2, i8*** [[BUF0]])
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public func constructResilientEnumNoPayload() -> Medium {
|
|||||||
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
|
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
|
||||||
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
|
|
||||||
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 17
|
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 16
|
||||||
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
||||||
// CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
|
// CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
|
||||||
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA]])
|
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA]])
|
||||||
@@ -148,7 +148,7 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
|
|||||||
// CHECK-NEXT: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR2]], [[INT]] -1
|
// CHECK-NEXT: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR2]], [[INT]] -1
|
||||||
// CHECK-NEXT: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
|
// CHECK-NEXT: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
|
||||||
|
|
||||||
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 17
|
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 16
|
||||||
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
||||||
// CHECK-NEXT: [[WITNESS_FN:%destructiveInjectEnumTag]] = bitcast i8* [[WITNESS]]
|
// CHECK-NEXT: [[WITNESS_FN:%destructiveInjectEnumTag]] = bitcast i8* [[WITNESS]]
|
||||||
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA2]])
|
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA2]])
|
||||||
@@ -165,7 +165,7 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
|
|||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
|
|
||||||
// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
||||||
// CHECK: [[WITNESS_FOR_SIZE:%size]] = ptrtoint i8* [[WITNESS]]
|
// CHECK: [[WITNESS_FOR_SIZE:%size]] = ptrtoint i8* [[WITNESS]]
|
||||||
// CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
|
// CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
|
||||||
@@ -177,7 +177,7 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
|
|||||||
// CHECK: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]]
|
// CHECK: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]]
|
||||||
// CHECK: [[ENUM_COPY:%.*]] = call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.opaque* noalias %0, %swift.type* [[METADATA]])
|
// CHECK: [[ENUM_COPY:%.*]] = call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.opaque* noalias %0, %swift.type* [[METADATA]])
|
||||||
|
|
||||||
// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 15
|
// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 14
|
||||||
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
||||||
// CHECK: [[WITNESS_FN:%getEnumTag]] = bitcast i8* [[WITNESS]]
|
// CHECK: [[WITNESS_FN:%getEnumTag]] = bitcast i8* [[WITNESS]]
|
||||||
// CHECK: [[TAG:%.*]] = call i32 [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.type* [[METADATA]])
|
// CHECK: [[TAG:%.*]] = call i32 [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.type* [[METADATA]])
|
||||||
|
|||||||
@@ -94,14 +94,13 @@ enum GenericFixedLayout<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOWV" = internal constant [18 x i8*] [
|
// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOWV" = internal constant [17 x i8*] [
|
||||||
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
||||||
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
|
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
|
||||||
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
||||||
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
||||||
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
||||||
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
||||||
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
|
|
||||||
// CHECK: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwet" to i8*),
|
// CHECK: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwet" to i8*),
|
||||||
// CHECK: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwst" to i8*),
|
// CHECK: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwst" to i8*),
|
||||||
// CHECK: i8* inttoptr (i64 9 to i8*),
|
// CHECK: i8* inttoptr (i64 9 to i8*),
|
||||||
@@ -118,13 +117,13 @@ enum GenericFixedLayout<T> {
|
|||||||
|
|
||||||
// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOMf" =
|
// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOMf" =
|
||||||
// CHECK-SAME: internal constant <{ {{.*}} }> <{
|
// CHECK-SAME: internal constant <{ {{.*}} }> <{
|
||||||
// CHECK-SAME: i8** getelementptr inbounds ([18 x i8*], [18 x i8*]* @"$S20enum_value_semantics20SinglePayloadTrivialOWV", i32 0, i32 0),
|
// CHECK-SAME: i8** getelementptr inbounds ([17 x i8*], [17 x i8*]* @"$S20enum_value_semantics20SinglePayloadTrivialOWV", i32 0, i32 0),
|
||||||
// CHECK-SAME: i64 2,
|
// CHECK-SAME: i64 2,
|
||||||
// CHECK-SAME: {{.*}}* @"$S20enum_value_semantics20SinglePayloadTrivialOMn"
|
// CHECK-SAME: {{.*}}* @"$S20enum_value_semantics20SinglePayloadTrivialOMn"
|
||||||
// CHECK-SAME: }>
|
// CHECK-SAME: }>
|
||||||
|
|
||||||
|
|
||||||
// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOWV" = internal constant [18 x i8*] [
|
// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOWV" = internal constant [17 x i8*] [
|
||||||
// CHECK: i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwCP" to i8*),
|
// CHECK: i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwCP" to i8*),
|
||||||
// CHECK: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwxx" to i8*),
|
// CHECK: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwxx" to i8*),
|
||||||
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwcp" to i8*),
|
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwcp" to i8*),
|
||||||
@@ -148,7 +147,7 @@ enum GenericFixedLayout<T> {
|
|||||||
|
|
||||||
// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOMf" =
|
// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOMf" =
|
||||||
// CHECK-SAME: internal constant <{ {{.*}} }> <{
|
// CHECK-SAME: internal constant <{ {{.*}} }> <{
|
||||||
// CHECK-SAME: i8** getelementptr inbounds ([18 x i8*], [18 x i8*]* @"$S20enum_value_semantics23SinglePayloadNontrivialOWV", i32 0, i32 0),
|
// CHECK-SAME: i8** getelementptr inbounds ([17 x i8*], [17 x i8*]* @"$S20enum_value_semantics23SinglePayloadNontrivialOWV", i32 0, i32 0),
|
||||||
// CHECK-SAME: i64 2,
|
// CHECK-SAME: i64 2,
|
||||||
// CHECK-SAME: {{.*}}* @"$S20enum_value_semantics23SinglePayloadNontrivialOMn"
|
// CHECK-SAME: {{.*}}* @"$S20enum_value_semantics23SinglePayloadNontrivialOMn"
|
||||||
// CHECK-SAME: }>
|
// CHECK-SAME: }>
|
||||||
@@ -166,7 +165,7 @@ enum GenericFixedLayout<T> {
|
|||||||
// Pattern flags. 0x400000 == (MetadataKind::Enum << 21).
|
// Pattern flags. 0x400000 == (MetadataKind::Enum << 21).
|
||||||
// CHECK-SAME: i32 4194304,
|
// CHECK-SAME: i32 4194304,
|
||||||
// Value witness table.
|
// Value witness table.
|
||||||
// CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint ([18 x i8*]* @"$S20enum_value_semantics18GenericFixedLayoutOWV" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32 }>, <{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP", i32 0, i32 3) to i64)) to i32)
|
// CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint ([17 x i8*]* @"$S20enum_value_semantics18GenericFixedLayoutOWV" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32 }>, <{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP", i32 0, i32 3) to i64)) to i32)
|
||||||
// CHECK-SAME: }>
|
// CHECK-SAME: }>
|
||||||
|
|
||||||
sil @single_payload_nontrivial_copy_destroy : $(@owned SinglePayloadNontrivial) -> () {
|
sil @single_payload_nontrivial_copy_destroy : $(@owned SinglePayloadNontrivial) -> () {
|
||||||
|
|||||||
@@ -42,20 +42,11 @@ bb0(%0 : $*Any, %1 : $*Any):
|
|||||||
// CHECK: call %Any* @"$SypWOb"(%Any* %1, %Any* %0)
|
// CHECK: call %Any* @"$SypWOb"(%Any* %1, %Any* %0)
|
||||||
// CHECK-NEXT: ret void
|
// CHECK-NEXT: ret void
|
||||||
|
|
||||||
// CHECK-DAG: define linkonce_odr hidden %Any* @"$SypWOb"([[ANY:%Any]]*, %Any*)
|
// CHECK-DAG: define linkonce_odr hidden %Any* @"$SypWOb"(%Any*, %Any*)
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds [[ANY]], [[ANY]]* [[SRC:%0]], i32 0, i32 1
|
// CHECK: %2 = bitcast %Any* %1 to i8*
|
||||||
// CHECK-NEXT: [[TYPE:%.*]] = load %swift.type*, %swift.type** [[T0]], align 8
|
// CHECK-NEXT: %3 = bitcast %Any* %0 to i8*
|
||||||
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[ANY]], [[ANY]]* [[DEST:%1]], i32 0, i32 1
|
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 32, i32 8, i1 false)
|
||||||
// CHECK-NEXT: store %swift.type* [[TYPE]], %swift.type** [[T0]], align 8
|
// CHECK-NEXT: ret %Any* %1
|
||||||
// CHECK-NEXT: [[FROM_BUFFER_ADDR:%.*]] = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0
|
|
||||||
// CHECK-NEXT: [[TO_BUFFER_ADDR:%.*]] = getelementptr inbounds %Any, %Any* %1, i32 0, i32 0
|
|
||||||
// CHECK-NEXT: [[CAST:%.*]] = bitcast %swift.type* [[TYPE]] to i8***
|
|
||||||
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], i64 -1
|
|
||||||
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
|
||||||
// CHECK-NEXT: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
|
|
||||||
// CHECK-NEXT: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
|
||||||
// CHECK-NEXT: [[INITWITHTAKEBUFFER:%.*]] = bitcast i8* [[VW]]
|
|
||||||
// CHECK-NEXT: call %swift.opaque* [[INITWITHTAKEBUFFER]]({{.*}} [[TO_BUFFER_ADDR]], {{.*}} [[FROM_BUFFER_ADDR]], %swift.type* [[TYPE]])
|
|
||||||
|
|
||||||
// rdar://problem/19035529
|
// rdar://problem/19035529
|
||||||
@objc protocol OP {}
|
@objc protocol OP {}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ entry(%0 : $*T):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[METATYPE]]
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[METATYPE]]
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[FLAG_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
|
// CHECK: [[FLAG_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
||||||
// CHECK: [[FLAG_WITNESS:%.*]] = load i8*, i8** [[FLAG_WITNESS_ADDR]]
|
// CHECK: [[FLAG_WITNESS:%.*]] = load i8*, i8** [[FLAG_WITNESS_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAG_WITNESS]]
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAG_WITNESS]]
|
||||||
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
||||||
@@ -115,7 +115,7 @@ entry:
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** %3, {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** %3, {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
|
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
||||||
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
// CHECK: [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
||||||
@@ -132,7 +132,7 @@ entry:
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
|
||||||
// CHECK: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
|
// CHECK: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
|
||||||
// CHECK: [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 9
|
// CHECK: [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 8
|
||||||
// CHECK: [[VW2:%.*]] = load i8*, i8** [[VW_ADDR2]]
|
// CHECK: [[VW2:%.*]] = load i8*, i8** [[VW_ADDR2]]
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[VW2]] to {{(i64|i32)}}
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[VW2]] to {{(i64|i32)}}
|
||||||
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
|
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
|
||||||
@@ -164,7 +164,7 @@ bb0(%0 : $*Existential):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
|
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
||||||
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
||||||
@@ -207,7 +207,7 @@ bb0(%0 : $*Existential):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
|
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
||||||
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
||||||
@@ -244,7 +244,7 @@ bb0(%0 : $*Existential):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
|
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
||||||
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
||||||
@@ -301,7 +301,7 @@ bb0(%0 : $*Existential):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
|
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
||||||
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
// CHECK: [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
|
||||||
@@ -339,7 +339,7 @@ bb0(%0 : $*Existential):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
|
||||||
// CHECK: [[DEST_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[DEST_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[DEST_VWT:%.*]] = load i8**, i8*** [[DEST_VWT_ADDR]]
|
// CHECK: [[DEST_VWT:%.*]] = load i8**, i8*** [[DEST_VWT_ADDR]]
|
||||||
// CHECK: [[DEST_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[DEST_VWT]], i32 10
|
// CHECK: [[DEST_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[DEST_VWT]], i32 9
|
||||||
// CHECK: [[DEST_VW:%.*]] = load i8*, i8** [[DEST_VW_ADDR]]
|
// CHECK: [[DEST_VW:%.*]] = load i8*, i8** [[DEST_VW_ADDR]]
|
||||||
// CHECK: [[DEST_FLAGS:%.*]] = ptrtoint i8* [[DEST_VW]] to {{(i64|i32)}}
|
// CHECK: [[DEST_FLAGS:%.*]] = ptrtoint i8* [[DEST_VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[DEST_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[DEST_FLAGS]], 131072
|
// CHECK: [[DEST_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[DEST_FLAGS]], 131072
|
||||||
@@ -347,7 +347,7 @@ bb0(%0 : $*Existential):
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[SRC_TYPE]] to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[SRC_TYPE]] to i8***
|
||||||
// CHECK: [[SRC_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
// CHECK: [[SRC_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
|
||||||
// CHECK: [[SRC_VWT:%.*]] = load i8**, i8*** [[SRC_VWT_ADDR]]
|
// CHECK: [[SRC_VWT:%.*]] = load i8**, i8*** [[SRC_VWT_ADDR]]
|
||||||
// CHECK: [[SRC_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SRC_VWT]], i32 10
|
// CHECK: [[SRC_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SRC_VWT]], i32 9
|
||||||
// CHECK: [[SRC_VW:%.*]] = load i8*, i8** [[SRC_VW_ADDR]]
|
// CHECK: [[SRC_VW:%.*]] = load i8*, i8** [[SRC_VW_ADDR]]
|
||||||
// CHECK: [[SRC_FLAGS:%.*]] = ptrtoint i8* [[SRC_VW]] to {{(i64|i32)}}
|
// CHECK: [[SRC_FLAGS:%.*]] = ptrtoint i8* [[SRC_VW]] to {{(i64|i32)}}
|
||||||
// CHECK: [[SRC_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[SRC_FLAGS]], 131072
|
// CHECK: [[SRC_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[SRC_FLAGS]], 131072
|
||||||
@@ -443,24 +443,10 @@ bb0(%0 : $*Existential):
|
|||||||
return %t : $()
|
return %t : $()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: define linkonce_odr hidden %T25existentials_opaque_boxed11ExistentialP* @"$S25existentials_opaque_boxed11Existential_pWOb"(%T25existentials_opaque_boxed11ExistentialP*, %T25existentials_opaque_boxed11ExistentialP*)
|
// CHECK-LABEL: define linkonce_odr hidden %T25existentials_opaque_boxed11ExistentialP* @"$S25existentials_opaque_boxed11Existential_pWOb"(%T25existentials_opaque_boxed11ExistentialP*, %T25existentials_opaque_boxed11ExistentialP*)
|
||||||
// CHECK: [[METADATA_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 1
|
// CHECK: %2 = bitcast %T25existentials_opaque_boxed11ExistentialP* %1 to i8*
|
||||||
// CHECK: [[METADATA:%.*]] = load %swift.type*, %swift.type** [[METADATA_ADDR]]
|
// CHECK: %3 = bitcast %T25existentials_opaque_boxed11ExistentialP* %0 to i8*
|
||||||
// CHECK: [[LOCAL_METADATA_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 1
|
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 40, i32 8, i1 false)
|
||||||
// CHECK: store %swift.type* [[METADATA]], %swift.type** [[LOCAL_METADATA_ADDR]]
|
|
||||||
// CHECK: [[PWT_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 2
|
|
||||||
// CHECK: [[PWT:%.*]] = load i8**, i8*** [[PWT_ADDR]]
|
|
||||||
// CHECK: [[LOCAL_PWT_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 2
|
|
||||||
// CHECK: store i8** [[PWT]], i8*** [[LOCAL_PWT_ADDR]]
|
|
||||||
// CHECK: [[BUFFER_ARG_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 0
|
|
||||||
// CHECK: [[BUFFER_LOCAL_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 0
|
|
||||||
// CHECK: [[CAST_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST_ADDR]], {{(i64|i32)}} -1
|
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
|
||||||
// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
|
|
||||||
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
|
|
||||||
// CHECK: [[INITWITHTAKEBUFFER:%.*]] = bitcast i8* [[VW]]
|
|
||||||
// CHECK: call %swift.opaque* [[INITWITHTAKEBUFFER]]({{.*}} [[BUFFER_LOCAL_ADDR]], {{.*}} [[BUFFER_ARG_ADDR]], %swift.type* [[METADATA]])
|
|
||||||
// CHECK: ret %T25existentials_opaque_boxed11ExistentialP* %1
|
// CHECK: ret %T25existentials_opaque_boxed11ExistentialP* %1
|
||||||
|
|
||||||
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_initWithTake_existential_addr(%T25existentials_opaque_boxed11ExistentialP*
|
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_initWithTake_existential_addr(%T25existentials_opaque_boxed11ExistentialP*
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func allToInt<T>(_ x: T) -> Int {
|
|||||||
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
// CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
||||||
// CHECK: [[T_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
// CHECK: [[T_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ entry(%c : $RootGeneric<Int32>):
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[B_CHECKED]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[B_CHECKED]] to i8***
|
||||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[T1]], align 8
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[T1]], align 8
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[FIELDS_ADDR]], i32 0
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[FIELDS_ADDR]], i32 0
|
||||||
// CHECK: store i8** [[T0]], i8*** [[T1]], align 8
|
// CHECK: store i8** [[T0]], i8*** [[T1]], align 8
|
||||||
// CHECK: call void @swift_initClassMetadata(%swift.type* [[METADATA]], i64 0, i64 1, i8*** [[FIELDS_ADDR]], i64* [[OFFSETS]])
|
// CHECK: call void @swift_initClassMetadata(%swift.type* [[METADATA]], i64 0, i64 1, i8*** [[FIELDS_ADDR]], i64* [[OFFSETS]])
|
||||||
|
|||||||
@@ -228,20 +228,6 @@ entry(%0 : $*ComplexDynamic<A, B>, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Ch
|
|||||||
// CHECK-NEXT: ret %swift.opaque* [[T2]]
|
// CHECK-NEXT: ret %swift.opaque* [[T2]]
|
||||||
|
|
||||||
|
|
||||||
// initializeBufferWithTakeOfBuffer
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S15generic_structs13SingleDynamicVwTK"([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
|
|
||||||
// CHECK: %T = load %swift.type*,
|
|
||||||
// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %T to i8***
|
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
|
|
||||||
// CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** [[T1]]
|
|
||||||
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 6
|
|
||||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]],
|
|
||||||
// CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[T1]] to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)*
|
|
||||||
// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %T)
|
|
||||||
// CHECK-NEXT: [[T1:%.*]] = bitcast %swift.opaque* [[T0]] to {{.*}}
|
|
||||||
// CHECK-NEXT: [[T2:%.*]] = bitcast {{.*}} [[T1]] to %swift.opaque*
|
|
||||||
// CHECK-NEXT: ret %swift.opaque* [[T2]]
|
|
||||||
|
|
||||||
protocol HasAssociatedType {
|
protocol HasAssociatedType {
|
||||||
associatedtype Assoc
|
associatedtype Assoc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func dup<T>(_ x: T) -> (T, T) { var x = x; return (x,x) }
|
|||||||
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
// CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
||||||
// CHECK: [[X_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
// CHECK: [[X_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ bb0:
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 10
|
// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 9
|
||||||
// CHECK: [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
|
// CHECK: [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
|
||||||
// CHECK: [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
|
// CHECK: [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
|
||||||
@@ -136,7 +136,7 @@ bb0:
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[SIZEWITNESS:%.*]] = load i8*, i8** [[SIZE_ADDR]]
|
// CHECK: [[SIZEWITNESS:%.*]] = load i8*, i8** [[SIZE_ADDR]]
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZEWITNESS]]
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZEWITNESS]]
|
||||||
// CHECK: [[ALIGN:%.*]] = and {{.*}} [[FLAGS]], 65535
|
// CHECK: [[ALIGN:%.*]] = and {{.*}} [[FLAGS]], 65535
|
||||||
@@ -155,7 +155,7 @@ bb0:
|
|||||||
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
|
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
|
||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 10
|
// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 9
|
||||||
// CHECK: [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
|
// CHECK: [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
|
||||||
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
|
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
|
||||||
// CHECK: [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
|
// CHECK: [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ entry(%p : $*(), %i: $Builtin.Word):
|
|||||||
// CHECK: %3 = bitcast %swift.type* %T to i8***
|
// CHECK: %3 = bitcast %swift.type* %T to i8***
|
||||||
// CHECK-NEXT: %4 = getelementptr inbounds i8**, i8*** %3, i64 -1
|
// CHECK-NEXT: %4 = getelementptr inbounds i8**, i8*** %3, i64 -1
|
||||||
// CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** %4, align 8
|
// CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** %4, align 8
|
||||||
// CHECK-NEXT: %5 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 11
|
// CHECK-NEXT: %5 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 10
|
||||||
// CHECK-NEXT: %6 = load i8*, i8** %5, align 8
|
// CHECK-NEXT: %6 = load i8*, i8** %5, align 8
|
||||||
// CHECK-NEXT: %stride = ptrtoint i8* %6 to i64
|
// CHECK-NEXT: %stride = ptrtoint i8* %6 to i64
|
||||||
// CHECK-NEXT: %7 = mul nsw i64 %1, %stride
|
// CHECK-NEXT: %7 = mul nsw i64 %1, %stride
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ bb0(%x : $*T):
|
|||||||
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
|
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
|
||||||
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
// CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
||||||
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
||||||
// CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
// CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
||||||
@@ -61,7 +61,7 @@ bb0(%x : $*T):
|
|||||||
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
|
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
|
||||||
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
// CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
|
||||||
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
|
||||||
// CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
// CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
||||||
// CHECK: [[VWT:%.*]] = load i8**,
|
// CHECK: [[VWT:%.*]] = load i8**,
|
||||||
// Allocate 'copy'.
|
// Allocate 'copy'.
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
|
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
|
||||||
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
|
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import OtherModule
|
|||||||
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
||||||
// CHECK: [[VWT:%.*]] = load i8**,
|
// CHECK: [[VWT:%.*]] = load i8**,
|
||||||
// Allocate 'copy'.
|
// Allocate 'copy'.
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
|
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
|
||||||
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
|
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
|
||||||
@@ -49,7 +49,7 @@ public func copyFoo(foo: Foo) -> Foo {
|
|||||||
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
||||||
// CHECK: [[VWT:%.*]] = load i8**,
|
// CHECK: [[VWT:%.*]] = load i8**,
|
||||||
// Allocate 'copy'.
|
// Allocate 'copy'.
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
|
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
|
||||||
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
|
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
|
||||||
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
|
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ sil public_external @captured_fixed_and_dependent_params : $@convention(thin) <A
|
|||||||
// CHECK: [[T_METADATA_BASE:%.*]] = bitcast %swift.type* %T to i8***
|
// CHECK: [[T_METADATA_BASE:%.*]] = bitcast %swift.type* %T to i8***
|
||||||
// CHECK: [[T_VWTABLE_ADDR:%.*]] = getelementptr {{.*}} [[T_METADATA_BASE]], [[WORD:i[0-9]+]] -1
|
// CHECK: [[T_VWTABLE_ADDR:%.*]] = getelementptr {{.*}} [[T_METADATA_BASE]], [[WORD:i[0-9]+]] -1
|
||||||
// CHECK: [[T_VWTABLE:%.*]] = load {{.*}} [[T_VWTABLE_ADDR]]
|
// CHECK: [[T_VWTABLE:%.*]] = load {{.*}} [[T_VWTABLE_ADDR]]
|
||||||
// CHECK: [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 10
|
// CHECK: [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
|
||||||
// CHECK: [[T_FLAGS_PTR:%.*]] = load {{.*}} [[T_FLAGS_ADDR]]
|
// CHECK: [[T_FLAGS_PTR:%.*]] = load {{.*}} [[T_FLAGS_ADDR]]
|
||||||
// CHECK: [[T_FLAGS:%.*]] = ptrtoint {{.*}} [[T_FLAGS_PTR]] to [[WORD]]
|
// 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]], 65535
|
||||||
@@ -245,7 +245,7 @@ sil public_external @captured_fixed_and_dependent_params : $@convention(thin) <A
|
|||||||
// CHECK: [[T_OFFSET:%.*]] = and [[WORD]] [[T_UP_TO_ALIGN_1]], [[T_ALIGN_MASK_NOT]]
|
// CHECK: [[T_OFFSET:%.*]] = and [[WORD]] [[T_UP_TO_ALIGN_1]], [[T_ALIGN_MASK_NOT]]
|
||||||
|
|
||||||
// -- Add the size of T to start the Int field.
|
// -- Add the size of T to start the Int field.
|
||||||
// CHECK: [[T_SIZE_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
|
// CHECK: [[T_SIZE_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 8
|
||||||
// CHECK: [[T_SIZE_PTR:%.*]] = load {{.*}} [[T_SIZE_ADDR]]
|
// CHECK: [[T_SIZE_PTR:%.*]] = load {{.*}} [[T_SIZE_ADDR]]
|
||||||
// CHECK: [[T_SIZE:%.*]] = ptrtoint {{.*}} [[T_SIZE_PTR]] to [[WORD]]
|
// CHECK: [[T_SIZE:%.*]] = ptrtoint {{.*}} [[T_SIZE_PTR]] to [[WORD]]
|
||||||
// CHECK: [[T_END:%.*]] = add [[WORD]] [[T_OFFSET]], [[T_SIZE]]
|
// CHECK: [[T_END:%.*]] = add [[WORD]] [[T_OFFSET]], [[T_SIZE]]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public func functionWithResilientTypesSize(_ s: __owned Size, f: (__owned Size)
|
|||||||
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
|
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
|
||||||
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
|
||||||
|
|
||||||
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
|
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
|
||||||
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
|
||||||
// CHECK: [[WITNESS_FOR_SIZE:%.*]] = ptrtoint i8* [[WITNESS]]
|
// CHECK: [[WITNESS_FOR_SIZE:%.*]] = ptrtoint i8* [[WITNESS]]
|
||||||
// CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
|
// CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
|
||||||
|
|||||||
@@ -34,14 +34,14 @@ struct TypeLayoutTest<T> {
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
||||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
||||||
// CHECK: [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
// CHECK: [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
||||||
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
|
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
|
||||||
// CHECK: store i8** [[T_LAYOUT]]
|
// CHECK: store i8** [[T_LAYOUT]]
|
||||||
var z: T
|
var z: T
|
||||||
// -- native class, use standard NativeObject value witness
|
// -- native class, use standard NativeObject value witness
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 8)
|
||||||
var a: C
|
var a: C
|
||||||
// -- Single-element struct, shares layout of its field (Builtin.Int64)
|
// -- Single-element struct, shares layout of its field (Builtin.Int64)
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
|
||||||
var c: SSing
|
var c: SSing
|
||||||
// -- Multi-element structs use open-coded layouts
|
// -- Multi-element structs use open-coded layouts
|
||||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
|
||||||
@@ -53,13 +53,13 @@ struct TypeLayoutTest<T> {
|
|||||||
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI]]_bt, i32 0, i32 0)
|
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI]]_bt, i32 0, i32 0)
|
||||||
var f: SMult3
|
var f: SMult3
|
||||||
// -- Single-case enum, shares layout of its field (Builtin.Int64)
|
// -- Single-case enum, shares layout of its field (Builtin.Int64)
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
|
||||||
var g: ESing
|
var g: ESing
|
||||||
// -- Multi-case enum, open-coded layout
|
// -- Multi-case enum, open-coded layout
|
||||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
|
||||||
var h: EMult
|
var h: EMult
|
||||||
// -- Single-element generic struct, shares layout of its field (T)
|
// -- Single-element generic struct, shares layout of its field (T)
|
||||||
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
|
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
|
||||||
// CHECK: store i8** [[T_LAYOUT]]
|
// CHECK: store i8** [[T_LAYOUT]]
|
||||||
var i: GSing<T>
|
var i: GSing<T>
|
||||||
// -- Multi-element generic struct, need to derive from metadata
|
// -- Multi-element generic struct, need to derive from metadata
|
||||||
@@ -71,13 +71,13 @@ struct TypeLayoutTest<T> {
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
||||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
||||||
// CHECK: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
// CHECK: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
||||||
// CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
|
// CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
|
||||||
// CHECK: store i8** [[LAYOUT]]
|
// CHECK: store i8** [[LAYOUT]]
|
||||||
var j: GMult<T>
|
var j: GMult<T>
|
||||||
// -- Common layout, reuse common value witness table layout
|
// -- Common layout, reuse common value witness table layout
|
||||||
// CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 9)
|
// CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 8)
|
||||||
var k: CommonLayout
|
var k: CommonLayout
|
||||||
// -- Single-field aggregate with alignment
|
// -- Single-field aggregate with alignment
|
||||||
// CHECK: store i8** getelementptr (i8*, i8** @"$SBi128_WV", i32 9)
|
// CHECK: store i8** getelementptr (i8*, i8** @"$SBi128_WV", i32 8)
|
||||||
var l: AlignedFourInts
|
var l: AlignedFourInts
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,17 +33,17 @@ struct TypeLayoutTest<T> {
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
|
||||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
||||||
// CHECK: [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
// CHECK: [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
||||||
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
|
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
|
||||||
// CHECK: store i8** [[T_LAYOUT]]
|
// CHECK: store i8** [[T_LAYOUT]]
|
||||||
var z: T
|
var z: T
|
||||||
// -- native class, use standard NativeObject value witness
|
// -- native class, use standard NativeObject value witness
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 8)
|
||||||
var a: C
|
var a: C
|
||||||
// -- ObjC class, use standard UnknownObject value witness
|
// -- ObjC class, use standard UnknownObject value witness
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOWV", i32 8)
|
||||||
var b: O
|
var b: O
|
||||||
// -- Single-element struct, shares layout of its field (Builtin.Int64)
|
// -- Single-element struct, shares layout of its field (Builtin.Int64)
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
|
||||||
var c: SSing
|
var c: SSing
|
||||||
// -- Multi-element structs use open-coded layouts
|
// -- Multi-element structs use open-coded layouts
|
||||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
|
||||||
@@ -55,13 +55,13 @@ struct TypeLayoutTest<T> {
|
|||||||
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_1000_bt, i32 0, i32 0)
|
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_1000_bt, i32 0, i32 0)
|
||||||
var f: SMult3
|
var f: SMult3
|
||||||
// -- Single-case enum, shares layout of its field (Builtin.Int64)
|
// -- Single-case enum, shares layout of its field (Builtin.Int64)
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
|
||||||
var g: ESing
|
var g: ESing
|
||||||
// -- Multi-case enum, open-coded layout
|
// -- Multi-case enum, open-coded layout
|
||||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
|
||||||
var h: EMult
|
var h: EMult
|
||||||
// -- Single-element generic struct, shares layout of its field (T)
|
// -- Single-element generic struct, shares layout of its field (T)
|
||||||
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
|
// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
|
||||||
// CHECK: store i8** [[T_LAYOUT]]
|
// CHECK: store i8** [[T_LAYOUT]]
|
||||||
var i: GSing<T>
|
var i: GSing<T>
|
||||||
// -- Multi-element generic struct, need to derive from metadata
|
// -- Multi-element generic struct, need to derive from metadata
|
||||||
@@ -73,10 +73,10 @@ struct TypeLayoutTest<T> {
|
|||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
|
||||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
|
||||||
// CHECK: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
// CHECK: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
|
||||||
// CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
|
// CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
|
||||||
// CHECK: store i8** [[LAYOUT]]
|
// CHECK: store i8** [[LAYOUT]]
|
||||||
var j: GMult<T>
|
var j: GMult<T>
|
||||||
// -- Common layout, reuse common value witness table layout
|
// -- Common layout, reuse common value witness table layout
|
||||||
// CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 9)
|
// CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 8)
|
||||||
var k: CommonLayout
|
var k: CommonLayout
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,23 +10,23 @@ struct ReferenceStorageTypeLayout<T, Native : C, Unknown : AnyObject> {
|
|||||||
var z: T
|
var z: T
|
||||||
|
|
||||||
// -- Known-Swift-refcounted type
|
// -- Known-Swift-refcounted type
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
|
||||||
unowned(safe) var cs: C
|
unowned(safe) var cs: C
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var cu: C
|
unowned(unsafe) var cu: C
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
|
||||||
weak var cwo: C?
|
weak var cwo: C?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
|
||||||
weak var cwi: C!
|
weak var cwi: C!
|
||||||
|
|
||||||
// -- Known-Swift-refcounted archetype
|
// -- Known-Swift-refcounted archetype
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
|
||||||
unowned(safe) var nc: Native
|
unowned(safe) var nc: Native
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var nu: Native
|
unowned(unsafe) var nu: Native
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
|
||||||
weak var nwo: Native?
|
weak var nwo: Native?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
|
||||||
weak var nwi: Native!
|
weak var nwi: Native!
|
||||||
|
|
||||||
// -- Open-code layout for protocol types with witness tables.
|
// -- Open-code layout for protocol types with witness tables.
|
||||||
@@ -72,23 +72,23 @@ struct ReferenceStorageTypeLayout<T, Native : C, Unknown : AnyObject> {
|
|||||||
weak var pqcwi: (P & Q & C)!
|
weak var pqcwi: (P & Q & C)!
|
||||||
|
|
||||||
// -- Unknown-refcounted existential without witness tables.
|
// -- Unknown-refcounted existential without witness tables.
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 8)
|
||||||
unowned(safe) var aos: AnyObject
|
unowned(safe) var aos: AnyObject
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var aou: AnyObject
|
unowned(unsafe) var aou: AnyObject
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
|
||||||
weak var aowo: AnyObject?
|
weak var aowo: AnyObject?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
|
||||||
weak var aowi: AnyObject!
|
weak var aowi: AnyObject!
|
||||||
|
|
||||||
// -- Unknown-refcounted archetype
|
// -- Unknown-refcounted archetype
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 8)
|
||||||
unowned(safe) var us: Unknown
|
unowned(safe) var us: Unknown
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var uu: Unknown
|
unowned(unsafe) var uu: Unknown
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
|
||||||
weak var uwo: Unknown?
|
weak var uwo: Unknown?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
|
||||||
weak var uwi: Unknown!
|
weak var uwi: Unknown!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,52 +15,52 @@ struct ReferenceStorageTypeLayout<T, ObjC: C> {
|
|||||||
var z: T
|
var z: T
|
||||||
|
|
||||||
// -- ObjC-refcounted class
|
// -- ObjC-refcounted class
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
|
||||||
unowned(safe) var cs: C
|
unowned(safe) var cs: C
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var cu: C
|
unowned(unsafe) var cu: C
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var cwo: C?
|
weak var cwo: C?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var cwi: C!
|
weak var cwi: C!
|
||||||
|
|
||||||
// -- ObjC-refcounted archetype
|
// -- ObjC-refcounted archetype
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
|
||||||
unowned(safe) var os: ObjC
|
unowned(safe) var os: ObjC
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var ou: ObjC
|
unowned(unsafe) var ou: ObjC
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var owo: ObjC?
|
weak var owo: ObjC?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var owi: ObjC!
|
weak var owi: ObjC!
|
||||||
|
|
||||||
// -- Pure ObjC protocols are unknown-refcounted
|
// -- Pure ObjC protocols are unknown-refcounted
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
|
||||||
unowned(safe) var ps: P
|
unowned(safe) var ps: P
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var pu: P
|
unowned(unsafe) var pu: P
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var pwo: P?
|
weak var pwo: P?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var pwi: P!
|
weak var pwi: P!
|
||||||
|
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
|
||||||
unowned(safe) var pqs: P & Q
|
unowned(safe) var pqs: P & Q
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var pqu: P & Q
|
unowned(unsafe) var pqu: P & Q
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var pqwo: (P & Q)?
|
weak var pqwo: (P & Q)?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
|
||||||
weak var pqwi: (P & Q)!
|
weak var pqwi: (P & Q)!
|
||||||
|
|
||||||
// -- Composition with ObjC protocol and native class is native-refcounted
|
// -- Composition with ObjC protocol and native class is native-refcounted
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
|
||||||
unowned(safe) var pncs: (P & NativeClass)
|
unowned(safe) var pncs: (P & NativeClass)
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
|
||||||
unowned(unsafe) var pncu: (P & NativeClass)
|
unowned(unsafe) var pncu: (P & NativeClass)
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
|
||||||
weak var pncwo: (P & NativeClass)?
|
weak var pncwo: (P & NativeClass)?
|
||||||
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
|
// CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
|
||||||
weak var pncwi: (P & NativeClass)!
|
weak var pncwi: (P & NativeClass)!
|
||||||
|
|
||||||
// -- Open-code layouts when there are witness tables.
|
// -- Open-code layouts when there are witness tables.
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ struct Gen<T> {
|
|||||||
var x: C
|
var x: C
|
||||||
var y: T
|
var y: T
|
||||||
}
|
}
|
||||||
// CHECK: @"$S20weak_value_witnesses8JustWeakVWV" = internal constant [12 x i8*] {{.*}}@__swift_copy_outline_existential_box_pointer
|
|
||||||
|
|
||||||
// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwTK"(
|
// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwTK"(
|
||||||
|
|
||||||
|
|||||||
@@ -658,48 +658,6 @@ namespace swift {
|
|||||||
ValueWitnessTable *vwtable);
|
ValueWitnessTable *vwtable);
|
||||||
} // namespace swift
|
} // namespace swift
|
||||||
|
|
||||||
|
|
||||||
TEST(MetadataTest, installCommonValueWitnesses_pod_indirect) {
|
|
||||||
ValueWitnessTable testTable;
|
|
||||||
FullMetadata<Metadata> testMetadata{{&testTable}, {MetadataKind::Opaque}};
|
|
||||||
|
|
||||||
// rdar://problem/21375421 - pod_indirect_initializeBufferWithTakeOfBuffer
|
|
||||||
// should move ownership of a fixed-size buffer.
|
|
||||||
|
|
||||||
testTable.size = sizeof(ValueBuffer) + 1;
|
|
||||||
testTable.flags = ValueWitnessFlags()
|
|
||||||
.withAlignment(alignof(ValueBuffer))
|
|
||||||
.withPOD(true)
|
|
||||||
.withBitwiseTakable(true)
|
|
||||||
.withInlineStorage(false);
|
|
||||||
testTable.stride = sizeof(ValueBuffer) + alignof(ValueBuffer);
|
|
||||||
|
|
||||||
installCommonValueWitnesses(*testTable.getTypeLayout(), &testTable);
|
|
||||||
|
|
||||||
// Replace allocateBuffer and destroyBuffer with logging versions.
|
|
||||||
struct {
|
|
||||||
ValueBuffer buffer;
|
|
||||||
uintptr_t canary;
|
|
||||||
} buf1{{}, 0x5A5A5A5AU}, buf2{{}, 0xA5A5A5A5U};
|
|
||||||
testMetadata.allocateBoxForExistentialIn(&buf1.buffer);
|
|
||||||
|
|
||||||
testTable.initializeBufferWithTakeOfBuffer(&buf2.buffer, &buf1.buffer,
|
|
||||||
&testMetadata);
|
|
||||||
|
|
||||||
// The existential's box reference should be copied.
|
|
||||||
EXPECT_EQ(buf1.buffer.PrivateData[0], buf2.buffer.PrivateData[0]);
|
|
||||||
|
|
||||||
// Ownership of the box should have been transferred.
|
|
||||||
auto *reference = reinterpret_cast<HeapObject *>(buf2.buffer.PrivateData[0]);
|
|
||||||
EXPECT_TRUE(swift_isUniquelyReferencedOrPinned_nonNull_native(reference));
|
|
||||||
|
|
||||||
EXPECT_EQ(buf1.canary, (uintptr_t)0x5A5A5A5AU);
|
|
||||||
EXPECT_EQ(buf2.canary, (uintptr_t)0xA5A5A5A5U);
|
|
||||||
|
|
||||||
// Release the buffer.
|
|
||||||
swift_release(reference);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We cannot construct RelativeDirectPointer instances, so define
|
// We cannot construct RelativeDirectPointer instances, so define
|
||||||
// a "shadow" struct for that purpose
|
// a "shadow" struct for that purpose
|
||||||
struct GenericWitnessTableStorage {
|
struct GenericWitnessTableStorage {
|
||||||
|
|||||||
Reference in New Issue
Block a user