Unable to lower RelativeAddress/RelativeOffset on 16-bit arch: Assertion failed

16-bit

(Carl Peto) #1

I'm getting another compile fail from any code containing even simple structs for 16 bit, with the above error.

Here's the backtrace:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007fff6055bb66 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff60726080 libsystem_pthread.dylib`pthread_kill + 333
    frame #2: 0x00007fff604b71ae libsystem_c.dylib`abort + 127
    frame #3: 0x00007fff6047f1ac libsystem_c.dylib`__assert_rtn + 320
    frame #4: 0x00000001088f47d8 swift`llvm::ConstantExpr::getTrunc(C=0x000000011683ead0, Ty=0x0000000117845c38, OnlyIfReduced=false) at Constants.cpp:1622
    frame #5: 0x0000000100c401f9 swift`clang::CodeGen::ConstantAggregateBuilderBase::getRelativeOffset(this=0x00007ffeefbf5c70, offsetType=0x0000000117845c38, target=0x000000011683e738) at ConstantInitBuilder.cpp:142
    frame #6: 0x000000010031260a swift`clang::CodeGen::ConstantAggregateBuilderBase::addTaggedRelativeOffset(this=0x00007ffeefbf5c70, type=0x0000000117845c38, address=0x000000011683e5c8, tag=0) at ConstantInitBuilder.h:237
    frame #7: 0x00000001002f8d9a swift`swift::irgen::ConstantAggregateBuilderBase::addRelativeAddress(this=0x00007ffeefbf5c70, reference=ConstantReference @ 0x00007ffeefbf5b08) at ConstantBuilder.h:92
    frame #8: 0x00000001003ee59c swift`(anonymous namespace)::WitnessTableBuilder::buildAccessFunction(this=0x00007ffeefbf6130, wtable=0x000000011683e288) at GenProto.cpp:1996
    frame #9: 0x00000001003edd86 swift`swift::irgen::IRGenModule::emitSILWitnessTable(this=0x00007ffeefbf6e80, wt=0x0000000115843b48) at GenProto.cpp:2252
    frame #10: 0x00000001002fc04e swift`swift::irgen::IRGenerator::emitGlobalTopLevel(this=0x00007ffeefbf8588, emitForParallelEmission=false) at GenDecl.cpp:1084
    frame #11: 0x0000000100483ffd swift`performIRGeneration(Opts=0x00007ffeefbfc180, M=0x000000011581c6a0, SILMod=unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> > @ 0x00007ffeefbf89b0, ModuleName=(Data = "uSwift.ll", Length = 9), PSPs=0x00007ffeefbfa580, LLVMContext=0x0000000116807920, SF=0x000000011581c758, outModuleHash=0x00007ffeefbf9378, StartElem=0) at IRGen.cpp:795
    frame #12: 0x0000000100484dcb swift`swift::performIRGeneration(Opts=0x00007ffeefbfc180, SF=0x000000011581c758, SILMod=unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> > @ 0x00007ffeefbf8c78, ModuleName=(Data = "uSwift.ll", Length = 9), PSPs=0x00007ffeefbfa580, LLVMContext=0x0000000116807920, StartElem=0, outModuleHash=0x00007ffeefbf9378) at IRGen.cpp:1121
    frame #13: 0x000000010011f2cc swift`generateIR(IRGenOpts=0x00007ffeefbfc180, SM=unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> > @ 0x00007ffeefbf9370, PSPs=0x00007ffeefbfa580, OutputFilename=(Data = "uSwift.ll", Length = 9), MSF=swift::ModuleOrSourceFile @ 0x00007ffeefbf8ca0, IRModule=0x00007ffeefbf9380, HashGlobal=0x00007ffeefbf9378, parallelOutputFilenames=(Data = "uSwift.ll", Length = 1)) at FrontendTool.cpp:1131
    frame #14: 0x00000001000f89ad swift`performCompileStepsPostSILGen(Instance=0x000000011581b000, Invocation=0x00007ffeefbfbaf8, SM=unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> > @ 0x00007ffeefbfa560, astGuaranteedToCorrespondToSIL=true, MSF=swift::ModuleOrSourceFile @ 0x00007ffeefbf94f8, PSPs=0x00007ffeefbfa580, moduleIsPublic=true, ReturnValue=0x00007ffeefbfaf74, observer=0x0000000000000000, Stats=0x0000000000000000) at FrontendTool.cpp:1384
    frame #15: 0x00000001000ea273 swift`performCompile(Instance=0x000000011581b000, Invocation=0x00007ffeefbfbaf8, Args=ArrayRef<const char *> @ 0x00007ffeefbfa780, ReturnValue=0x00007ffeefbfaf74, observer=0x0000000000000000, Stats=0x0000000000000000) at FrontendTool.cpp:1002
    frame #16: 0x00000001000e7352 swift`swift::performFrontend(Args=ArrayRef<const char *> @ 0x00007ffeefbfb188, Argv0="/Users/carlpeto/avr/swift/build/Ninja-DebugAssert+stdlib-ReleaseAssert/swift-macosx-x86_64/bin/swift", MainAddr=0x000000010000af80, observer=0x0000000000000000) at FrontendTool.cpp:1842
    frame #17: 0x000000010000d6a5 swift`run_driver(ExecName=(Data = "swift", Length = 5), argv=const llvm::ArrayRef<const char *> @ 0x00007ffeefbfc8e8) at driver.cpp:122
    frame #18: 0x000000010000bf5d swift`main(argc_=20, argv_=0x00007ffeefbff788) at driver.cpp:246
    frame #19: 0x00007fff6040b015 libdyld.dylib`start + 1
    frame #20: 0x00007fff6040b015 libdyld.dylib`start + 1

This is the original swift code...

import AVR
import Swift

typealias IntegerLiteralType = UInt8

pinMode(pin: 4, mode: INPUT)

setupTimerIntervalInterruptCallback(tenthsOfAMillisecond: 1000) {
}

struct MyStruct {
  var internal1: Int8
  var internal2: Int8
  var internal3: Int16
  var internal4: Int16
  var internal5: Int8
}

while(true) {
}

In the swift compiler layer, the trap occurs in IRGen, when lowering a constant using addRelativeAddress.

This is the method in ConstantBuilder.h:

  /// Add a tagged relative reference to the given address.  The direct
  /// target must be defined within the current image, but it might be
  /// a "GOT-equivalent", i.e. a pointer to an external object; if so,
  /// set the low bit of the offset to indicate that this is true.
  void addRelativeAddress(ConstantReference reference) {
    addTaggedRelativeOffset(IGM().RelativeAddressTy,
                            reference.getValue(),
                            unsigned(reference.isIndirect()));
  }

This is calling into clang code and there's a bit of a mismatch that is causing the trap.

The clang code is building the relevant LLVM IR:

ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
                                                llvm::Constant *target) {
  // Compute the address of the relative-address slot.
  auto base = getAddrOfCurrentPosition(offsetType);

  // Subtract.
  base = llvm::ConstantExpr::getPtrToInt(base, Builder.CGM.IntPtrTy);
  target = llvm::ConstantExpr::getPtrToInt(target, Builder.CGM.IntPtrTy);
  llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base);

  // Truncate to the relative-address type if necessary.
  if (Builder.CGM.IntPtrTy != offsetType) {
    offset = llvm::ConstantExpr::getTrunc(offset, offsetType);
  }

  return offset;
}

In this case, the architecture is 16 bit so Builder.CGM.IntPtrTy is a 16 bit integer.

The offsetType comes from the swift IRGen layer, IRGenModule.RelativeAddressTy.

In swift, I read this as hard coded to be a 32 bit integer using a union in the IRGenModule class.

I think this is the code in question...

  llvm::Type *VoidTy;                  /// void (usually {})
  llvm::IntegerType *Int1Ty;           /// i1
  llvm::IntegerType *Int8Ty;           /// i8
  llvm::IntegerType *Int16Ty;          /// i16
  union {
    llvm::IntegerType *Int32Ty;          /// i32
    llvm::IntegerType *RelativeAddressTy;
  };
  union {
    llvm::PointerType *Int32PtrTy;            /// i32 *
    llvm::PointerType *RelativeAddressPtrTy;
  };
  llvm::IntegerType *Int64Ty;          /// i64
  union {
    llvm::IntegerType *SizeTy;         /// usually i32 or i64
    llvm::IntegerType *IntPtrTy;
    llvm::IntegerType *MetadataKindTy;
    llvm::IntegerType *OnceTy;
    llvm::IntegerType *FarRelativeAddressTy;
    llvm::IntegerType *ProtocolDescriptorRefTy;
  };
  llvm::IntegerType *ObjCBoolTy;       /// i8 or i1
  union {
    llvm::PointerType *Int8PtrTy;      /// i8*
    llvm::PointerType *WitnessTableTy;
    llvm::PointerType *ObjCSELTy;
    llvm::PointerType *FunctionPtrTy;
    llvm::PointerType *CaptureDescriptorPtrTy;
  };
  union {
    llvm::PointerType *Int8PtrPtrTy;   /// i8**
    llvm::PointerType *WitnessTablePtrTy;
  };

So in this case I think clang reads this as "the offset does not match the standard integer/pointer type for the target/platform, so it must be longer, add an i32 trunc instruction into the IR". In this case, the integer type is 16-bit so clang traps when you try to insert a trunc from 16 bit to 32 bit.

I think there are two ways to solve this issue and I wanted to ask what everyone thinks is the best approach?

I don't really understand these relative offsets very well so I'll need advice.

First approach:
Change RelativeAddressTy and RelativeAddressPtrTy to be platform dependent instead of hard coded to 32 bit. This seems cleaner but might have performance/complexity implications or introduce bugs.

Second approach:
Patch clang::ConstantAggregateBuilderBase::getRelativeOffset so that it will either trunc or zero extend as appropriate. This seems safer but might have implications that I haven't thought of and is a patch outside the standard swift tree (in clang) so that's not ideal I guess.

Both patches seem relatively significant changes, just to add a feature to swift/clang that will be very rarely used (16-bit support) so I'm unsure what's the best approach. I'm also open to any suggestions for better or less intrusive modifications?

Cheers,
Carl


(Adrian Zubarev) #2

Was it really necessary to open the thread under such a scary title?

Best Regards,
Adrian


(Carl Peto) #3

Happy to change it. New to the forums. What is scary? How would you rather I called it?

Carl


(Adrian Zubarev) #4

The new shorter title is good enough, I think ;)


(Carl Peto) #5

Cool. Thanks. Was trying to make sure people who google for the error find it. I'll keep titles shorter in future.


(John McCall) #6

I think it’s reasonable to change RelativePointerTy to be 16-bit on your target. Note that you’ll eventually need to do a lot of work to support that in the runtime headers.


(Joe Groff) #7

Chances are whatever metadata structure is getting emitted here isn't really necessary for an embedded zero-runtime target too. This is another place where, for the OP's purposes, having a no-metadata compiler flag might help make progress.


(John McCall) #8

Yeah, a lot of these structures are probably really undesirable on a 16-bit target. But in case they are, it would be good to make a quick run through the metadata structures to see if any of them would be obviously poorly-packed if we used a 16-bit relative address.


(Carl Peto) #9

How about this as a patch?

diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 53629b8ade..7b2b0a591f 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -166,6 +166,8 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
   Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
   Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
   SizeTy = DataLayout.getIntPtrType(getLLVMContext(), /*addrspace*/ 0);
+  RelativeAddressTy = SizeTy;
+  RelativeAddressPtrTy = RelativeAddressTy->getPointerTo();
 
   auto CI = static_cast<ClangImporter*>(&*Context.getClangModuleLoader());
   assert(CI && "no clang module loader");
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index fa24169e16..f3381a0403 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -488,14 +488,10 @@ public:
   llvm::IntegerType *Int1Ty;           /// i1
   llvm::IntegerType *Int8Ty;           /// i8
   llvm::IntegerType *Int16Ty;          /// i16
-  union {
-    llvm::IntegerType *Int32Ty;          /// i32
-    llvm::IntegerType *RelativeAddressTy;
-  };
-  union {
-    llvm::PointerType *Int32PtrTy;            /// i32 *
-    llvm::PointerType *RelativeAddressPtrTy;
-  };
+  llvm::IntegerType *Int32Ty;          /// i32
+  llvm::IntegerType *RelativeAddressTy;
+  llvm::PointerType *Int32PtrTy;            /// i32 *
+  llvm::PointerType *RelativeAddressPtrTy;
   llvm::IntegerType *Int64Ty;          /// i64
   union {
     llvm::IntegerType *SizeTy;         /// usually i32 or i64

I don't know if this would be appropriate to upstream though? I'm a bit inexperienced and don't know all the angles. It solves the problem and I'm able to produce roughly correct LLVM IR, which I can compile to 16 bit AVR assembly language. :grin:

Here's the original source...

import AVR
import Swift

typealias IntegerLiteralType = UInt8

struct MyStruct {
  var internal1: Int8
  var internal2: Int8
  var internal3: Int16
  var internal4: Int16
  var internal5: Int8
}

while(true) {
}

Producing the following LLVM IR...

; ModuleID = 'main_clean.ll'
source_filename = "main.ll"
target datalayout = "e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
target triple = "avr-atmel-linux-gnueabihf"

%swift.type_metadata_record = type { i16 }
%swift.type = type { i16 }
%T4main8MyStructV = type <{ %Ts4Int8V, %Ts4Int8V, %Ts5Int16V, %Ts5Int16V, %Ts4Int8V }>
%Ts5Int16V = type <{ i16 }>
%Ts4Int8V = type <{ i8 }>
%swift.opaque = type opaque
%swift.refcounted = type { %swift.type*, i16 }
%swift.metadata_response = type { %swift.type*, i16 }

@"$S4main8MyStructVWV" = internal constant [11 x i8*] [i8* bitcast (%swift.opaque* ([6 x i8]*, [6 x i8]*, %swift.type*)* @"$S4main8MyStructVwCP" to i8*), i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy7_2 to i8*), i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy7_2 to i8*), i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy7_2 to i8*), i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy7_2 to i8*), i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$S4main8MyStructVwet" to i8*), i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$S4main8MyStructVwst" to i8*), i8* inttoptr (i16 7 to i8*), i8* inttoptr (i16 1 to i8*), i8* inttoptr (i16 8 to i8*)], align 2
@0 = private constant [5 x i8] c"main\00"
@"$S4mainMXM" = linkonce_odr hidden constant <{ i32, i32, i16 }> <{ i32 0, i32 0, i16 sub (i16 ptrtoint ([5 x i8]* @0 to i16), i16 ptrtoint (i16* getelementptr inbounds (<{ i32, i32, i16 }>, <{ i32, i32, i16 }>* @"$S4mainMXM", i32 0, i32 2) to i16)) }>, section ".rodata", align 4
@1 = private constant [9 x i8] c"MyStruct\00"
@"$S4main8MyStructVMn" = hidden constant <{ i32, i16, i16, i16, i16, i32, i32 }> <{ i32 81, i16 sub (i16 ptrtoint (<{ i32, i32, i16 }>* @"$S4mainMXM" to i16), i16 ptrtoint (i16* getelementptr inbounds (<{ i32, i16, i16, i16, i16, i32, i32 }>, <{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn", i32 0, i32 1) to i16)), i16 sub (i16 ptrtoint ([9 x i8]* @1 to i16), i16 ptrtoint (i16* getelementptr inbounds (<{ i32, i16, i16, i16, i16, i32, i32 }>, <{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn", i32 0, i32 2) to i16)), i16 sub (i16 ptrtoint (%swift.metadata_response (i16)* @"$S4main8MyStructVMa" to i16), i16 ptrtoint (i16* getelementptr inbounds (<{ i32, i16, i16, i16, i16, i32, i32 }>, <{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn", i32 0, i32 3) to i16)), i16 sub (i16 ptrtoint ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF" to i16), i16 ptrtoint (i16* getelementptr inbounds (<{ i32, i16, i16, i16, i16, i32, i32 }>, <{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn", i32 0, i32 4) to i16)), i32 5, i32 2 }>, section ".rodata", align 4
@"$S4main8MyStructVMf" = internal constant <{ i8**, i16, <{ i32, i16, i16, i16, i16, i32, i32 }>*, i32, i32, i32, i32, i32 }> <{ i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @"$S4main8MyStructVWV", i32 0, i32 0), i16 512, <{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn", i32 0, i32 1, i32 2, i32 4, i32 6 }>, align 2
@"symbolic \01____ 4main8MyStructV" = linkonce_odr hidden constant <{ [1 x i8], i16, i8 }> <{ [1 x i8] c"\01", i16 sub (i16 ptrtoint (<{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn" to i16), i16 ptrtoint (i16* getelementptr inbounds (<{ [1 x i8], i16, i8 }>, <{ [1 x i8], i16, i8 }>* @"symbolic \01____ 4main8MyStructV", i32 0, i32 1) to i16)), i8 0 }>, section "swift5_typeref", align 1
@"symbolic s4Int8V" = linkonce_odr hidden constant <{ [7 x i8], i8 }> <{ [7 x i8] c"s4Int8V", i8 0 }>, section "swift5_typeref", align 1
@2 = private constant [10 x i8] c"internal1\00", section "swift5_reflstr"
@3 = private constant [10 x i8] c"internal2\00", section "swift5_reflstr"
@"symbolic s5Int16V" = linkonce_odr hidden constant <{ [8 x i8], i8 }> <{ [8 x i8] c"s5Int16V", i8 0 }>, section "swift5_typeref", align 1
@4 = private constant [10 x i8] c"internal3\00", section "swift5_reflstr"
@5 = private constant [10 x i8] c"internal4\00", section "swift5_reflstr"
@6 = private constant [10 x i8] c"internal5\00", section "swift5_reflstr"
@"$S4main8MyStructVMF" = internal constant { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 } { i16 sub (i16 ptrtoint (<{ [1 x i8], i16, i8 }>* @"symbolic \01____ 4main8MyStructV" to i16), i16 ptrtoint ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF" to i16)), i32 0, i16 0, i16 12, i32 5, i32 2, i16 sub (i16 ptrtoint (<{ [7 x i8], i8 }>* @"symbolic s4Int8V" to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 6) to i16)), i16 sub (i16 ptrtoint ([10 x i8]* @2 to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 7) to i16)), i32 2, i16 sub (i16 ptrtoint (<{ [7 x i8], i8 }>* @"symbolic s4Int8V" to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 9) to i16)), i16 sub (i16 ptrtoint ([10 x i8]* @3 to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 10) to i16)), i32 2, i16 sub (i16 ptrtoint (<{ [8 x i8], i8 }>* @"symbolic s5Int16V" to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 12) to i16)), i16 sub (i16 ptrtoint ([10 x i8]* @4 to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 13) to i16)), i32 2, i16 sub (i16 ptrtoint (<{ [8 x i8], i8 }>* @"symbolic s5Int16V" to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 15) to i16)), i16 sub (i16 ptrtoint ([10 x i8]* @5 to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 16) to i16)), i32 2, i16 sub (i16 ptrtoint (<{ [7 x i8], i8 }>* @"symbolic s4Int8V" to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 18) to i16)), i16 sub (i16 ptrtoint ([10 x i8]* @6 to i16), i16 ptrtoint (i16* getelementptr inbounds ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }, { i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF", i32 0, i32 19) to i16)) }, section "swift5_fieldmd", align 4
@"\01l_type_metadata_table" = private constant [1 x %swift.type_metadata_record] [%swift.type_metadata_record { i16 sub (i16 ptrtoint (<{ i32, i16, i16, i16, i16, i32, i32 }>* @"$S4main8MyStructVMn" to i16), i16 ptrtoint ([1 x %swift.type_metadata_record]* @"\01l_type_metadata_table" to i16)) }], section "swift5_type_metadata", align 4
@__swift_reflection_version = linkonce_odr hidden constant i16 3
@_swift1_autolink_entries = private constant [6 x i8] c"-lavr\00", section ".swift1_autolink_entries", align 2
@llvm.used = appending global [4 x i8*] [i8* bitcast ([1 x %swift.type_metadata_record]* @"\01l_type_metadata_table" to i8*), i8* bitcast ({ i16, i32, i16, i16, i32, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16, i32, i16, i16 }* @"$S4main8MyStructVMF" to i8*), i8* bitcast (i16* @__swift_reflection_version to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @_swift1_autolink_entries, i32 0, i32 0)], section "llvm.metadata"

@"$S4main8MyStructVN" = hidden alias %swift.type, bitcast (i16* getelementptr inbounds (<{ i8**, i16, <{ i32, i16, i16, i16, i16, i32, i32 }>*, i32, i32, i32, i32, i32 }>, <{ i8**, i16, <{ i32, i16, i16, i16, i16, i32, i32 }>*, i32, i32, i32, i32, i32 }>* @"$S4main8MyStructVMf", i32 0, i32 1) to %swift.type*)

; Function Attrs: norecurse noreturn nounwind readnone
define protected i16 @main(i16, i8** nocapture readnone) local_unnamed_addr #0 {
entry:
  br label %2

; <label>:2:                                      ; preds = %2, %entry
  br label %2
}

...SNIP...

And compiling to this assembly...

	.text
	.file	"main.ll"
	.protected	main            ; -- Begin function main
	.globl	main
	.p2align	1
	.type	main,@function
main:                                   ; @main
; %bb.0:                                ; %entry
LBB0_1:                                 ; =>This Inner Loop Header: Depth=1
	rjmp	LBB0_1
.Lfunc_end0:
	.size	main, .Lfunc_end0-main
                                        ; -- End function
	.hidden	$S4main8MyStructV9internal1s4Int8Vvg ; -- Begin function $S4main8MyStructV9internal1s4Int8Vvg
	.globl	$S4main8MyStructV9internal1s4Int8Vvg
	.p2align	1
	.type	$S4main8MyStructV9internal1s4Int8Vvg,@function
$S4main8MyStructV9internal1s4Int8Vvg:   ; @"$S4main8MyStructV9internal1s4Int8Vvg"
; %bb.0:                                ; %entry
                                        ; kill: def $r24 killed $r24 killed $r25r24
	ret
.Lfunc_end1:
	.size	$S4main8MyStructV9internal1s4Int8Vvg, .Lfunc_end1-($S4main8MyStructV9internal1s4Int8Vvg)
                                        ; -- End function
	.hidden	$S4main8MyStructV9internal1s4Int8Vvs ; -- Begin function $S4main8MyStructV9internal1s4Int8Vvs
	.globl	$S4main8MyStructV9internal1s4Int8Vvs
	.p2align	1
	.type	$S4main8MyStructV9internal1s4Int8Vvs,@function
$S4main8MyStructV9internal1s4Int8Vvs:   ; @"$S4main8MyStructV9internal1s4Int8Vvs"
; %bb.0:                                ; %entry
	mov	r26, r22
	mov	r27, r23
	st	X, r24
	ret
.Lfunc_end2:
	.size	$S4main8MyStructV9internal1s4Int8Vvs, .Lfunc_end2-($S4main8MyStructV9internal1s4Int8Vvs)
                                        ; -- End function
	.hidden	$S4main8MyStructV9internal1s4Int8VvM ; -- Begin function $S4main8MyStructV9internal1s4Int8VvM
	.globl	$S4main8MyStructV9internal1s4Int8VvM
	.p2align	1
	.type	$S4main8MyStructV9internal1s4Int8VvM,@function
$S4main8MyStructV9internal1s4Int8VvM:   ; @"$S4main8MyStructV9internal1s4Int8VvM"
; %bb.0:                                ; %entry
	mov	r24, r22
	mov	r25, r23
	ldi	r22, pm_lo8(($S4main8MyStructV9internal1s4Int8VvM.resume.0))
	ldi	r23, pm_hi8(($S4main8MyStructV9internal1s4Int8VvM.resume.0))
	ret
.Lfunc_end3:
	.size	$S4main8MyStructV9internal1s4Int8VvM, .Lfunc_end3-($S4main8MyStructV9internal1s4Int8VvM)
                                        ; -- End function
	.p2align	1               ; -- Begin function $S4main8MyStructV9internal1s4Int8VvM.resume.0
	.type	$S4main8MyStructV9internal1s4Int8VvM.resume.0,@function
$S4main8MyStructV9internal1s4Int8VvM.resume.0: ; @"$S4main8MyStructV9internal1s4Int8VvM.resume.0"
; %bb.0:                                ; %entryresume.0
	ret
.Lfunc_end4:
	.size	$S4main8MyStructV9internal1s4Int8VvM.resume.0, .Lfunc_end4-($S4main8MyStructV9internal1s4Int8VvM.resume.0)
                                        ; -- End function
	.hidden	$S4main8MyStructV9internal2s4Int8Vvg ; -- Begin function $S4main8MyStructV9internal2s4Int8Vvg
	.globl	$S4main8MyStructV9internal2s4Int8Vvg
	.p2align	1
	.type	$S4main8MyStructV9internal2s4Int8Vvg,@function
$S4main8MyStructV9internal2s4Int8Vvg:   ; @"$S4main8MyStructV9internal2s4Int8Vvg"
; %bb.0:                                ; %entry
	mov	r24, r25
	ret
.Lfunc_end5:
	.size	$S4main8MyStructV9internal2s4Int8Vvg, .Lfunc_end5-($S4main8MyStructV9internal2s4Int8Vvg)
                                        ; -- End function
	.hidden	$S4main8MyStructV9internal2s4Int8Vvs ; -- Begin function $S4main8MyStructV9internal2s4Int8Vvs
	.globl	$S4main8MyStructV9internal2s4Int8Vvs
	.p2align	1
	.type	$S4main8MyStructV9internal2s4Int8Vvs,@function
$S4main8MyStructV9internal2s4Int8Vvs:   ; @"$S4main8MyStructV9internal2s4Int8Vvs"
; %bb.0:                                ; %entry
	mov	r30, r22
	mov	r31, r23
	std	Z+1, r24
	ret
.Lfunc_end6:
	.size	$S4main8MyStructV9internal2s4Int8Vvs, .Lfunc_end6-($S4main8MyStructV9internal2s4Int8Vvs)
                                        ; -- End function
	.hidden	$S4main8MyStructV9internal2s4Int8VvM ; -- Begin function $S4main8MyStructV9internal2s4Int8VvM
	.globl	$S4main8MyStructV9internal2s4Int8VvM
	.p2align	1
	.type	$S4main8MyStructV9internal2s4Int8VvM,@function
$S4main8MyStructV9internal2s4Int8VvM:   ; @"$S4main8MyStructV9internal2s4Int8VvM"
; %bb.0:                                ; %entry
	mov	r24, r22
	mov	r25, r23
	adiw	r24, 1
	ldi	r22, pm_lo8(($S4main8MyStructV9internal2s4Int8VvM.resume.0))
	ldi	r23, pm_hi8(($S4main8MyStructV9internal2s4Int8VvM.resume.0))
	ret
.Lfunc_end7:
	.size	$S4main8MyStructV9internal2s4Int8VvM, .Lfunc_end7-($S4main8MyStructV9internal2s4Int8VvM)
                                        ; -- End function
	.p2align	1               ; -- Begin function $S4main8MyStructV9internal2s4Int8VvM.resume.0
	.type	$S4main8MyStructV9internal2s4Int8VvM.resume.0,@function

...SNIP...

LBB26_9:
	andi	r20, 1
	cpi	r20, 0
	brne	LBB26_11
; %bb.10:
	adiw	r30, 7
	ldi	r24, 0
	st	Z, r24
LBB26_11:
	ret
.Lfunc_end26:
	.size	$S4main8MyStructVwst, .Lfunc_end26-($S4main8MyStructVwst)
                                        ; -- End function
	.hidden	$S4main8MyStructVMa     ; -- Begin function $S4main8MyStructVMa
	.globl	$S4main8MyStructVMa
	.p2align	1
	.type	$S4main8MyStructVMa,@function
$S4main8MyStructVMa:                    ; @"$S4main8MyStructVMa"
; %bb.0:                                ; %entry
	ldi	r22, lo8(($S4main8MyStructVMf)+2)
	ldi	r23, hi8(($S4main8MyStructVMf)+2)
	ldi	r24, 0
	ldi	r25, 0
	ret
.Lfunc_end27:
	.size	$S4main8MyStructVMa, .Lfunc_end27-($S4main8MyStructVMa)
                                        ; -- End function
	.type	$S4main8MyStructVWV,@object ; @"$S4main8MyStructVWV"
	.section	.rodata,"a",@progbits
	.p2align	1
$S4main8MyStructVWV:
	.short	($S4main8MyStructVwCP)
	.short	__swift_noop_void_return
	.short	__swift_memcpy7_2
	.short	__swift_memcpy7_2
	.short	__swift_memcpy7_2
	.short	__swift_memcpy7_2
	.short	($S4main8MyStructVwet)
	.short	($S4main8MyStructVwst)
	.short	7
	.short	1
	.short	8
	.size	$S4main8MyStructVWV, 22

	.type	__unnamed_1,@object     ; @0
__unnamed_1:
	.asciz	"main"
	.size	__unnamed_1, 5

	.hidden	$S4mainMXM              ; @"$S4mainMXM"
	.type	$S4mainMXM,@object
	.weak	$S4mainMXM
	.p2align	2
$S4mainMXM:
	.long	0                       ; 0x0
	.long	0                       ; 0x0
	.short	(__unnamed_1-($S4mainMXM))-8
	.size	$S4mainMXM, 10

	.type	__unnamed_2,@object     ; @1
__unnamed_2:
	.asciz	"MyStruct"
	.size	__unnamed_2, 9

	.hidden	$S4main8MyStructVMn     ; @"$S4main8MyStructVMn"
	.type	$S4main8MyStructVMn,@object
	.globl	$S4main8MyStructVMn
	.p2align	2
$S4main8MyStructVMn:
	.long	81                      ; 0x51
	.short	(($S4mainMXM)-($S4main8MyStructVMn))-4
	.short	(__unnamed_2-($S4main8MyStructVMn))-6
	.short	(($S4main8MyStructVMa)-($S4main8MyStructVMn))-8
	.short	(($S4main8MyStructVMF)-($S4main8MyStructVMn))-10
	.long	5                       ; 0x5
	.long	2                       ; 0x2
	.size	$S4main8MyStructVMn, 20

	.type	$S4main8MyStructVMf,@object ; @"$S4main8MyStructVMf"
	.p2align	1
$S4main8MyStructVMf:
	.short	($S4main8MyStructVWV)
	.short	512                     ; 0x200
	.short	($S4main8MyStructVMn)
	.long	0                       ; 0x0
	.long	1                       ; 0x1
	.long	2                       ; 0x2
	.long	4                       ; 0x4
	.long	6                       ; 0x6
	.size	$S4main8MyStructVMf, 26

	.hidden	"symbolic ____ 4main8MyStructV" ; @"symbolic \01____ 4main8MyStructV"
	.type	"symbolic ____ 4main8MyStructV",@object
	.section	swift5_typeref,"a",@progbits
	.weak	"symbolic ____ 4main8MyStructV"
"symbolic ____ 4main8MyStructV":
	.byte	1
	.short	(($S4main8MyStructVMn)-"symbolic ____ 4main8MyStructV")-1
	.byte	0                       ; 0x0
	.size	"symbolic ____ 4main8MyStructV", 4

	.hidden	"symbolic s4Int8V"      ; @"symbolic s4Int8V"
	.type	"symbolic s4Int8V",@object
	.weak	"symbolic s4Int8V"
"symbolic s4Int8V":
	.ascii	"s4Int8V"
	.byte	0                       ; 0x0
	.size	"symbolic s4Int8V", 8

	.type	__unnamed_3,@object     ; @2
	.section	swift5_reflstr,"a",@progbits
__unnamed_3:
	.asciz	"internal1"
	.size	__unnamed_3, 10

	.type	__unnamed_4,@object     ; @3
__unnamed_4:
	.asciz	"internal2"
	.size	__unnamed_4, 10

	.hidden	"symbolic s5Int16V"     ; @"symbolic s5Int16V"
	.type	"symbolic s5Int16V",@object
	.section	swift5_typeref,"a",@progbits
	.weak	"symbolic s5Int16V"
"symbolic s5Int16V":
	.ascii	"s5Int16V"
	.byte	0                       ; 0x0
	.size	"symbolic s5Int16V", 9

	.type	__unnamed_5,@object     ; @4
	.section	swift5_reflstr,"a",@progbits
__unnamed_5:
	.asciz	"internal3"
	.size	__unnamed_5, 10

	.type	__unnamed_6,@object     ; @5
__unnamed_6:
	.asciz	"internal4"
	.size	__unnamed_6, 10

	.type	__unnamed_7,@object     ; @6
__unnamed_7:
	.asciz	"internal5"
	.size	__unnamed_7, 10

	.type	$S4main8MyStructVMF,@object ; @"$S4main8MyStructVMF"
	.section	swift5_fieldmd,"a",@progbits
	.p2align	2
$S4main8MyStructVMF:
	.short	"symbolic ____ 4main8MyStructV"-($S4main8MyStructVMF)
	.long	0                       ; 0x0
	.short	0                       ; 0x0
	.short	12                      ; 0xc
	.long	5                       ; 0x5
	.long	2                       ; 0x2
	.short	("symbolic s4Int8V"-($S4main8MyStructVMF))-18
	.short	(__unnamed_3-($S4main8MyStructVMF))-20
	.long	2                       ; 0x2
	.short	("symbolic s4Int8V"-($S4main8MyStructVMF))-26
	.short	(__unnamed_4-($S4main8MyStructVMF))-28
	.long	2                       ; 0x2
	.short	("symbolic s5Int16V"-($S4main8MyStructVMF))-34
	.short	(__unnamed_5-($S4main8MyStructVMF))-36
	.long	2                       ; 0x2
	.short	("symbolic s5Int16V"-($S4main8MyStructVMF))-42
	.short	(__unnamed_6-($S4main8MyStructVMF))-44
	.long	2                       ; 0x2
	.short	("symbolic s4Int8V"-($S4main8MyStructVMF))-50
	.short	(__unnamed_7-($S4main8MyStructVMF))-52
	.size	$S4main8MyStructVMF, 54

	.type	l_type_metadata_table,@object ; @"\01l_type_metadata_table"
	.section	swift5_type_metadata,"a",@progbits
	.p2align	2
l_type_metadata_table:
	.short	($S4main8MyStructVMn)-l_type_metadata_table
	.size	l_type_metadata_table, 2

	.hidden	__swift_reflection_version ; @__swift_reflection_version
	.type	__swift_reflection_version,@object
	.section	.rodata,"a",@progbits
	.weak	__swift_reflection_version
__swift_reflection_version:
	.short	3                       ; 0x3
	.size	__swift_reflection_version, 2

	.type	_swift1_autolink_entries,@object ; @_swift1_autolink_entries
	.section	.swift1_autolink_entries,"a",@progbits
	.p2align	1
_swift1_autolink_entries:
	.asciz	"-lavr"
	.size	_swift1_autolink_entries, 6


	.globl	$S4main8MyStructVN
	.hidden	$S4main8MyStructVN
.set $S4main8MyStructVN, ($S4main8MyStructVMf)+2
	; Declaring this symbol tells the CRT that it should
	;copy all variables from program memory to RAM on startup
	.globl	__do_copy_data
	; Declaring this symbol tells the CRT that it should
	;clear the zeroed data section on startup
	.globl	__do_clear_bss

Mostly it's working I think. It won't link at the moment due to missing runtime (swift_retain).

However, @Joe_Groff has a point, it would be really good to start figuring out how I might turn off metadata emission on this platform. Do you have any pointers where I might look first?


(John McCall) #10

Please open a PR if you'd like us to do code review. We won't merge it without your approval.


(Carl Peto) #11

@John_McCall PR created! My first. Exciting. :slight_smile: https://github.com/apple/swift/pull/20694