<div dir="ltr"><div dir="ltr">Hello Tim,<br><br>Your commit added broken tests to the builder llvm-clang-x86_64-expensive-checks-win.<br>The builder was already red and did not send notifications on this.<br>Please have a look ASAP?<br><br>Thanks<br><br>Galina<br>. . .<br>Failing Tests (4):<br>    LLVM :: CodeGen/AArch64/arm64-collect-loh.ll<br>    LLVM :: CodeGen/AArch64/arm64_32-tls.ll<br>    LLVM :: CodeGen/AArch64/arm64_32.ll<br>    . . .</div><div dir="ltr"><br></div><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 12, 2019 at 3:20 AM Tim Northover via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: tnorthover<br>
Date: Thu Sep 12 03:22:23 2019<br>
New Revision: 371722<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=371722&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=371722&view=rev</a><br>
Log:<br>
AArch64: support arm64_32, an ILP32 slice for watchOS.<br>
<br>
This is the main CodeGen patch to support the arm64_32 watchOS ABI in LLVM.<br>
FastISel is mostly disabled for now since it would generate incorrect code for<br>
ILP32.<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-addrs.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-atomics.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-fastisel.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-frame-pointers.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-gep-sink.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-memcpy.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-neon.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-null.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-pointer-extend.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-stack-pointers.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-tls.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32-va.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64_32.ll<br>
    llvm/trunk/test/CodeGen/AArch64/jump-table-32.ll<br>
    llvm/trunk/test/MC/AArch64/arm64_32-compact-unwind.s<br>
Modified:<br>
    llvm/trunk/include/llvm/CodeGen/CallingConvLower.h<br>
    llvm/trunk/include/llvm/Target/TargetCallingConv.td<br>
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
    llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp<br>
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp<br>
    llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp<br>
    llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp<br>
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp<br>
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
    llvm/trunk/lib/LTO/LTOModule.cpp<br>
    llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp<br>
    llvm/trunk/lib/MC/MCObjectFileInfo.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.h<br>
    llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td<br>
    llvm/trunk/lib/Target/AArch64/AArch64CollectLOH.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h<br>
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br>
    llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp<br>
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp<br>
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h<br>
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp<br>
    llvm/trunk/lib/Target/X86/X86FastISel.cpp<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-aapcs.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-garbage-crash.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-str.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-indexed-memory.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-stacksave.ll<br>
    llvm/trunk/test/CodeGen/AArch64/fastcc-reserved.ll<br>
    llvm/trunk/test/CodeGen/AArch64/fastcc.ll<br>
    llvm/trunk/test/CodeGen/AArch64/sibling-call.ll<br>
    llvm/trunk/test/CodeGen/AArch64/swift-return.ll<br>
    llvm/trunk/test/CodeGen/AArch64/swiftcc.ll<br>
    llvm/trunk/test/CodeGen/AArch64/swifterror.ll<br>
    llvm/trunk/test/CodeGen/AArch64/swiftself.ll<br>
    llvm/trunk/test/CodeGen/AArch64/tail-call.ll<br>
    llvm/trunk/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll<br>
    llvm/trunk/test/CodeGen/AArch64/win64_vararg.ll<br>
    llvm/trunk/utils/TableGen/CallingConvEmitter.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/CallingConvLower.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CallingConvLower.h?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CallingConvLower.h?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/CallingConvLower.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/CallingConvLower.h Thu Sep 12 03:22:23 2019<br>
@@ -44,6 +44,7 @@ public:<br>
     AExtUpper, // The value is in the upper bits of the location and should be<br>
                // extended with undefined upper bits when retrieved.<br>
     BCvt,      // The value is bit-converted in the location.<br>
+    Trunc,     // The value is truncated in the location.<br>
     VExt,      // The value is vector-widened in the location.<br>
                // FIXME: Not implemented yet. Code that uses AExt to mean<br>
                // vector-widen should be fixed to use VExt instead.<br>
<br>
Modified: llvm/trunk/include/llvm/Target/TargetCallingConv.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetCallingConv.td?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetCallingConv.td?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Target/TargetCallingConv.td (original)<br>
+++ llvm/trunk/include/llvm/Target/TargetCallingConv.td Thu Sep 12 03:22:23 2019<br>
@@ -152,6 +152,12 @@ class CCBitConvertToType<ValueType destT<br>
   ValueType DestTy = destTy;<br>
 }<br>
<br>
+/// CCTruncToType - If applied, this truncates the specified current value to<br>
+/// the specified type.<br>
+class CCTruncToType<ValueType destTy> : CCAction {<br>
+  ValueType DestTy = destTy;<br>
+}<br>
+<br>
 /// CCPassIndirect - If applied, this stores the value to stack and passes the pointer<br>
 /// as normal argument.<br>
 class CCPassIndirect<ValueType destTy> : CCAction {<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Sep 12 03:22:23 2019<br>
@@ -9867,6 +9867,10 @@ void SelectionDAGISel::LowerArguments(co<br>
           FuncInfo->setArgumentFrameIndex(&Arg, FI->getIndex());<br>
     }<br>
<br>
+    // Analyses past this point are naive and don't expect an assertion.<br>
+    if (Res.getOpcode() == ISD::AssertZext)<br>
+      Res = Res.getOperand(0);<br>
+<br>
     // Update the SwiftErrorVRegDefMap.<br>
     if (Res.getOpcode() == ISD::CopyFromReg && isSwiftErrorArg) {<br>
       unsigned Reg = cast<RegisterSDNode>(Res.getOperand(1))->getReg();<br>
<br>
Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Thu Sep 12 03:22:23 2019<br>
@@ -167,6 +167,7 @@ void TargetLoweringBase::InitLibcalls(co<br>
         setLibcallName(RTLIB::BZERO, "__bzero");<br>
       break;<br>
     case Triple::aarch64:<br>
+    case Triple::aarch64_32:<br>
       setLibcallName(RTLIB::BZERO, "bzero");<br>
       break;<br>
     default:<br>
<br>
Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thu Sep 12 03:22:23 2019<br>
@@ -155,6 +155,7 @@ void TargetLoweringObjectFileELF::Initia<br>
     break;<br>
   case Triple::aarch64:<br>
   case Triple::aarch64_be:<br>
+  case Triple::aarch64_32:<br>
     // The small model guarantees static code/data size < 4GB, but not where it<br>
     // will be in memory. Most of these could end up >2GB away so even a signed<br>
     // pc-relative 32-bit address is insufficient, theoretically.<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp Thu Sep 12 03:22:23 2019<br>
@@ -120,7 +120,8 @@ createLocalCompileCallbackManager(const<br>
     return make_error<StringError>(<br>
         std::string("No callback manager available for ") + T.str(),<br>
         inconvertibleErrorCode());<br>
-  case Triple::aarch64: {<br>
+  case Triple::aarch64:<br>
+  case Triple::aarch64_32: {<br>
     typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT;<br>
     return CCMgrT::Create(ES, ErrorHandlerAddress);<br>
     }<br>
@@ -168,6 +169,7 @@ createLocalIndirectStubsManagerBuilder(c<br>
       };<br>
<br>
     case Triple::aarch64:<br>
+    case Triple::aarch64_32:<br>
       return [](){<br>
         return std::make_unique<<br>
                        orc::LocalIndirectStubsManager<orc::OrcAArch64>>();<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp Thu Sep 12 03:22:23 2019<br>
@@ -90,6 +90,7 @@ createLocalLazyCallThroughManager(const<br>
         inconvertibleErrorCode());<br>
<br>
   case Triple::aarch64:<br>
+  case Triple::aarch64_32:<br>
     return LocalLazyCallThroughManager::Create<OrcAArch64>(ES,<br>
                                                            ErrorHandlerAddr);<br>
<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Thu Sep 12 03:22:23 2019<br>
@@ -919,7 +919,8 @@ void RuntimeDyldImpl::addRelocationForSy<br>
<br>
 uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr,<br>
                                              unsigned AbiVariant) {<br>
-  if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) {<br>
+  if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be ||<br>
+      Arch == Triple::aarch64_32) {<br>
     // This stub has to be able to access the full address space,<br>
     // since symbol lookup won't necessarily find a handy, in-range,<br>
     // PLT stub for functions which could be anywhere.<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp Thu Sep 12 03:22:23 2019<br>
@@ -357,6 +357,8 @@ RuntimeDyldMachO::create(Triple::ArchTyp<br>
     return std::make_unique<RuntimeDyldMachOARM>(MemMgr, Resolver);<br>
   case Triple::aarch64:<br>
     return std::make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver);<br>
+  case Triple::aarch64_32:<br>
+    return std::make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver);<br>
   case Triple::x86:<br>
     return std::make_unique<RuntimeDyldMachOI386>(MemMgr, Resolver);<br>
   case Triple::x86_64:<br>
<br>
Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Thu Sep 12 03:22:23 2019<br>
@@ -365,7 +365,8 @@ bool LTOCodeGenerator::determineTarget()<br>
       MCpu = "core2";<br>
     else if (Triple.getArch() == llvm::Triple::x86)<br>
       MCpu = "yonah";<br>
-    else if (Triple.getArch() == llvm::Triple::aarch64)<br>
+    else if (Triple.getArch() == llvm::Triple::aarch64 ||<br>
+             Triple.getArch() == llvm::Triple::aarch64_32)<br>
       MCpu = "cyclone";<br>
   }<br>
<br>
<br>
Modified: llvm/trunk/lib/LTO/LTOModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOModule.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOModule.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/LTOModule.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTOModule.cpp Thu Sep 12 03:22:23 2019<br>
@@ -220,7 +220,8 @@ LTOModule::makeLTOModule(MemoryBufferRef<br>
       CPU = "core2";<br>
     else if (Triple.getArch() == llvm::Triple::x86)<br>
       CPU = "yonah";<br>
-    else if (Triple.getArch() == llvm::Triple::aarch64)<br>
+    else if (Triple.getArch() == llvm::Triple::aarch64 ||<br>
+             Triple.getArch() == llvm::Triple::aarch64_32)<br>
       CPU = "cyclone";<br>
   }<br>
<br>
<br>
Modified: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp (original)<br>
+++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp Thu Sep 12 03:22:23 2019<br>
@@ -489,7 +489,8 @@ static void initTMBuilder(TargetMachineB<br>
       TMBuilder.MCpu = "core2";<br>
     else if (TheTriple.getArch() == llvm::Triple::x86)<br>
       TMBuilder.MCpu = "yonah";<br>
-    else if (TheTriple.getArch() == llvm::Triple::aarch64)<br>
+    else if (TheTriple.getArch() == llvm::Triple::aarch64 ||<br>
+             TheTriple.getArch() == llvm::Triple::aarch64_32)<br>
       TMBuilder.MCpu = "cyclone";<br>
   }<br>
   TMBuilder.TheTriple = std::move(TheTriple);<br>
<br>
Modified: llvm/trunk/lib/MC/MCObjectFileInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCObjectFileInfo.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp Thu Sep 12 03:22:23 2019<br>
@@ -28,7 +28,7 @@ static bool useCompactUnwind(const Tripl<br>
     return false;<br>
<br>
   // aarch64 always has it.<br>
-  if (T.getArch() == Triple::aarch64)<br>
+  if (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32)<br>
     return true;<br>
<br>
   // armv7k always has it.<br>
@@ -57,7 +57,8 @@ void MCObjectFileInfo::initMachOMCObject<br>
           MachO::S_ATTR_STRIP_STATIC_SYMS | MachO::S_ATTR_LIVE_SUPPORT,<br>
       SectionKind::getReadOnly());<br>
<br>
-  if (T.isOSDarwin() && T.getArch() == Triple::aarch64)<br>
+  if (T.isOSDarwin() &&<br>
+      (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32))<br>
     SupportsCompactUnwindWithoutEHFrame = true;<br>
<br>
   if (T.isWatchABI())<br>
@@ -193,7 +194,7 @@ void MCObjectFileInfo::initMachOMCObject<br>
<br>
     if (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86)<br>
       CompactUnwindDwarfEHFrameOnly = 0x04000000;  // UNWIND_X86_64_MODE_DWARF<br>
-    else if (T.getArch() == Triple::aarch64)<br>
+    else if (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32)<br>
       CompactUnwindDwarfEHFrameOnly = 0x03000000;  // UNWIND_ARM64_MODE_DWARF<br>
     else if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)<br>
       CompactUnwindDwarfEHFrameOnly = 0x04000000;  // UNWIND_ARM_MODE_DWARF<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp Thu Sep 12 03:22:23 2019<br>
@@ -1203,4 +1203,6 @@ extern "C" void LLVMInitializeAArch64Asm<br>
   RegisterAsmPrinter<AArch64AsmPrinter> X(getTheAArch64leTarget());<br>
   RegisterAsmPrinter<AArch64AsmPrinter> Y(getTheAArch64beTarget());<br>
   RegisterAsmPrinter<AArch64AsmPrinter> Z(getTheARM64Target());<br>
+  RegisterAsmPrinter<AArch64AsmPrinter> W(getTheARM64_32Target());<br>
+  RegisterAsmPrinter<AArch64AsmPrinter> V(getTheAArch64_32Target());<br>
 }<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Thu Sep 12 03:22:23 2019<br>
@@ -379,14 +379,16 @@ bool AArch64CallLowering::lowerFormalArg<br>
     return false;<br>
<br>
   if (F.isVarArg()) {<br>
-    if (!MF.getSubtarget<AArch64Subtarget>().isTargetDarwin()) {<br>
-      // FIXME: we need to reimplement saveVarArgsRegisters from<br>
+    auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();<br>
+    if (!Subtarget.isTargetDarwin()) {<br>
+        // FIXME: we need to reimplement saveVarArgsRegisters from<br>
       // AArch64ISelLowering.<br>
       return false;<br>
     }<br>
<br>
-    // We currently pass all varargs at 8-byte alignment.<br>
-    uint64_t StackOffset = alignTo(Handler.StackUsed, 8);<br>
+    // We currently pass all varargs at 8-byte alignment, or 4 in ILP32.<br>
+    uint64_t StackOffset =<br>
+        alignTo(Handler.StackUsed, Subtarget.isTargetILP32() ? 4 : 8);<br>
<br>
     auto &MFI = MIRBuilder.getMF().getFrameInfo();<br>
     AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.cpp Thu Sep 12 03:22:23 2019<br>
@@ -79,10 +79,14 @@ static bool CC_AArch64_Custom_Stack_Bloc<br>
 static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,<br>
                                     CCValAssign::LocInfo &LocInfo,<br>
                                     ISD::ArgFlagsTy &ArgFlags, CCState &State) {<br>
+  const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(<br>
+      State.getMachineFunction().getSubtarget());<br>
+  bool IsDarwinILP32 = Subtarget.isTargetILP32() && Subtarget.isTargetMachO();<br>
+<br>
   // Try to allocate a contiguous block of registers, each of the correct<br>
   // size to hold one member.<br>
   ArrayRef<MCPhysReg> RegList;<br>
-  if (LocVT.SimpleTy == MVT::i64)<br>
+  if (LocVT.SimpleTy == MVT::i64 || (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32))<br>
     RegList = XRegList;<br>
   else if (LocVT.SimpleTy == MVT::f16)<br>
     RegList = HRegList;<br>
@@ -107,8 +111,12 @@ static bool CC_AArch64_Custom_Block(unsi<br>
   if (!ArgFlags.isInConsecutiveRegsLast())<br>
     return true;<br>
<br>
-  unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());<br>
-  if (RegResult) {<br>
+  // [N x i32] arguments get packed into x-registers on Darwin's arm64_32<br>
+  // because that's how the armv7k Clang front-end emits small structs.<br>
+  unsigned EltsPerReg = (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32) ? 2 : 1;<br>
+  unsigned RegResult = State.AllocateRegBlock(<br>
+      RegList, alignTo(PendingMembers.size(), EltsPerReg) / EltsPerReg);<br>
+  if (RegResult && EltsPerReg == 1) {<br>
     for (auto &It : PendingMembers) {<br>
       It.convertToReg(RegResult);<br>
       State.addLoc(It);<br>
@@ -116,14 +124,26 @@ static bool CC_AArch64_Custom_Block(unsi<br>
     }<br>
     PendingMembers.clear();<br>
     return true;<br>
+  } else if (RegResult) {<br>
+    assert(EltsPerReg == 2 && "unexpected ABI");<br>
+    bool UseHigh = false;<br>
+    CCValAssign::LocInfo Info;<br>
+    for (auto &It : PendingMembers) {<br>
+      Info = UseHigh ? CCValAssign::AExtUpper : CCValAssign::ZExt;<br>
+      State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32, RegResult,<br>
+                                       MVT::i64, Info));<br>
+      UseHigh = !UseHigh;<br>
+      if (!UseHigh)<br>
+        ++RegResult;<br>
+    }<br>
+    PendingMembers.clear();<br>
+    return true;<br>
   }<br>
<br>
   // Mark all regs in the class as unavailable<br>
   for (auto Reg : RegList)<br>
     State.AllocateReg(Reg);<br>
<br>
-  const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(<br>
-      State.getMachineFunction().getSubtarget());<br>
   unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8;<br>
<br>
   return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.h?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.h?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.h (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.h Thu Sep 12 03:22:23 2019<br>
@@ -25,6 +25,9 @@ bool CC_AArch64_DarwinPCS_VarArg(unsigne<br>
 bool CC_AArch64_DarwinPCS(unsigned ValNo, MVT ValVT, MVT LocVT,<br>
                           CCValAssign::LocInfo LocInfo,<br>
                           ISD::ArgFlagsTy ArgFlags, CCState &State);<br>
+bool CC_AArch64_DarwinPCS_ILP32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,<br>
+                          CCValAssign::LocInfo LocInfo,<br>
+                          ISD::ArgFlagsTy ArgFlags, CCState &State);<br>
 bool CC_AArch64_Win64_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,<br>
                              CCValAssign::LocInfo LocInfo,<br>
                              ISD::ArgFlagsTy ArgFlags, CCState &State);<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td Thu Sep 12 03:22:23 2019<br>
@@ -17,6 +17,10 @@ class CCIfAlign<string Align, CCAction A<br>
 class CCIfBigEndian<CCAction A> :<br>
   CCIf<"State.getMachineFunction().getDataLayout().isBigEndian()", A>;<br>
<br>
+class CCIfILP32<CCAction A> :<br>
+  CCIf<"State.getMachineFunction().getDataLayout().getPointerSize() == 4", A>;<br>
+<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // ARM AAPCS64 Calling Convention<br>
 //===----------------------------------------------------------------------===//<br>
@@ -123,6 +127,7 @@ def RetCC_AArch64_AAPCS : CallingConv<[<br>
   CCIfType<[v2f32], CCBitConvertToType<v2i32>>,<br>
   CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,<br>
<br>
+  CCIfConsecutiveRegs<CCCustom<"CC_AArch64_Custom_Block">>,<br>
   CCIfSwiftError<CCIfType<[i64], CCAssignToRegWithShadow<[X21], [W21]>>>,<br>
<br>
   // Big endian vectors must be passed as if they were 1-element vectors so that<br>
@@ -221,6 +226,12 @@ def CC_AArch64_DarwinPCS : CallingConv<[<br>
   CCIf<"ValVT == MVT::i1 || ValVT == MVT::i8", CCAssignToStack<1, 1>>,<br>
   CCIf<"ValVT == MVT::i16 || ValVT == MVT::f16", CCAssignToStack<2, 2>>,<br>
   CCIfType<[i32, f32], CCAssignToStack<4, 4>>,<br>
+<br>
+  // Re-demote pointers to 32-bits so we don't end up storing 64-bit<br>
+  // values and clobbering neighbouring stack locations. Not very pretty.<br>
+  CCIfPtr<CCIfILP32<CCTruncToType<i32>>>,<br>
+  CCIfPtr<CCIfILP32<CCAssignToStack<4, 4>>>,<br>
+<br>
   CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8, v4f16],<br>
            CCAssignToStack<8, 8>>,<br>
   CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64, v8f16],<br>
@@ -248,6 +259,29 @@ def CC_AArch64_DarwinPCS_VarArg : Callin<br>
            CCAssignToStack<16, 16>><br>
 ]>;<br>
<br>
+// In the ILP32 world, the minimum stack slot size is 4 bytes. Otherwise the<br>
+// same as the normal Darwin VarArgs handling.<br>
+let Entry = 1 in<br>
+def CC_AArch64_DarwinPCS_ILP32_VarArg : CallingConv<[<br>
+  CCIfType<[v2f32], CCBitConvertToType<v2i32>>,<br>
+  CCIfType<[v2f64, v4f32, f128], CCBitConvertToType<v2i64>>,<br>
+<br>
+  // Handle all scalar types as either i32 or f32.<br>
+  CCIfType<[i8, i16], CCPromoteToType<i32>>,<br>
+  CCIfType<[f16],     CCPromoteToType<f32>>,<br>
+<br>
+  // Everything is on the stack.<br>
+  // i128 is split to two i64s, and its stack alignment is 16 bytes.<br>
+  CCIfPtr<CCIfILP32<CCTruncToType<i32>>>,<br>
+  CCIfType<[i32, f32], CCAssignToStack<4, 4>>,<br>
+  CCIfType<[i64], CCIfSplit<CCAssignToStack<8, 16>>>,<br>
+  CCIfType<[i64, f64, v1i64, v2i32, v4i16, v8i8, v1f64, v2f32, v4f16],<br>
+           CCAssignToStack<8, 8>>,<br>
+  CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64, v8f16],<br>
+           CCAssignToStack<16, 16>><br>
+]>;<br>
+<br>
+<br>
 // The WebKit_JS calling convention only passes the first argument (the callee)<br>
 // in register and the remaining arguments on stack. We allow 32bit stack slots,<br>
 // so that WebKit can write partial values in the stack and define the other<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64CollectLOH.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CollectLOH.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CollectLOH.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64CollectLOH.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64CollectLOH.cpp Thu Sep 12 03:22:23 2019<br>
@@ -103,6 +103,7 @@<br>
 #include "llvm/ADT/BitVector.h"<br>
 #include "llvm/ADT/DenseMap.h"<br>
 #include "llvm/ADT/MapVector.h"<br>
+#include "llvm/ADT/SmallSet.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
 #include "llvm/ADT/Statistic.h"<br>
 #include "llvm/CodeGen/MachineBasicBlock.h"<br>
@@ -181,6 +182,7 @@ static bool canDefBePartOfLOH(const Mach<br>
   case AArch64::ADDXri:<br>
     return canAddBePartOfLOH(MI);<br>
   case AArch64::LDRXui:<br>
+  case AArch64::LDRWui:<br>
     // Check immediate to see if the immediate is an address.<br>
     switch (MI.getOperand(2).getType()) {<br>
     default:<br>
@@ -312,7 +314,8 @@ static void handleUse(const MachineInstr<br>
     Info.Type = MCLOH_AdrpAdd;<br>
     Info.IsCandidate = true;<br>
     Info.MI0 = &MI;<br>
-  } else if (MI.getOpcode() == AArch64::LDRXui &&<br>
+  } else if ((MI.getOpcode() == AArch64::LDRXui ||<br>
+              MI.getOpcode() == AArch64::LDRWui) &&<br>
              MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT) {<br>
     Info.Type = MCLOH_AdrpLdrGot;<br>
     Info.IsCandidate = true;<br>
@@ -357,7 +360,9 @@ static bool handleMiddleInst(const Machi<br>
       return true;<br>
     }<br>
   } else {<br>
-    assert(MI.getOpcode() == AArch64::LDRXui && "Expect LDRXui");<br>
+    assert((MI.getOpcode() == AArch64::LDRXui ||<br>
+            MI.getOpcode() == AArch64::LDRWui) &&<br>
+           "Expect LDRXui or LDRWui");<br>
     assert((MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT) &&<br>
            "Expected GOT relocation");<br>
     if (OpInfo.Type == MCLOH_AdrpAddStr && OpInfo.MI1 == nullptr) {<br>
@@ -474,13 +479,23 @@ static void handleNormalInst(const Machi<br>
     handleClobber(LOHInfos[Idx]);<br>
   }<br>
   // Handle uses.<br>
+<br>
+  SmallSet<int, 4> UsesSeen;<br>
   for (const MachineOperand &MO : MI.uses()) {<br>
     if (!MO.isReg() || !MO.readsReg())<br>
       continue;<br>
     int Idx = mapRegToGPRIndex(MO.getReg());<br>
     if (Idx < 0)<br>
       continue;<br>
-    handleUse(MI, MO, LOHInfos[Idx]);<br>
+<br>
+    // Multiple uses of the same register within a single instruction don't<br>
+    // count as MultiUser or block optimization. This is especially important on<br>
+    // arm64_32, where any memory operation is likely to be an explicit use of<br>
+    // xN and an implicit use of wN (the base address register).<br>
+    if (!UsesSeen.count(Idx)) {<br>
+      handleUse(MI, MO, LOHInfos[Idx]);<br>
+      UsesSeen.insert(Idx);<br>
+    }<br>
   }<br>
 }<br>
<br>
@@ -512,6 +527,7 @@ bool AArch64CollectLOH::runOnMachineFunc<br>
       switch (Opcode) {<br>
       case AArch64::ADDXri:<br>
       case AArch64::LDRXui:<br>
+      case AArch64::LDRWui:<br>
         if (canDefBePartOfLOH(MI)) {<br>
           const MachineOperand &Def = MI.getOperand(0);<br>
           const MachineOperand &Op = MI.getOperand(1);<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp Thu Sep 12 03:22:23 2019<br>
@@ -495,12 +495,26 @@ bool AArch64ExpandPseudo::expandMI(Machi<br>
       }<br>
     } else {<br>
       // Small codemodel expand into ADRP + LDR.<br>
+      MachineFunction &MF = *MI.getParent()->getParent();<br>
+      DebugLoc DL = MI.getDebugLoc();<br>
       MachineInstrBuilder MIB1 =<br>
           BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg);<br>
-      MachineInstrBuilder MIB2 =<br>
-          BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::LDRXui))<br>
-              .add(MI.getOperand(0))<br>
-              .addReg(DstReg);<br>
+<br>
+      MachineInstrBuilder MIB2;<br>
+      if (MF.getSubtarget<AArch64Subtarget>().isTargetILP32()) {<br>
+        auto TRI = MBB.getParent()->getSubtarget().getRegisterInfo();<br>
+        unsigned Reg32 = TRI->getSubReg(DstReg, AArch64::sub_32);<br>
+        unsigned DstFlags = MI.getOperand(0).getTargetFlags();<br>
+        MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::LDRWui))<br>
+                   .addDef(Reg32, RegState::Dead)<br>
+                   .addReg(DstReg, RegState::Kill)<br>
+                   .addReg(DstReg, DstFlags | RegState::Implicit);<br>
+      } else {<br>
+        unsigned DstReg = MI.getOperand(0).getReg();<br>
+        MIB2 = BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXui))<br>
+                   .add(MI.getOperand(0))<br>
+                   .addUse(DstReg, RegState::Kill);<br>
+      }<br>
<br>
       if (MO1.isGlobal()) {<br>
         MIB1.addGlobalAddress(MO1.getGlobal(), 0, Flags | AArch64II::MO_PAGE);<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Thu Sep 12 03:22:23 2019<br>
@@ -474,12 +474,32 @@ unsigned AArch64FastISel::materializeGV(<br>
             ADRPReg)<br>
         .addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);<br>
<br>
-    ResultReg = createResultReg(&AArch64::GPR64RegClass);<br>
-    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::LDRXui),<br>
+    unsigned LdrOpc;<br>
+    if (Subtarget->isTargetILP32()) {<br>
+      ResultReg = createResultReg(&AArch64::GPR32RegClass);<br>
+      LdrOpc = AArch64::LDRWui;<br>
+    } else {<br>
+      ResultReg = createResultReg(&AArch64::GPR64RegClass);<br>
+      LdrOpc = AArch64::LDRXui;<br>
+    }<br>
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(LdrOpc),<br>
             ResultReg)<br>
-        .addReg(ADRPReg)<br>
-        .addGlobalAddress(GV, 0,<br>
-                          AArch64II::MO_PAGEOFF | AArch64II::MO_NC | OpFlags);<br>
+      .addReg(ADRPReg)<br>
+      .addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF |<br>
+                        AArch64II::MO_NC | OpFlags);<br>
+    if (!Subtarget->isTargetILP32())<br>
+      return ResultReg;<br>
+<br>
+    // LDRWui produces a 32-bit register, but pointers in-register are 64-bits<br>
+    // so we must extend the result on ILP32.<br>
+    unsigned Result64 = createResultReg(&AArch64::GPR64RegClass);<br>
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,<br>
+            TII.get(TargetOpcode::SUBREG_TO_REG))<br>
+        .addDef(Result64)<br>
+        .addImm(0)<br>
+        .addReg(ResultReg, RegState::Kill)<br>
+        .addImm(AArch64::sub_32);<br>
+    return Result64;<br>
   } else {<br>
     // ADRP + ADDX<br>
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),<br>
@@ -504,6 +524,15 @@ unsigned AArch64FastISel::fastMaterializ<br>
   if (!CEVT.isSimple())<br>
     return 0;<br>
   MVT VT = CEVT.getSimpleVT();<br>
+  // arm64_32 has 32-bit pointers held in 64-bit registers. Because of that,<br>
+  // 'null' pointers need to have a somewhat special treatment.<br>
+  if (const auto *CPN = dyn_cast<ConstantPointerNull>(C)) {<br>
+    (void)CPN;<br>
+    assert(CPN->getType()->getPointerAddressSpace() == 0 &&<br>
+           "Unexpected address space");<br>
+    assert(VT == MVT::i64 && "Expected 64-bit pointers");<br>
+    return materializeInt(ConstantInt::get(Type::getInt64Ty(*Context), 0), VT);<br>
+  }<br>
<br>
   if (const auto *CI = dyn_cast<ConstantInt>(C))<br>
     return materializeInt(CI, VT);<br>
@@ -946,6 +975,9 @@ bool AArch64FastISel::computeCallAddress<br>
 bool AArch64FastISel::isTypeLegal(Type *Ty, MVT &VT) {<br>
   EVT evt = TLI.getValueType(DL, Ty, true);<br>
<br>
+  if (Subtarget->isTargetILP32() && Ty->isPointerTy())<br>
+    return false;<br>
+<br>
   // Only handle simple types.<br>
   if (evt == MVT::Other || !evt.isSimple())<br>
     return false;<br>
@@ -988,6 +1020,9 @@ bool AArch64FastISel::isValueAvailable(c<br>
 }<br>
<br>
 bool AArch64FastISel::simplifyAddress(Address &Addr, MVT VT) {<br>
+  if (Subtarget->isTargetILP32())<br>
+    return false;<br>
+<br>
   unsigned ScaleFactor = getImplicitScaleFactor(VT);<br>
   if (!ScaleFactor)<br>
     return false;<br>
@@ -3165,6 +3200,11 @@ bool AArch64FastISel::fastLowerCall(Call<br>
   if (IsTailCall)<br>
     return false;<br>
<br>
+  // FIXME: we could and should support this, but for now correctness at -O0 is<br>
+  // more important.<br>
+  if (Subtarget->isTargetILP32())<br>
+    return false;<br>
+<br>
   CodeModel::Model CM = TM.getCodeModel();<br>
   // Only support the small-addressing and large code models.<br>
   if (CM != CodeModel::Large && !Subtarget->useSmallAddressing())<br>
@@ -3796,6 +3836,11 @@ bool AArch64FastISel::selectRet(const In<br>
   if (!FuncInfo.CanLowerReturn)<br>
     return false;<br>
<br>
+  // FIXME: in principle it could. Mostly just a case of zero extending outgoing<br>
+  // pointers.<br>
+  if (Subtarget->isTargetILP32())<br>
+    return false;<br>
+<br>
   if (F.isVarArg())<br>
     return false;<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Thu Sep 12 03:22:23 2019<br>
@@ -23,6 +23,7 @@<br>
 #include "llvm/ADT/APInt.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/STLExtras.h"<br>
+#include "llvm/ADT/SmallSet.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
 #include "llvm/ADT/Statistic.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
@@ -1053,6 +1054,14 @@ void AArch64TargetLowering::computeKnown<br>
     Known.One &= Known2.One;<br>
     break;<br>
   }<br>
+  case AArch64ISD::LOADgot:<br>
+  case AArch64ISD::ADDlow: {<br>
+    if (!Subtarget->isTargetILP32())<br>
+      break;<br>
+    // In ILP32 mode all valid pointers are in the low 4GB of the address-space.<br>
+    Known.Zero = APInt::getHighBitsSet(64, 32);<br>
+    break;<br>
+  }<br>
   case ISD::INTRINSIC_W_CHAIN: {<br>
     ConstantSDNode *CN = cast<ConstantSDNode>(Op->getOperand(1));<br>
     Intrinsic::ID IntID = static_cast<Intrinsic::ID>(CN->getZExtValue());<br>
@@ -3071,8 +3080,11 @@ CCAssignFn *AArch64TargetLowering::CCAss<br>
       return CC_AArch64_Win64_VarArg;<br>
     if (!Subtarget->isTargetDarwin())<br>
       return CC_AArch64_AAPCS;<br>
-    return IsVarArg ? CC_AArch64_DarwinPCS_VarArg : CC_AArch64_DarwinPCS;<br>
-  case CallingConv::Win64:<br>
+    if (!IsVarArg)<br>
+      return CC_AArch64_DarwinPCS;<br>
+    return Subtarget->isTargetILP32() ? CC_AArch64_DarwinPCS_ILP32_VarArg<br>
+                                      : CC_AArch64_DarwinPCS_VarArg;<br>
+   case CallingConv::Win64:<br>
     return IsVarArg ? CC_AArch64_Win64_VarArg : CC_AArch64_AAPCS;<br>
   case CallingConv::AArch64_VectorCall:<br>
     return CC_AArch64_AAPCS;<br>
@@ -3095,6 +3107,7 @@ SDValue AArch64TargetLowering::LowerForm<br>
<br>
   // Assign locations to all of the incoming arguments.<br>
   SmallVector<CCValAssign, 16> ArgLocs;<br>
+  DenseMap<unsigned, SDValue> CopiedRegs;<br>
   CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,<br>
                  *DAG.getContext());<br>
<br>
@@ -3151,11 +3164,10 @@ SDValue AArch64TargetLowering::LowerForm<br>
       continue;<br>
     }<br>
<br>
+    SDValue ArgValue;<br>
     if (VA.isRegLoc()) {<br>
       // Arguments stored in registers.<br>
       EVT RegVT = VA.getLocVT();<br>
-<br>
-      SDValue ArgValue;<br>
       const TargetRegisterClass *RC;<br>
<br>
       if (RegVT == MVT::i32)<br>
@@ -3200,14 +3212,13 @@ SDValue AArch64TargetLowering::LowerForm<br>
       case CCValAssign::AExt:<br>
       case CCValAssign::SExt:<br>
       case CCValAssign::ZExt:<br>
-        // SelectionDAGBuilder will insert appropriate AssertZExt & AssertSExt<br>
-        // nodes after our lowering.<br>
-        assert(RegVT == Ins[i].VT && "incorrect register location selected");<br>
+        break;<br>
+      case CCValAssign::AExtUpper:<br>
+        ArgValue = DAG.getNode(ISD::SRL, DL, RegVT, ArgValue,<br>
+                               DAG.getConstant(32, DL, RegVT));<br>
+        ArgValue = DAG.getZExtOrTrunc(ArgValue, DL, VA.getValVT());<br>
         break;<br>
       }<br>
-<br>
-      InVals.push_back(ArgValue);<br>
-<br>
     } else { // VA.isRegLoc()<br>
       assert(VA.isMemLoc() && "CCValAssign is neither reg nor mem");<br>
       unsigned ArgOffset = VA.getLocMemOffset();<br>
@@ -3222,7 +3233,6 @@ SDValue AArch64TargetLowering::LowerForm<br>
<br>
       // Create load nodes to retrieve arguments from the stack.<br>
       SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));<br>
-      SDValue ArgValue;<br>
<br>
       // For NON_EXTLOAD, generic code in getLoad assert(ValVT == MemVT)<br>
       ISD::LoadExtType ExtType = ISD::NON_EXTLOAD;<br>
@@ -3231,6 +3241,7 @@ SDValue AArch64TargetLowering::LowerForm<br>
       switch (VA.getLocInfo()) {<br>
       default:<br>
         break;<br>
+      case CCValAssign::Trunc:<br>
       case CCValAssign::BCvt:<br>
         MemVT = VA.getLocVT();<br>
         break;<br>
@@ -3254,8 +3265,11 @@ SDValue AArch64TargetLowering::LowerForm<br>
           MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI),<br>
           MemVT);<br>
<br>
-      InVals.push_back(ArgValue);<br>
     }<br>
+    if (Subtarget->isTargetILP32() && Ins[i].Flags.isPointer())<br>
+      ArgValue = DAG.getNode(ISD::AssertZext, DL, ArgValue.getValueType(),<br>
+                             ArgValue, DAG.getValueType(MVT::i32));<br>
+    InVals.push_back(ArgValue);<br>
   }<br>
<br>
   // varargs<br>
@@ -3272,8 +3286,8 @@ SDValue AArch64TargetLowering::LowerForm<br>
<br>
     // This will point to the next argument passed via stack.<br>
     unsigned StackOffset = CCInfo.getNextStackOffset();<br>
-    // We currently pass all varargs at 8-byte alignment.<br>
-    StackOffset = ((StackOffset + 7) & ~7);<br>
+    // We currently pass all varargs at 8-byte alignment, or 4 for ILP32<br>
+    StackOffset = alignTo(StackOffset, Subtarget->isTargetILP32() ? 4 : 8);<br>
     FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackOffset, true));<br>
<br>
     if (MFI.hasMustTailInVarArgFunc()) {<br>
@@ -3436,6 +3450,7 @@ SDValue AArch64TargetLowering::LowerCall<br>
                           : RetCC_AArch64_AAPCS;<br>
   // Assign locations to each value returned by this call.<br>
   SmallVector<CCValAssign, 16> RVLocs;<br>
+  DenseMap<unsigned, SDValue> CopiedRegs;<br>
   CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,<br>
                  *DAG.getContext());<br>
   CCInfo.AnalyzeCallResult(Ins, RetCC);<br>
@@ -3453,10 +3468,16 @@ SDValue AArch64TargetLowering::LowerCall<br>
       continue;<br>
     }<br>
<br>
-    SDValue Val =<br>
-        DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), InFlag);<br>
-    Chain = Val.getValue(1);<br>
-    InFlag = Val.getValue(2);<br>
+    // Avoid copying a physreg twice since RegAllocFast is incompetent and only<br>
+    // allows one use of a physreg per block.<br>
+    SDValue Val = CopiedRegs.lookup(VA.getLocReg());<br>
+    if (!Val) {<br>
+      Val =<br>
+          DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), InFlag);<br>
+      Chain = Val.getValue(1);<br>
+      InFlag = Val.getValue(2);<br>
+      CopiedRegs[VA.getLocReg()] = Val;<br>
+    }<br>
<br>
     switch (VA.getLocInfo()) {<br>
     default:<br>
@@ -3466,6 +3487,15 @@ SDValue AArch64TargetLowering::LowerCall<br>
     case CCValAssign::BCvt:<br>
       Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);<br>
       break;<br>
+    case CCValAssign::AExtUpper:<br>
+      Val = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Val,<br>
+                        DAG.getConstant(32, DL, VA.getLocVT()));<br>
+      LLVM_FALLTHROUGH;<br>
+    case CCValAssign::AExt:<br>
+      LLVM_FALLTHROUGH;<br>
+    case CCValAssign::ZExt:<br>
+      Val = DAG.getZExtOrTrunc(Val, DL, VA.getValVT());<br>
+      break;<br>
     }<br>
<br>
     InVals.push_back(Val);<br>
@@ -3779,6 +3809,7 @@ AArch64TargetLowering::LowerCall(CallLow<br>
                                         getPointerTy(DAG.getDataLayout()));<br>
<br>
   SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;<br>
+  SmallSet<unsigned, 8> RegsUsed;<br>
   SmallVector<SDValue, 8> MemOpChains;<br>
   auto PtrVT = getPointerTy(DAG.getDataLayout());<br>
<br>
@@ -3786,7 +3817,7 @@ AArch64TargetLowering::LowerCall(CallLow<br>
     const auto &Forwards = FuncInfo->getForwardedMustTailRegParms();<br>
     for (const auto &F : Forwards) {<br>
       SDValue Val = DAG.getCopyFromReg(Chain, DL, F.VReg, F.VT);<br>
-       RegsToPass.push_back(std::make_pair(unsigned(F.PReg), Val));<br>
+       RegsToPass.emplace_back(F.PReg, Val);<br>
     }<br>
   }<br>
<br>
@@ -3817,8 +3848,17 @@ AArch64TargetLowering::LowerCall(CallLow<br>
       }<br>
       Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);<br>
       break;<br>
+    case CCValAssign::AExtUpper:<br>
+      assert(VA.getValVT() == MVT::i32 && "only expect 32 -> 64 upper bits");<br>
+      Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);<br>
+      Arg = DAG.getNode(ISD::SHL, DL, VA.getLocVT(), Arg,<br>
+                        DAG.getConstant(32, DL, VA.getLocVT()));<br>
+      break;<br>
     case CCValAssign::BCvt:<br>
-      Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);<br>
+      Arg = DAG.getBitcast(VA.getLocVT(), Arg);<br>
+      break;<br>
+    case CCValAssign::Trunc:<br>
+      Arg = DAG.getZExtOrTrunc(Arg, DL, VA.getLocVT());<br>
       break;<br>
     case CCValAssign::FPExt:<br>
       Arg = DAG.getNode(ISD::FP_EXTEND, DL, VA.getLocVT(), Arg);<br>
@@ -3838,7 +3878,22 @@ AArch64TargetLowering::LowerCall(CallLow<br>
                "unexpected use of 'returned'");<br>
         IsThisReturn = true;<br>
       }<br>
-      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));<br>
+      if (RegsUsed.count(VA.getLocReg())) {<br>
+        // If this register has already been used then we're trying to pack<br>
+        // parts of an [N x i32] into an X-register. The extension type will<br>
+        // take care of putting the two halves in the right place but we have to<br>
+        // combine them.<br>
+        SDValue &Bits =<br>
+            std::find_if(RegsToPass.begin(), RegsToPass.end(),<br>
+                         [=](const std::pair<unsigned, SDValue> &Elt) {<br>
+                           return Elt.first == VA.getLocReg();<br>
+                         })<br>
+                ->second;<br>
+        Bits = DAG.getNode(ISD::OR, DL, Bits.getValueType(), Bits, Arg);<br>
+      } else {<br>
+        RegsToPass.emplace_back(VA.getLocReg(), Arg);<br>
+        RegsUsed.insert(VA.getLocReg());<br>
+      }<br>
     } else {<br>
       assert(VA.isMemLoc());<br>
<br>
@@ -4071,7 +4126,8 @@ AArch64TargetLowering::LowerReturn(SDVal<br>
<br>
   // Copy the result values into the output registers.<br>
   SDValue Flag;<br>
-  SmallVector<SDValue, 4> RetOps(1, Chain);<br>
+  SmallVector<std::pair<unsigned, SDValue>, 4> RetVals;<br>
+  SmallSet<unsigned, 4> RegsUsed;<br>
   for (unsigned i = 0, realRVLocIdx = 0; i != RVLocs.size();<br>
        ++i, ++realRVLocIdx) {<br>
     CCValAssign &VA = RVLocs[i];<br>
@@ -4093,11 +4149,38 @@ AArch64TargetLowering::LowerReturn(SDVal<br>
     case CCValAssign::BCvt:<br>
       Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);<br>
       break;<br>
+    case CCValAssign::AExt:<br>
+    case CCValAssign::ZExt:<br>
+      Arg = DAG.getZExtOrTrunc(Arg, DL, VA.getLocVT());<br>
+      break;<br>
+    case CCValAssign::AExtUpper:<br>
+      assert(VA.getValVT() == MVT::i32 && "only expect 32 -> 64 upper bits");<br>
+      Arg = DAG.getZExtOrTrunc(Arg, DL, VA.getLocVT());<br>
+      Arg = DAG.getNode(ISD::SHL, DL, VA.getLocVT(), Arg,<br>
+                        DAG.getConstant(32, DL, VA.getLocVT()));<br>
+      break;<br>
     }<br>
<br>
-    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Arg, Flag);<br>
+    if (RegsUsed.count(VA.getLocReg())) {<br>
+      SDValue &Bits =<br>
+          std::find_if(RetVals.begin(), RetVals.end(),<br>
+                       [=](const std::pair<unsigned, SDValue> &Elt) {<br>
+                         return Elt.first == VA.getLocReg();<br>
+                       })<br>
+              ->second;<br>
+      Bits = DAG.getNode(ISD::OR, DL, Bits.getValueType(), Bits, Arg);<br>
+    } else {<br>
+      RetVals.emplace_back(VA.getLocReg(), Arg);<br>
+      RegsUsed.insert(VA.getLocReg());<br>
+    }<br>
+  }<br>
+<br>
+  SmallVector<SDValue, 4> RetOps(1, Chain);<br>
+  for (auto &RetVal : RetVals) {<br>
+    Chain = DAG.getCopyToReg(Chain, DL, RetVal.first, RetVal.second, Flag);<br>
     Flag = Chain.getValue(1);<br>
-    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));<br>
+    RetOps.push_back(<br>
+        DAG.getRegister(RetVal.first, RetVal.second.getValueType()));<br>
   }<br>
<br>
   // Windows AArch64 ABIs require that for returning structs by value we copy<br>
@@ -4291,6 +4374,7 @@ AArch64TargetLowering::LowerDarwinGlobal<br>
<br>
   SDLoc DL(Op);<br>
   MVT PtrVT = getPointerTy(DAG.getDataLayout());<br>
+  MVT PtrMemVT = getPointerMemTy(DAG.getDataLayout());<br>
   const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();<br>
<br>
   SDValue TLVPAddr =<br>
@@ -4301,12 +4385,15 @@ AArch64TargetLowering::LowerDarwinGlobal<br>
   // to obtain the address of the variable.<br>
   SDValue Chain = DAG.getEntryNode();<br>
   SDValue FuncTLVGet = DAG.getLoad(<br>
-      MVT::i64, DL, Chain, DescAddr,<br>
+      PtrMemVT, DL, Chain, DescAddr,<br>
       MachinePointerInfo::getGOT(DAG.getMachineFunction()),<br>
-      /* Alignment = */ 8,<br>
+      /* Alignment = */ PtrMemVT.getSizeInBits() / 8,<br>
       MachineMemOperand::MOInvariant | MachineMemOperand::MODereferenceable);<br>
   Chain = FuncTLVGet.getValue(1);<br>
<br>
+  // Extend loaded pointer if necessary (i.e. if ILP32) to DAG pointer.<br>
+  FuncTLVGet = DAG.getZExtOrTrunc(FuncTLVGet, DL, PtrVT);<br>
+<br>
   MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();<br>
   MFI.setAdjustsStack(true);<br>
<br>
@@ -5182,6 +5269,7 @@ SDValue AArch64TargetLowering::LowerDarw<br>
   SDLoc DL(Op);<br>
   SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsStackIndex(),<br>
                                  getPointerTy(DAG.getDataLayout()));<br>
+  FR = DAG.getZExtOrTrunc(FR, DL, getPointerMemTy(DAG.getDataLayout()));<br>
   const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();<br>
   return DAG.getStore(Op.getOperand(0), DL, FR, Op.getOperand(1),<br>
                       MachinePointerInfo(SV));<br>
@@ -5288,15 +5376,15 @@ SDValue AArch64TargetLowering::LowerVACO<br>
   // AAPCS has three pointers and two ints (= 32 bytes), Darwin has single<br>
   // pointer.<br>
   SDLoc DL(Op);<br>
-  unsigned VaListSize =<br>
-      Subtarget->isTargetDarwin() || Subtarget->isTargetWindows() ? 8 : 32;<br>
+  unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8;<br>
+  unsigned VaListSize = (Subtarget->isTargetDarwin() ||<br>
+                         Subtarget->isTargetWindows()) ? PtrSize : 32;<br>
   const Value *DestSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();<br>
   const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();<br>
<br>
-  return DAG.getMemcpy(Op.getOperand(0), DL, Op.getOperand(1),<br>
-                       Op.getOperand(2),<br>
-                       DAG.getConstant(VaListSize, DL, MVT::i32),<br>
-                       8, false, false, false, MachinePointerInfo(DestSV),<br>
+  return DAG.getMemcpy(Op.getOperand(0), DL, Op.getOperand(1), Op.getOperand(2),<br>
+                       DAG.getConstant(VaListSize, DL, MVT::i32), PtrSize,<br>
+                       false, false, false, MachinePointerInfo(DestSV),<br>
                        MachinePointerInfo(SrcSV));<br>
 }<br>
<br>
@@ -5310,12 +5398,15 @@ SDValue AArch64TargetLowering::LowerVAAR<br>
   SDValue Chain = Op.getOperand(0);<br>
   SDValue Addr = Op.getOperand(1);<br>
   unsigned Align = Op.getConstantOperandVal(3);<br>
+  unsigned MinSlotSize = Subtarget->isTargetILP32() ? 4 : 8;<br>
   auto PtrVT = getPointerTy(DAG.getDataLayout());<br>
-<br>
-  SDValue VAList = DAG.getLoad(PtrVT, DL, Chain, Addr, MachinePointerInfo(V));<br>
+  auto PtrMemVT = getPointerMemTy(DAG.getDataLayout());<br>
+  SDValue VAList =<br>
+      DAG.getLoad(PtrMemVT, DL, Chain, Addr, MachinePointerInfo(V));<br>
   Chain = VAList.getValue(1);<br>
+  VAList = DAG.getZExtOrTrunc(VAList, DL, PtrVT);<br>
<br>
-  if (Align > 8) {<br>
+  if (Align > MinSlotSize) {<br>
     assert(((Align & (Align - 1)) == 0) && "Expected Align to be a power of 2");<br>
     VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,<br>
                          DAG.getConstant(Align - 1, DL, PtrVT));<br>
@@ -5324,14 +5415,14 @@ SDValue AArch64TargetLowering::LowerVAAR<br>
   }<br>
<br>
   Type *ArgTy = VT.getTypeForEVT(*DAG.getContext());<br>
-  uint64_t ArgSize = DAG.getDataLayout().getTypeAllocSize(ArgTy);<br>
+  unsigned ArgSize = DAG.getDataLayout().getTypeAllocSize(ArgTy);<br>
<br>
   // Scalar integer and FP values smaller than 64 bits are implicitly extended<br>
   // up to 64 bits.  At the very least, we have to increase the striding of the<br>
   // vaargs list to match this, and for FP values we need to introduce<br>
   // FP_ROUND nodes as well.<br>
   if (VT.isInteger() && !VT.isVector())<br>
-    ArgSize = 8;<br>
+    ArgSize = std::max(ArgSize, MinSlotSize);<br>
   bool NeedFPTrunc = false;<br>
   if (VT.isFloatingPoint() && !VT.isVector() && VT != MVT::f64) {<br>
     ArgSize = 8;<br>
@@ -5341,6 +5432,8 @@ SDValue AArch64TargetLowering::LowerVAAR<br>
   // Increment the pointer, VAList, to the next vaarg<br>
   SDValue VANext = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,<br>
                                DAG.getConstant(ArgSize, DL, PtrVT));<br>
+  VANext = DAG.getZExtOrTrunc(VANext, DL, PtrMemVT);<br>
+<br>
   // Store the incremented VAList to the legalized pointer<br>
   SDValue APStore =<br>
       DAG.getStore(Chain, DL, VANext, Addr, MachinePointerInfo(V));<br>
@@ -5370,10 +5463,15 @@ SDValue AArch64TargetLowering::LowerFRAM<br>
   SDLoc DL(Op);<br>
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();<br>
   SDValue FrameAddr =<br>
-      DAG.getCopyFromReg(DAG.getEntryNode(), DL, AArch64::FP, VT);<br>
+      DAG.getCopyFromReg(DAG.getEntryNode(), DL, AArch64::FP, MVT::i64);<br>
   while (Depth--)<br>
     FrameAddr = DAG.getLoad(VT, DL, DAG.getEntryNode(), FrameAddr,<br>
                             MachinePointerInfo());<br>
+<br>
+  if (Subtarget->isTargetILP32())<br>
+    FrameAddr = DAG.getNode(ISD::AssertZext, DL, MVT::i64, FrameAddr,<br>
+                            DAG.getValueType(VT));<br>
+<br>
   return FrameAddr;<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h Thu Sep 12 03:22:23 2019<br>
@@ -261,6 +261,14 @@ public:<br>
                                      const SelectionDAG &DAG,<br>
                                      unsigned Depth = 0) const override;<br>
<br>
+  MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override {<br>
+    // Returning i64 unconditionally here (i.e. even for ILP32) means that the<br>
+    // *DAG* representation of pointers will always be 64-bits. They will be<br>
+    // truncated and extended when transferred to memory, but the 64-bit DAG<br>
+    // allows us to use AArch64's addressing modes much more easily.<br>
+    return MVT::getIntegerVT(64);<br>
+  }<br>
+<br>
   bool targetShrinkDemandedConstant(SDValue Op, const APInt &Demanded,<br>
                                     TargetLoweringOpt &TLO) const override;<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp Thu Sep 12 03:22:23 2019<br>
@@ -1471,6 +1471,8 @@ bool AArch64InstrInfo::expandPostRAPseud<br>
     return false;<br>
<br>
   MachineBasicBlock &MBB = *MI.getParent();<br>
+  auto &Subtarget = MBB.getParent()->getSubtarget<AArch64Subtarget>();<br>
+  auto TRI = Subtarget.getRegisterInfo();<br>
   DebugLoc DL = MI.getDebugLoc();<br>
<br>
   if (MI.getOpcode() == AArch64::CATCHRET) {<br>
@@ -1506,11 +1508,22 @@ bool AArch64InstrInfo::expandPostRAPseud<br>
   if ((OpFlags & AArch64II::MO_GOT) != 0) {<br>
     BuildMI(MBB, MI, DL, get(AArch64::LOADgot), Reg)<br>
         .addGlobalAddress(GV, 0, OpFlags);<br>
-    BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg)<br>
-        .addReg(Reg, RegState::Kill)<br>
-        .addImm(0)<br>
-        .addMemOperand(*MI.memoperands_begin());<br>
+    if (Subtarget.isTargetILP32()) {<br>
+      unsigned Reg32 = TRI->getSubReg(Reg, AArch64::sub_32);<br>
+      BuildMI(MBB, MI, DL, get(AArch64::LDRWui))<br>
+          .addDef(Reg32, RegState::Dead)<br>
+          .addUse(Reg, RegState::Kill)<br>
+          .addImm(0)<br>
+          .addMemOperand(*MI.memoperands_begin())<br>
+          .addDef(Reg, RegState::Implicit);<br>
+    } else {<br>
+      BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg)<br>
+          .addReg(Reg, RegState::Kill)<br>
+          .addImm(0)<br>
+          .addMemOperand(*MI.memoperands_begin());<br>
+    }<br>
   } else if (TM.getCodeModel() == CodeModel::Large) {<br>
+    assert(!Subtarget.isTargetILP32() && "how can large exist in ILP32?");<br>
     BuildMI(MBB, MI, DL, get(AArch64::MOVZXi), Reg)<br>
         .addGlobalAddress(GV, 0, AArch64II::MO_G0 | MO_NC)<br>
         .addImm(0);<br>
@@ -1537,10 +1550,20 @@ bool AArch64InstrInfo::expandPostRAPseud<br>
     BuildMI(MBB, MI, DL, get(AArch64::ADRP), Reg)<br>
         .addGlobalAddress(GV, 0, OpFlags | AArch64II::MO_PAGE);<br>
     unsigned char LoFlags = OpFlags | AArch64II::MO_PAGEOFF | MO_NC;<br>
-    BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg)<br>
-        .addReg(Reg, RegState::Kill)<br>
-        .addGlobalAddress(GV, 0, LoFlags)<br>
-        .addMemOperand(*MI.memoperands_begin());<br>
+    if (Subtarget.isTargetILP32()) {<br>
+      unsigned Reg32 = TRI->getSubReg(Reg, AArch64::sub_32);<br>
+      BuildMI(MBB, MI, DL, get(AArch64::LDRWui))<br>
+          .addDef(Reg32, RegState::Dead)<br>
+          .addUse(Reg, RegState::Kill)<br>
+          .addGlobalAddress(GV, 0, LoFlags)<br>
+          .addMemOperand(*MI.memoperands_begin())<br>
+          .addDef(Reg, RegState::Implicit);<br>
+    } else {<br>
+      BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg)<br>
+          .addReg(Reg, RegState::Kill)<br>
+          .addGlobalAddress(GV, 0, LoFlags)<br>
+          .addMemOperand(*MI.memoperands_begin());<br>
+    }<br>
   }<br>
<br>
   MBB.erase(MI);<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp Thu Sep 12 03:22:23 2019<br>
@@ -32,7 +32,7 @@ SDValue AArch64SelectionDAGInfo::EmitTar<br>
     const AArch64TargetLowering &TLI = *STI.getTargetLowering();<br>
<br>
     EVT IntPtr = TLI.getPointerTy(DAG.getDataLayout());<br>
-    Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());<br>
+    Type *IntPtrTy = Type::getInt8PtrTy(*DAG.getContext());<br>
     TargetLowering::ArgListTy Args;<br>
     TargetLowering::ArgListEntry Entry;<br>
     Entry.Node = Dst;<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Thu Sep 12 03:22:23 2019<br>
@@ -411,6 +411,8 @@ public:<br>
   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }<br>
   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }<br>
<br>
+  bool isTargetILP32() const { return TargetTriple.isArch32Bit(); }<br>
+<br>
   bool useAA() const override { return UseAA; }<br>
<br>
   bool hasVH() const { return HasVH; }<br>
@@ -437,6 +439,12 @@ public:<br>
   bool hasFMI() const { return HasFMI; }<br>
   bool hasRCPC_IMMO() const { return HasRCPC_IMMO; }<br>
<br>
+  bool addrSinkUsingGEPs() const override {<br>
+    // Keeping GEPs inbounds is important for exploiting AArch64<br>
+    // addressing-modes in ILP32 mode.<br>
+    return useAA() || isTargetILP32();<br>
+  }<br>
+<br>
   bool useSmallAddressing() const {<br>
     switch (TLInfo.getTargetMachine().getCodeModel()) {<br>
       case CodeModel::Kernel:<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Thu Sep 12 03:22:23 2019<br>
@@ -157,6 +157,8 @@ extern "C" void LLVMInitializeAArch64Tar<br>
   RegisterTargetMachine<AArch64leTargetMachine> X(getTheAArch64leTarget());<br>
   RegisterTargetMachine<AArch64beTargetMachine> Y(getTheAArch64beTarget());<br>
   RegisterTargetMachine<AArch64leTargetMachine> Z(getTheARM64Target());<br>
+  RegisterTargetMachine<AArch64leTargetMachine> W(getTheARM64_32Target());<br>
+  RegisterTargetMachine<AArch64leTargetMachine> V(getTheAArch64_32Target());<br>
   auto PR = PassRegistry::getPassRegistry();<br>
   initializeGlobalISel(*PR);<br>
   initializeAArch64A53Fix835769Pass(*PR);<br>
@@ -201,8 +203,11 @@ static std::string computeDataLayout(con<br>
                                      bool LittleEndian) {<br>
   if (Options.getABIName() == "ilp32")<br>
     return "e-m:e-p:32:32-i8:8-i16:16-i64:64-S128";<br>
-  if (TT.isOSBinFormatMachO())<br>
+  if (TT.isOSBinFormatMachO()) {<br>
+    if (TT.getArch() == Triple::aarch64_32)<br>
+      return "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128";<br>
     return "e-m:o-i64:64-i128:128-n32:64-S128";<br>
+  }<br>
   if (TT.isOSBinFormatCOFF())<br>
     return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128";<br>
   if (LittleEndian)<br>
@@ -279,7 +284,8 @@ AArch64TargetMachine::AArch64TargetMachi<br>
   }<br>
<br>
   // Enable GlobalISel at or below EnableGlobalISelAt0.<br>
-  if (getOptLevel() <= EnableGlobalISelAtO) {<br>
+  if (getOptLevel() <= EnableGlobalISelAtO &&<br>
+      TT.getArch() != Triple::aarch64_32) {<br>
     setGlobalISel(true);<br>
     setGlobalISelAbort(GlobalISelAbortMode::Disable);<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp Thu Sep 12 03:22:23 2019<br>
@@ -30,7 +30,7 @@ static cl::opt<AsmWriterVariantTy> AsmWr<br>
     cl::values(clEnumValN(Generic, "generic", "Emit generic NEON assembly"),<br>
                clEnumValN(Apple, "apple", "Emit Apple-style NEON assembly")));<br>
<br>
-AArch64MCAsmInfoDarwin::AArch64MCAsmInfoDarwin() {<br>
+AArch64MCAsmInfoDarwin::AArch64MCAsmInfoDarwin(bool IsILP32) {<br>
   // We prefer NEON instructions to be printed in the short, Apple-specific<br>
   // form when targeting Darwin.<br>
   AssemblerDialect = AsmWriterVariant == Default ? Apple : AsmWriterVariant;<br>
@@ -39,7 +39,8 @@ AArch64MCAsmInfoDarwin::AArch64MCAsmInfo<br>
   PrivateLabelPrefix = "L";<br>
   SeparatorString = "%%";<br>
   CommentString = ";";<br>
-  CodePointerSize = CalleeSaveStackSlotSize = 8;<br>
+  CalleeSaveStackSlotSize = 8;<br>
+  CodePointerSize = IsILP32 ? 4 : 8;<br>
<br>
   AlignmentIsInBytes = false;<br>
   UsesELFSectionDirectiveForBSS = true;<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h (original)<br>
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h Thu Sep 12 03:22:23 2019<br>
@@ -23,7 +23,7 @@ class Target;<br>
 class Triple;<br>
<br>
 struct AArch64MCAsmInfoDarwin : public MCAsmInfoDarwin {<br>
-  explicit AArch64MCAsmInfoDarwin();<br>
+  explicit AArch64MCAsmInfoDarwin(bool IsILP32);<br>
   const MCExpr *<br>
   getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding,<br>
                               MCStreamer &Streamer) const override;<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp Thu Sep 12 03:22:23 2019<br>
@@ -241,7 +241,7 @@ static MCAsmInfo *createAArch64MCAsmInfo<br>
                                          const Triple &TheTriple) {<br>
   MCAsmInfo *MAI;<br>
   if (TheTriple.isOSBinFormatMachO())<br>
-    MAI = new AArch64MCAsmInfoDarwin();<br>
+    MAI = new AArch64MCAsmInfoDarwin(TheTriple.getArch() == Triple::aarch64_32);<br>
   else if (TheTriple.isWindowsMSVCEnvironment())<br>
     MAI = new AArch64MCAsmInfoMicrosoftCOFF();<br>
   else if (TheTriple.isOSBinFormatCOFF())<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu Sep 12 03:22:23 2019<br>
@@ -3387,6 +3387,7 @@ bool X86FastISel::fastLowerCall(CallLowe<br>
     case CCValAssign::SExtUpper:<br>
     case CCValAssign::ZExtUpper:<br>
     case CCValAssign::FPExt:<br>
+    case CCValAssign::Trunc:<br>
       llvm_unreachable("Unexpected loc info!");<br>
     case CCValAssign::Indirect:<br>
       // FIXME: Indirect doesn't need extending, but fast-isel doesn't fully<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-aapcs.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-aapcs.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-aapcs.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-aapcs.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-aapcs.ll Thu Sep 12 03:22:23 2019<br>
@@ -25,7 +25,7 @@ define [2 x i64] @test_i64x2_align(i32,<br>
 @var64 = global i64 0, align 8<br>
<br>
 ; Check stack slots are 64-bit at all times.<br>
-define void @test_stack_slots([8 x i32], i1 %bool, i8 %char, i16 %short,<br>
+define void @test_stack_slots([8 x i64], i1 %bool, i8 %char, i16 %short,<br>
                                 i32 %int, i64 %long) {<br>
 ; CHECK-LABEL: test_stack_slots:<br>
 ; CHECK-DAG: ldr w[[ext1:[0-9]+]], [sp, #24]<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-garbage-crash.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-garbage-crash.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-garbage-crash.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-garbage-crash.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-garbage-crash.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,4 +1,5 @@<br>
 ; RUN: llc -o - %s -mtriple=arm64-apple-ios -O3 -aarch64-enable-collect-loh | FileCheck %s<br>
+; RUN: llc -o - %s -mtriple=arm64_32-apple-watchos -O3 -aarch64-enable-collect-loh | FileCheck %s<br>
 ; Check that the LOH analysis does not crash when the analysed chained<br>
 ; contains instructions that are filtered out.<br>
 ;<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-str.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-str.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-str.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-str.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh-str.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,4 +1,5 @@<br>
 ; RUN: llc -o - %s -mtriple=arm64-apple-ios -O2 | FileCheck %s<br>
+; RUN: llc -o - %s -mtriple=arm64_32-apple-ios -O2 | FileCheck %s<br>
 ; Test case for <rdar://problem/15942912>.<br>
 ; AdrpAddStr cannot be used when the store uses same<br>
 ; register as address and value. Indeed, the related<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-collect-loh.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,4 +1,5 @@<br>
 ; RUN: llc -o - %s -mtriple=arm64-apple-ios -O2 | FileCheck %s<br>
+; RUN: llc -o - %s -mtriple=arm64_32-apple-watchos -O2 | FileCheck %s<br>
 ; RUN: llc -o - %s -mtriple=arm64-linux-gnu -O2 | FileCheck %s --check-prefix=CHECK-ELF<br>
<br>
 ; CHECK-ELF-NOT: .loh<br>
@@ -60,9 +61,9 @@ if.end4:<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i32 @getC() {<br>
@@ -76,9 +77,9 @@ define i32 @getC() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldrsw x0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldrsw x0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i64 @getSExtC() {<br>
@@ -94,10 +95,10 @@ define i64 @getSExtC() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
-; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0<br>
-; CHECK-NEXT: str [[ADD]], {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str [[ADD]], [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]<br>
 define void @getSeveralC(i32 %t) {<br>
@@ -114,9 +115,9 @@ entry:<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define void @setC(i32 %t) {<br>
@@ -142,7 +143,7 @@ entry:<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpAddLdr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]<br>
 define i32 @getInternalCPlus4() {<br>
-  %addr = getelementptr i32, i32* @InternalC, i32 4<br>
+  %addr = getelementptr inbounds i32, i32* @InternalC, i32 4<br>
   %res = load i32, i32* %addr, align 4<br>
   ret i32 %res<br>
 }<br>
@@ -159,7 +160,7 @@ define i32 @getInternalCPlus4() {<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpAddLdr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]<br>
 define i64 @getSExtInternalCPlus4() {<br>
-  %addr = getelementptr i32, i32* @InternalC, i32 4<br>
+  %addr = getelementptr inbounds i32, i32* @InternalC, i32 4<br>
   %res = load i32, i32* %addr, align 4<br>
   %sextres = sext i32 %res to i64<br>
   ret i64 %sextres<br>
@@ -180,7 +181,7 @@ define i64 @getSExtInternalCPlus4() {<br>
 ; CHECK: .loh AdrpAdd [[ADRP_LABEL]], [[ADDGOT_LABEL]]<br>
 define void @getSeveralInternalCPlus4(i32 %t) {<br>
 entry:<br>
-  %addr = getelementptr i32, i32* @InternalC, i32 4<br>
+  %addr = getelementptr inbounds i32, i32* @InternalC, i32 4<br>
   %tmp = load i32, i32* %addr, align 4<br>
   %add = add nsw i32 %tmp, %t<br>
   store i32 %add, i32* %addr, align 4<br>
@@ -200,7 +201,7 @@ entry:<br>
 ; CHECK: .loh AdrpAddStr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]<br>
 define void @setInternalCPlus4(i32 %t) {<br>
 entry:<br>
-  %addr = getelementptr i32, i32* @InternalC, i32 4<br>
+  %addr = getelementptr inbounds i32, i32* @InternalC, i32 4<br>
   store i32 %t, i32* %addr, align 4<br>
   ret void<br>
 }<br>
@@ -276,8 +277,8 @@ entry:<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
-; CHECK-NEXT: ldrb w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldrb w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]<br>
 define i8 @getD() {<br>
@@ -289,9 +290,9 @@ define i8 @getD() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: strb w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: strb w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setD(i8 %t) {<br>
@@ -305,9 +306,9 @@ define void @setD(i8 %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldrsb w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldrsb w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i32 @getSExtD() {<br>
@@ -322,9 +323,9 @@ define i32 @getSExtD() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldrsb x0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldrsb x0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i64 @getSExt64D() {<br>
@@ -341,8 +342,8 @@ define i64 @getSExt64D() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
-; CHECK-NEXT: ldrh w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldrh w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]<br>
 define i16 @getE() {<br>
@@ -356,9 +357,9 @@ define i16 @getE() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldrsh w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldrsh w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i32 @getSExtE() {<br>
@@ -371,9 +372,9 @@ define i32 @getSExtE() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: strh w0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: strh w0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setE(i16 %t) {<br>
@@ -387,9 +388,9 @@ define void @setE(i16 %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldrsh x0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldrsh x0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i64 @getSExt64E() {<br>
@@ -406,9 +407,9 @@ define i64 @getSExt64E() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _F@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _F@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _F@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr x0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr x0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define i64 @getF() {<br>
@@ -420,9 +421,9 @@ define i64 @getF() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _F@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _F@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _F@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str x0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str x0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setF(i64 %t) {<br>
@@ -438,9 +439,9 @@ define void @setF(i64 %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _G@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _G@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _G@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr s0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr s0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define float @getG() {<br>
@@ -452,9 +453,9 @@ define float @getG() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _G@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _G@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _G@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str s0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str s0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setG(float %t) {<br>
@@ -470,9 +471,9 @@ define void @setG(float %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _H@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _H@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _H@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr h0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr h0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define half @getH() {<br>
@@ -484,9 +485,9 @@ define half @getH() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _H@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _H@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _H@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str h0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str h0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setH(half %t) {<br>
@@ -502,9 +503,9 @@ define void @setH(half %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _I@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _I@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _I@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr d0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr d0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define double @getI() {<br>
@@ -516,9 +517,9 @@ define double @getI() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _I@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _I@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _I@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str d0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str d0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setI(double %t) {<br>
@@ -534,9 +535,9 @@ define void @setI(double %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _J@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _J@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _J@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr d0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr d0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define <2 x i32> @getJ() {<br>
@@ -548,9 +549,9 @@ define <2 x i32> @getJ() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _J@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _J@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _J@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str d0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str d0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setJ(<2 x i32> %t) {<br>
@@ -566,9 +567,9 @@ define void @setJ(<2 x i32> %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _K@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _K@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _K@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr q0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr q0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define <4 x i32> @getK() {<br>
@@ -580,9 +581,9 @@ define <4 x i32> @getK() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _K@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _K@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _K@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: str q0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: str q0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]<br>
 define void @setK(<4 x i32> %t) {<br>
@@ -598,9 +599,9 @@ define void @setK(<4 x i32> %t) {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _L@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _L@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _L@GOTPAGEOFF]<br>
 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr b0, {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: ldr b0, [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]<br>
 define <1 x i8> @getL() {<br>
@@ -612,11 +613,11 @@ define <1 x i8> @getL() {<br>
 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:<br>
 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _L@GOTPAGE<br>
 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:<br>
-; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _L@GOTPAGEOFF]<br>
+; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], {{\[}}[[ADRP_REG]], _L@GOTPAGEOFF]<br>
 ; CHECK-NEXT: ; kill<br>
 ; Ultimately we should generate str b0, but right now, we match the vector<br>
 ; variant which does not allow to fold the immediate into the store.<br>
-; CHECK-NEXT: st1.b { v0 }[0], {{\[}}[[LDRGOT_REG]]]<br>
+; CHECK-NEXT: st1.b { v0 }[0], [x[[LDRGOT_REG]]]<br>
 ; CHECK-NEXT: ret<br>
 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]<br>
 define void @setL(<1 x i8> %t) {<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-indexed-memory.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-indexed-memory.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-indexed-memory.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-indexed-memory.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-indexed-memory.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,4 +1,5 @@<br>
 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-redzone | FileCheck %s<br>
+; RUN: llc < %s -mtriple=arm64_32-apple-ios -aarch64-redzone | FileCheck %s<br>
<br>
 define i64* @store64(i64* %ptr, i64 %index, i64 %spacing) {<br>
 ; CHECK-LABEL: store64:<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-stacksave.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-stacksave.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-stacksave.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-stacksave.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-stacksave.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,6 +1,6 @@<br>
-; RUN: llc < %s -verify-coalescing<br>
+; RUN: llc -mtriple=arm64-apple-macosx10.8.0 < %s -verify-coalescing<br>
+; RUN: llc -mtriple=arm64_32-apple-ios9.0 < %s -verify-coalescing<br>
 ; <rdar://problem/11522048><br>
-target triple = "arm64-apple-macosx10.8.0"<br>
<br>
 ; Verify that we can handle spilling the stack pointer without attempting<br>
 ; spilling it directly.<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-addrs.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-addrs.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-addrs.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-addrs.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-addrs.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,44 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios %s -o - | FileCheck %s<br>
+<br>
+; If %base < 96 then the sum will not wrap (in an unsigned sense), but "ldr w0,<br>
+; [x0, #-96]" would.<br>
+define i32 @test_valid_wrap(i32 %base) {<br>
+; CHECK-LABEL: test_valid_wrap:<br>
+; CHECK: sub w[[ADDR:[0-9]+]], w0, #96<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+<br>
+  %newaddr = add nuw i32 %base, -96<br>
+  %ptr = inttoptr i32 %newaddr to i32*<br>
+  %val = load i32, i32* %ptr<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i8 @test_valid_wrap_optimizable(i8* %base) {<br>
+; CHECK-LABEL: test_valid_wrap_optimizable:<br>
+; CHECK: ldurb w0, [x0, #-96]<br>
+<br>
+  %newaddr = getelementptr inbounds i8, i8* %base, i32 -96<br>
+  %val = load i8, i8* %newaddr<br>
+  ret i8 %val<br>
+}<br>
+<br>
+define i8 @test_valid_wrap_optimizable1(i8* %base, i32 %offset) {<br>
+; CHECK-LABEL: test_valid_wrap_optimizable1:<br>
+; CHECK: ldrb w0, [x0, w1, sxtw]<br>
+<br>
+  %newaddr = getelementptr inbounds i8, i8* %base, i32 %offset<br>
+  %val = load i8, i8* %newaddr<br>
+  ret i8 %val<br>
+}<br>
+<br>
+;<br>
+define i8 @test_valid_wrap_optimizable2(i8* %base, i32 %offset) {<br>
+; CHECK-LABEL: test_valid_wrap_optimizable2:<br>
+; CHECK: sxtw x[[OFFSET:[0-9]+]], w1<br>
+; CHECK: mov w[[BASE:[0-9]+]], #-100<br>
+; CHECK: ldrb w0, [x[[OFFSET]], x[[BASE]]]<br>
+<br>
+  %newaddr = getelementptr inbounds i8, i8* inttoptr(i32 -100 to i8*), i32 %offset<br>
+  %val = load i8, i8* %newaddr<br>
+  ret i8 %val<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-atomics.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-atomics.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-atomics.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-atomics.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-atomics.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,261 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios7.0 -o - %s | FileCheck %s<br>
+<br>
+define i8 @test_load_8(i8* %addr) {<br>
+; CHECK-LABAL: test_load_8:<br>
+; CHECK: ldarb w0, [x0]<br>
+  %val = load atomic i8, i8* %addr seq_cst, align 1<br>
+  ret i8 %val<br>
+}<br>
+<br>
+define i16 @test_load_16(i16* %addr) {<br>
+; CHECK-LABAL: test_load_16:<br>
+; CHECK: ldarh w0, [x0]<br>
+  %val = load atomic i16, i16* %addr acquire, align 2<br>
+  ret i16 %val<br>
+}<br>
+<br>
+define i32 @test_load_32(i32* %addr) {<br>
+; CHECK-LABAL: test_load_32:<br>
+; CHECK: ldar w0, [x0]<br>
+  %val = load atomic i32, i32* %addr seq_cst, align 4<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i64 @test_load_64(i64* %addr) {<br>
+; CHECK-LABAL: test_load_64:<br>
+; CHECK: ldar x0, [x0]<br>
+  %val = load atomic i64, i64* %addr seq_cst, align 8<br>
+  ret i64 %val<br>
+}<br>
+<br>
+define i8* @test_load_ptr(i8** %addr) {<br>
+; CHECK-LABAL: test_load_ptr:<br>
+; CHECK: ldar w0, [x0]<br>
+  %val = load atomic i8*, i8** %addr seq_cst, align 8<br>
+  ret i8* %val<br>
+}<br>
+<br>
+define void @test_store_8(i8* %addr) {<br>
+; CHECK-LABAL: test_store_8:<br>
+; CHECK: stlrb wzr, [x0]<br>
+  store atomic i8 0, i8* %addr seq_cst, align 1<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_store_16(i16* %addr) {<br>
+; CHECK-LABAL: test_store_16:<br>
+; CHECK: stlrh wzr, [x0]<br>
+  store atomic i16 0, i16* %addr seq_cst, align 2<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_store_32(i32* %addr) {<br>
+; CHECK-LABAL: test_store_32:<br>
+; CHECK: stlr wzr, [x0]<br>
+  store atomic i32 0, i32* %addr seq_cst, align 4<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_store_64(i64* %addr) {<br>
+; CHECK-LABAL: test_store_64:<br>
+; CHECK: stlr xzr, [x0]<br>
+  store atomic i64 0, i64* %addr seq_cst, align 8<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_store_ptr(i8** %addr) {<br>
+; CHECK-LABAL: test_store_ptr:<br>
+; CHECK: stlr wzr, [x0]<br>
+  store atomic i8* null, i8** %addr seq_cst, align 8<br>
+  ret void<br>
+}<br>
+<br>
+declare i64 @llvm.aarch64.ldxr.p0i8(i8* %addr)<br>
+declare i64 @llvm.aarch64.ldxr.p0i16(i16* %addr)<br>
+declare i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)<br>
+declare i64 @llvm.aarch64.ldxr.p0i64(i64* %addr)<br>
+<br>
+define i8 @test_ldxr_8(i8* %addr) {<br>
+; CHECK-LABEL: test_ldxr_8:<br>
+; CHECK: ldxrb w0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldxr.p0i8(i8* %addr)<br>
+  %val8 = trunc i64 %val to i8<br>
+  ret i8 %val8<br>
+}<br>
+<br>
+define i16 @test_ldxr_16(i16* %addr) {<br>
+; CHECK-LABEL: test_ldxr_16:<br>
+; CHECK: ldxrh w0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldxr.p0i16(i16* %addr)<br>
+  %val16 = trunc i64 %val to i16<br>
+  ret i16 %val16<br>
+}<br>
+<br>
+define i32 @test_ldxr_32(i32* %addr) {<br>
+; CHECK-LABEL: test_ldxr_32:<br>
+; CHECK: ldxr w0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)<br>
+  %val32 = trunc i64 %val to i32<br>
+  ret i32 %val32<br>
+}<br>
+<br>
+define i64 @test_ldxr_64(i64* %addr) {<br>
+; CHECK-LABEL: test_ldxr_64:<br>
+; CHECK: ldxr x0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldxr.p0i64(i64* %addr)<br>
+  ret i64 %val<br>
+}<br>
+<br>
+declare i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr)<br>
+declare i64 @llvm.aarch64.ldaxr.p0i16(i16* %addr)<br>
+declare i64 @llvm.aarch64.ldaxr.p0i32(i32* %addr)<br>
+declare i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr)<br>
+<br>
+define i8 @test_ldaxr_8(i8* %addr) {<br>
+; CHECK-LABEL: test_ldaxr_8:<br>
+; CHECK: ldaxrb w0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr)<br>
+  %val8 = trunc i64 %val to i8<br>
+  ret i8 %val8<br>
+}<br>
+<br>
+define i16 @test_ldaxr_16(i16* %addr) {<br>
+; CHECK-LABEL: test_ldaxr_16:<br>
+; CHECK: ldaxrh w0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldaxr.p0i16(i16* %addr)<br>
+  %val16 = trunc i64 %val to i16<br>
+  ret i16 %val16<br>
+}<br>
+<br>
+define i32 @test_ldaxr_32(i32* %addr) {<br>
+; CHECK-LABEL: test_ldaxr_32:<br>
+; CHECK: ldaxr w0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldaxr.p0i32(i32* %addr)<br>
+  %val32 = trunc i64 %val to i32<br>
+  ret i32 %val32<br>
+}<br>
+<br>
+define i64 @test_ldaxr_64(i64* %addr) {<br>
+; CHECK-LABEL: test_ldaxr_64:<br>
+; CHECK: ldaxr x0, [x0]<br>
+<br>
+  %val = call i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr)<br>
+  ret i64 %val<br>
+}<br>
+<br>
+declare i32 @llvm.aarch64.stxr.p0i8(i64, i8*)<br>
+declare i32 @llvm.aarch64.stxr.p0i16(i64, i16*)<br>
+declare i32 @llvm.aarch64.stxr.p0i32(i64, i32*)<br>
+declare i32 @llvm.aarch64.stxr.p0i64(i64, i64*)<br>
+<br>
+define i32 @test_stxr_8(i8* %addr, i8 %val) {<br>
+; CHECK-LABEL: test_stxr_8:<br>
+; CHECK: stxrb [[TMP:w[0-9]+]], w1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %extval = zext i8 %val to i64<br>
+  %success = call i32 @llvm.aarch64.stxr.p0i8(i64 %extval, i8* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define i32 @test_stxr_16(i16* %addr, i16 %val) {<br>
+; CHECK-LABEL: test_stxr_16:<br>
+; CHECK: stxrh [[TMP:w[0-9]+]], w1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %extval = zext i16 %val to i64<br>
+  %success = call i32 @llvm.aarch64.stxr.p0i16(i64 %extval, i16* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define i32 @test_stxr_32(i32* %addr, i32 %val) {<br>
+; CHECK-LABEL: test_stxr_32:<br>
+; CHECK: stxr [[TMP:w[0-9]+]], w1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %extval = zext i32 %val to i64<br>
+  %success = call i32 @llvm.aarch64.stxr.p0i32(i64 %extval, i32* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define i32 @test_stxr_64(i64* %addr, i64 %val) {<br>
+; CHECK-LABEL: test_stxr_64:<br>
+; CHECK: stxr [[TMP:w[0-9]+]], x1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %success = call i32 @llvm.aarch64.stxr.p0i64(i64 %val, i64* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+declare i32 @llvm.aarch64.stlxr.p0i8(i64, i8*)<br>
+declare i32 @llvm.aarch64.stlxr.p0i16(i64, i16*)<br>
+declare i32 @llvm.aarch64.stlxr.p0i32(i64, i32*)<br>
+declare i32 @llvm.aarch64.stlxr.p0i64(i64, i64*)<br>
+<br>
+define i32 @test_stlxr_8(i8* %addr, i8 %val) {<br>
+; CHECK-LABEL: test_stlxr_8:<br>
+; CHECK: stlxrb [[TMP:w[0-9]+]], w1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %extval = zext i8 %val to i64<br>
+  %success = call i32 @llvm.aarch64.stlxr.p0i8(i64 %extval, i8* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define i32 @test_stlxr_16(i16* %addr, i16 %val) {<br>
+; CHECK-LABEL: test_stlxr_16:<br>
+; CHECK: stlxrh [[TMP:w[0-9]+]], w1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %extval = zext i16 %val to i64<br>
+  %success = call i32 @llvm.aarch64.stlxr.p0i16(i64 %extval, i16* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define i32 @test_stlxr_32(i32* %addr, i32 %val) {<br>
+; CHECK-LABEL: test_stlxr_32:<br>
+; CHECK: stlxr [[TMP:w[0-9]+]], w1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %extval = zext i32 %val to i64<br>
+  %success = call i32 @llvm.aarch64.stlxr.p0i32(i64 %extval, i32* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define i32 @test_stlxr_64(i64* %addr, i64 %val) {<br>
+; CHECK-LABEL: test_stlxr_64:<br>
+; CHECK: stlxr [[TMP:w[0-9]+]], x1, [x0]<br>
+; CHECK: mov w0, [[TMP]]<br>
+<br>
+  %success = call i32 @llvm.aarch64.stlxr.p0i64(i64 %val, i64* %addr)<br>
+  ret i32 %success<br>
+}<br>
+<br>
+define {i8*, i1} @test_cmpxchg_ptr(i8** %addr, i8* %cmp, i8* %new) {<br>
+; CHECK-LABEL: test_cmpxchg_ptr:<br>
+; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:<br>
+; CHECK:     ldaxr [[OLD:w[0-9]+]], [x0]<br>
+; CHECK:     cmp [[OLD]], w1<br>
+; CHECK:     <a href="http://b.ne" rel="noreferrer" target="_blank">b.ne</a> [[DONE:LBB[0-9]+_[0-9]+]]<br>
+; CHECK:     stlxr [[SUCCESS:w[0-9]+]], w2, [x0]<br>
+; CHECK:     cbnz [[SUCCESS]], [[LOOP]]<br>
+<br>
+; CHECK:     mov w1, #1<br>
+; CHECK:     mov w0, [[OLD]]<br>
+; CHECK:     ret<br>
+<br>
+; CHECK: [[DONE]]:<br>
+; CHECK:     clrex<br>
+; CHECK:     mov w1, wzr<br>
+; CHECK:     mov w0, [[OLD]]<br>
+; CHECK:     ret<br>
+  %res = cmpxchg i8** %addr, i8* %cmp, i8* %new acq_rel acquire<br>
+  ret {i8*, i1} %res<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-fastisel.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-fastisel.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-fastisel.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-fastisel.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-fastisel.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,28 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios -O0 -fast-isel %s -o - | FileCheck %s<br>
+@var = global i8* null<br>
+<br>
+define void @test_store_release_ptr() {<br>
+; CHECK-LABEL: test_store_release_ptr<br>
+; CHECK: mov [[ZERO:w[0-9]+]], wzr<br>
+; CHECK: stlr [[ZERO]]<br>
+  store atomic i8* null, i8** @var release, align 4<br>
+  br label %next<br>
+<br>
+next:<br>
+  ret void<br>
+}<br>
+<br>
+declare [2 x i32] @callee()<br>
+<br>
+define void @test_struct_return(i32* %addr) {<br>
+; CHECK-LABEL: test_struct_return:<br>
+; CHECK: bl _callee<br>
+; CHECK-DAG: lsr [[HI:x[0-9]+]], x0, #32<br>
+; CHECK-DAG: str w0<br>
+  %res = call [2 x i32] @callee()<br>
+  %res.0 = extractvalue [2 x i32] %res, 0<br>
+  store i32 %res.0, i32* %addr<br>
+  %res.1 = extractvalue [2 x i32] %res, 1<br>
+  store i32 %res.1, i32* %addr<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-frame-pointers.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-frame-pointers.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-frame-pointers.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-frame-pointers.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-frame-pointers.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,26 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios8.0 %s -o - | FileCheck %s<br>
+<br>
+; We're provoking LocalStackSlotAllocation to create some shared frame bases<br>
+; here: it wants multiple <fi#N> using instructions that can be satisfied by a<br>
+; single base, but not within the addressing-mode.<br>
+;<br>
+; When that happens it's important that we don't mix our pointer sizes<br>
+; (e.g. try to create an ldr from a w-register base).<br>
+define i8 @test_register_wrangling() {<br>
+; CHECK-LABEL: test_register_wrangling:<br>
+; CHECK: add [[TMP:x[0-9]+]], sp,<br>
+; CHECK: add x[[BASE:[0-9]+]], [[TMP]],<br>
+; CHECK: ldrb {{w[0-9]+}}, [x[[BASE]], #1]<br>
+; CHECK: ldrb {{w[0-9]+}}, [x[[BASE]]]<br>
+<br>
+  %var1 = alloca i8, i32 4100<br>
+  %var3 = alloca i8<br>
+  %dummy = alloca i8, i32 4100<br>
+<br>
+  %var1p1 = getelementptr i8, i8* %var1, i32 1<br>
+  %val1 = load i8, i8* %var1<br>
+  %val2 = load i8, i8* %var3<br>
+<br>
+  %sum = add i8 %val1, %val2<br>
+  ret i8 %sum<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-gep-sink.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-gep-sink.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-gep-sink.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-gep-sink.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-gep-sink.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,61 @@<br>
+; RUN: opt -codegenprepare -mtriple=arm64_32-apple-ios %s -S -o - | FileCheck %s<br>
+<br>
+define void @test_simple_sink(i1* %base, i64 %offset) {<br>
+; CHECK-LABEL: @test_simple_sink<br>
+; CHECK: next:<br>
+; CHECK:   [[BASE8:%.*]] = bitcast i1* %base to i8*<br>
+; CHECK:   [[ADDR8:%.*]] = getelementptr i8, i8* [[BASE8]], i64 %offset<br>
+; CHECK:   [[ADDR:%.*]] = bitcast i8* [[ADDR8]] to i1*<br>
+; CHECK:   load volatile i1, i1* [[ADDR]]<br>
+  %addr = getelementptr i1, i1* %base, i64 %offset<br>
+  %tst = load i1, i1* %addr<br>
+  br i1 %tst, label %next, label %end<br>
+<br>
+next:<br>
+  load volatile i1, i1* %addr<br>
+  ret void<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_inbounds_sink(i1* %base, i64 %offset) {<br>
+; CHECK-LABEL: @test_inbounds_sink<br>
+; CHECK: next:<br>
+; CHECK:   [[BASE8:%.*]] = bitcast i1* %base to i8*<br>
+; CHECK:   [[ADDR8:%.*]] = getelementptr inbounds i8, i8* [[BASE8]], i64 %offset<br>
+; CHECK:   [[ADDR:%.*]] = bitcast i8* [[ADDR8]] to i1*<br>
+; CHECK:   load volatile i1, i1* [[ADDR]]<br>
+  %addr = getelementptr inbounds i1, i1* %base, i64 %offset<br>
+  %tst = load i1, i1* %addr<br>
+  br i1 %tst, label %next, label %end<br>
+<br>
+next:<br>
+  load volatile i1, i1* %addr<br>
+  ret void<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; No address derived via an add can be guaranteed inbounds<br>
+define void @test_add_sink(i1* %base, i64 %offset) {<br>
+; CHECK-LABEL: @test_add_sink<br>
+; CHECK: next:<br>
+; CHECK:   [[BASE8:%.*]] = bitcast i1* %base to i8*<br>
+; CHECK:   [[ADDR8:%.*]] = getelementptr i8, i8* [[BASE8]], i64 %offset<br>
+; CHECK:   [[ADDR:%.*]] = bitcast i8* [[ADDR8]] to i1*<br>
+; CHECK:   load volatile i1, i1* [[ADDR]]<br>
+  %base64 = ptrtoint i1* %base to i64<br>
+  %addr64 = add nsw nuw i64 %base64, %offset<br>
+  %addr = inttoptr i64 %addr64 to i1*<br>
+  %tst = load i1, i1* %addr<br>
+  br i1 %tst, label %next, label %end<br>
+<br>
+next:<br>
+  load volatile i1, i1* %addr<br>
+  ret void<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-memcpy.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-memcpy.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-memcpy.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-memcpy.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-memcpy.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,66 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios9.0 -o - %s | FileCheck %s<br>
+<br>
+define i64 @test_memcpy(i64* %addr, i8* %src, i1 %tst) minsize {<br>
+; CHECK-LABEL: test_memcpy:<br>
+; CHECK: ldr [[VAL64:x[0-9]+]], [x0]<br>
+; [...]<br>
+; CHECK: and x0, [[VAL64]], #0xffffffff<br>
+; CHECK: bl _memcpy<br>
+<br>
+  %val64 = load i64, i64* %addr<br>
+  br i1 %tst, label %true, label %false<br>
+<br>
+true:<br>
+  ret i64 %val64<br>
+<br>
+false:<br>
+  %val32 = trunc i64 %val64 to i32<br>
+  %val.ptr = inttoptr i32 %val32 to i8*<br>
+  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %val.ptr, i8* %src, i32 128, i32 0, i1 1)<br>
+  ret i64 undef<br>
+}<br>
+<br>
+define i64 @test_memmove(i64* %addr, i8* %src, i1 %tst) minsize {<br>
+; CHECK-LABEL: test_memmove:<br>
+; CHECK: ldr [[VAL64:x[0-9]+]], [x0]<br>
+; [...]<br>
+; CHECK: and x0, [[VAL64]], #0xffffffff<br>
+; CHECK: bl _memmove<br>
+<br>
+  %val64 = load i64, i64* %addr<br>
+  br i1 %tst, label %true, label %false<br>
+<br>
+true:<br>
+  ret i64 %val64<br>
+<br>
+false:<br>
+  %val32 = trunc i64 %val64 to i32<br>
+  %val.ptr = inttoptr i32 %val32 to i8*<br>
+  call void @llvm.memmove.p0i8.p0i8.i32(i8* %val.ptr, i8* %src, i32 128, i32 0, i1 1)<br>
+  ret i64 undef<br>
+}<br>
+<br>
+define i64 @test_memset(i64* %addr, i8* %src, i1 %tst) minsize {<br>
+; CHECK-LABEL: test_memset:<br>
+; CHECK: ldr [[VAL64:x[0-9]+]], [x0]<br>
+; [...]<br>
+; CHECK: and x0, [[VAL64]], #0xffffffff<br>
+; CHECK: bl _memset<br>
+<br>
+  %val64 = load i64, i64* %addr<br>
+  br i1 %tst, label %true, label %false<br>
+<br>
+true:<br>
+  ret i64 %val64<br>
+<br>
+false:<br>
+  %val32 = trunc i64 %val64 to i32<br>
+  %val.ptr = inttoptr i32 %val32 to i8*<br>
+  call void @llvm.memset.p0i8.i32(i8* %val.ptr, i8 42, i32 256, i32 0, i1 1)<br>
+  ret i64 undef<br>
+}<br>
+<br>
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)<br>
+declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)<br>
+declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)<br>
+<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-neon.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-neon.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-neon.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-neon.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-neon.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,198 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios7.0 -mcpu=cyclone %s -o - | FileCheck %s<br>
+<br>
+define <2 x double> @test_insert_elt(<2 x double> %vec, double %val) {<br>
+; CHECK-LABEL: test_insert_elt:<br>
+; CHECK: mov.d v0[0], v1[0]<br>
+  %res = insertelement <2 x double> %vec, double %val, i32 0<br>
+  ret <2 x double> %res<br>
+}<br>
+<br>
+define void @test_split_16B(<4 x float> %val, <4 x float>* %addr) {<br>
+; CHECK-LABEL: test_split_16B:<br>
+; CHECK: str q0, [x0]<br>
+  store <4 x float> %val, <4 x float>* %addr, align 8<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_split_16B_splat(<4 x i32>, <4 x i32>* %addr) {<br>
+; CHECK-LABEL: test_split_16B_splat:<br>
+; CHECK: str {{q[0-9]+}}<br>
+<br>
+  %vec.tmp0 = insertelement <4 x i32> undef, i32 42, i32 0<br>
+  %vec.tmp1 = insertelement <4 x i32> %vec.tmp0, i32 42, i32 1<br>
+  %vec.tmp2 = insertelement <4 x i32> %vec.tmp1, i32 42, i32 2<br>
+  %vec = insertelement <4 x i32> %vec.tmp2, i32 42, i32 3<br>
+<br>
+  store <4 x i32> %vec, <4 x i32>* %addr, align 8<br>
+  ret void<br>
+}<br>
+<br>
+<br>
+%vec = type <2 x double><br>
+<br>
+declare {%vec, %vec} @llvm.aarch64.neon.ld2r.v2f64.p0i8(i8*)<br>
+define {%vec, %vec} @test_neon_load(i8* %addr) {<br>
+; CHECK-LABEL: test_neon_load:<br>
+; CHECK: ld2r.2d { v0, v1 }, [x0]<br>
+  %res = call {%vec, %vec} @llvm.aarch64.neon.ld2r.v2f64.p0i8(i8* %addr)<br>
+  ret {%vec, %vec} %res<br>
+}<br>
+<br>
+declare {%vec, %vec} @llvm.aarch64.neon.ld2lane.v2f64.p0i8(%vec, %vec, i64, i8*)<br>
+define {%vec, %vec} @test_neon_load_lane(i8* %addr, %vec %in1, %vec %in2) {<br>
+; CHECK-LABEL: test_neon_load_lane:<br>
+; CHECK: ld2.d { v0, v1 }[0], [x0]<br>
+  %res = call {%vec, %vec} @llvm.aarch64.neon.ld2lane.v2f64.p0i8(%vec %in1, %vec %in2, i64 0, i8* %addr)<br>
+  ret {%vec, %vec} %res<br>
+}<br>
+<br>
+declare void @llvm.aarch64.neon.st2.v2f64.p0i8(%vec, %vec, i8*)<br>
+define void @test_neon_store(i8* %addr, %vec %in1, %vec %in2) {<br>
+; CHECK-LABEL: test_neon_store:<br>
+; CHECK: st2.2d { v0, v1 }, [x0]<br>
+  call void @llvm.aarch64.neon.st2.v2f64.p0i8(%vec %in1, %vec %in2, i8* %addr)<br>
+  ret void<br>
+}<br>
+<br>
+declare void @llvm.aarch64.neon.st2lane.v2f64.p0i8(%vec, %vec, i64, i8*)<br>
+define void @test_neon_store_lane(i8* %addr, %vec %in1, %vec %in2) {<br>
+; CHECK-LABEL: test_neon_store_lane:<br>
+; CHECK: st2.d { v0, v1 }[1], [x0]<br>
+  call void @llvm.aarch64.neon.st2lane.v2f64.p0i8(%vec %in1, %vec %in2, i64 1, i8* %addr)<br>
+  ret void<br>
+}<br>
+<br>
+declare {%vec, %vec} @llvm.aarch64.neon.ld2.v2f64.p0i8(i8*)<br>
+define {{%vec, %vec}, i8*} @test_neon_load_post(i8* %addr, i32 %offset) {<br>
+; CHECK-LABEL: test_neon_load_post:<br>
+; CHECK-DAG: sxtw [[OFFSET:x[0-9]+]], w1<br>
+; CHECK: ld2.2d { v0, v1 }, [x0], [[OFFSET]]<br>
+<br>
+  %vecs = call {%vec, %vec} @llvm.aarch64.neon.ld2.v2f64.p0i8(i8* %addr)<br>
+<br>
+  %addr.new = getelementptr inbounds i8, i8* %addr, i32 %offset<br>
+<br>
+  %res.tmp = insertvalue {{%vec, %vec}, i8*} undef, {%vec, %vec} %vecs, 0<br>
+  %res = insertvalue {{%vec, %vec}, i8*} %res.tmp, i8* %addr.new, 1<br>
+  ret {{%vec, %vec}, i8*} %res<br>
+}<br>
+<br>
+define {{%vec, %vec}, i8*} @test_neon_load_post_lane(i8* %addr, i32 %offset, %vec %in1, %vec %in2) {<br>
+; CHECK-LABEL: test_neon_load_post_lane:<br>
+; CHECK-DAG: sxtw [[OFFSET:x[0-9]+]], w1<br>
+; CHECK: ld2.d { v0, v1 }[1], [x0], [[OFFSET]]<br>
+<br>
+  %vecs = call {%vec, %vec} @llvm.aarch64.neon.ld2lane.v2f64.p0i8(%vec %in1, %vec %in2, i64 1, i8* %addr)<br>
+<br>
+  %addr.new = getelementptr inbounds i8, i8* %addr, i32 %offset<br>
+<br>
+  %res.tmp = insertvalue {{%vec, %vec}, i8*} undef, {%vec, %vec} %vecs, 0<br>
+  %res = insertvalue {{%vec, %vec}, i8*} %res.tmp, i8* %addr.new, 1<br>
+  ret {{%vec, %vec}, i8*} %res<br>
+}<br>
+<br>
+define i8* @test_neon_store_post(i8* %addr, i32 %offset, %vec %in1, %vec %in2) {<br>
+; CHECK-LABEL: test_neon_store_post:<br>
+; CHECK-DAG: sxtw [[OFFSET:x[0-9]+]], w1<br>
+; CHECK: st2.2d { v0, v1 }, [x0], [[OFFSET]]<br>
+<br>
+  call void @llvm.aarch64.neon.st2.v2f64.p0i8(%vec %in1, %vec %in2, i8* %addr)<br>
+<br>
+  %addr.new = getelementptr inbounds i8, i8* %addr, i32 %offset<br>
+<br>
+  ret i8* %addr.new<br>
+}<br>
+<br>
+define i8* @test_neon_store_post_lane(i8* %addr, i32 %offset, %vec %in1, %vec %in2) {<br>
+; CHECK-LABEL: test_neon_store_post_lane:<br>
+; CHECK: sxtw [[OFFSET:x[0-9]+]], w1<br>
+; CHECK: st2.d { v0, v1 }[0], [x0], [[OFFSET]]<br>
+<br>
+  call void @llvm.aarch64.neon.st2lane.v2f64.p0i8(%vec %in1, %vec %in2, i64 0, i8* %addr)<br>
+<br>
+  %addr.new = getelementptr inbounds i8, i8* %addr, i32 %offset<br>
+<br>
+  ret i8* %addr.new<br>
+}<br>
+<br>
+; ld1 is slightly different because it goes via ISelLowering of normal IR ops<br>
+; rather than an intrinsic.<br>
+define {%vec, double*} @test_neon_ld1_post_lane(double* %addr, i32 %offset, %vec %in) {<br>
+; CHECK-LABEL: test_neon_ld1_post_lane:<br>
+; CHECK: sbfiz [[OFFSET:x[0-9]+]], x1, #3, #32<br>
+; CHECK: ld1.d { v0 }[0], [x0], [[OFFSET]]<br>
+<br>
+  %loaded = load double, double* %addr, align 8<br>
+  %newvec = insertelement %vec %in, double %loaded, i32 0<br>
+<br>
+  %addr.new = getelementptr inbounds double, double* %addr, i32 %offset<br>
+<br>
+  %res.tmp = insertvalue {%vec, double*} undef, %vec %newvec, 0<br>
+  %res = insertvalue {%vec, double*} %res.tmp, double* %addr.new, 1<br>
+<br>
+  ret {%vec, double*} %res<br>
+}<br>
+<br>
+define {{%vec, %vec}, i8*} @test_neon_load_post_exact(i8* %addr) {<br>
+; CHECK-LABEL: test_neon_load_post_exact:<br>
+; CHECK: ld2.2d { v0, v1 }, [x0], #32<br>
+<br>
+  %vecs = call {%vec, %vec} @llvm.aarch64.neon.ld2.v2f64.p0i8(i8* %addr)<br>
+<br>
+  %addr.new = getelementptr inbounds i8, i8* %addr, i32 32<br>
+<br>
+  %res.tmp = insertvalue {{%vec, %vec}, i8*} undef, {%vec, %vec} %vecs, 0<br>
+  %res = insertvalue {{%vec, %vec}, i8*} %res.tmp, i8* %addr.new, 1<br>
+  ret {{%vec, %vec}, i8*} %res<br>
+}<br>
+<br>
+define {%vec, double*} @test_neon_ld1_post_lane_exact(double* %addr, %vec %in) {<br>
+; CHECK-LABEL: test_neon_ld1_post_lane_exact:<br>
+; CHECK: ld1.d { v0 }[0], [x0], #8<br>
+<br>
+  %loaded = load double, double* %addr, align 8<br>
+  %newvec = insertelement %vec %in, double %loaded, i32 0<br>
+<br>
+  %addr.new = getelementptr inbounds double, double* %addr, i32 1<br>
+<br>
+  %res.tmp = insertvalue {%vec, double*} undef, %vec %newvec, 0<br>
+  %res = insertvalue {%vec, double*} %res.tmp, double* %addr.new, 1<br>
+<br>
+  ret {%vec, double*} %res<br>
+}<br>
+<br>
+; As in the general load/store case, this GEP has defined semantics when the<br>
+; address wraps. We cannot use post-indexed addressing.<br>
+define {%vec, double*} @test_neon_ld1_notpost_lane_exact(double* %addr, %vec %in) {<br>
+; CHECK-LABEL: test_neon_ld1_notpost_lane_exact:<br>
+; CHECK-NOT: ld1.d { {{v[0-9]+}} }[0], [{{x[0-9]+|sp}}], #8<br>
+; CHECK: add w0, w0, #8<br>
+; CHECK: ret<br>
+<br>
+  %loaded = load double, double* %addr, align 8<br>
+  %newvec = insertelement %vec %in, double %loaded, i32 0<br>
+<br>
+  %addr.new = getelementptr double, double* %addr, i32 1<br>
+<br>
+  %res.tmp = insertvalue {%vec, double*} undef, %vec %newvec, 0<br>
+  %res = insertvalue {%vec, double*} %res.tmp, double* %addr.new, 1<br>
+<br>
+  ret {%vec, double*} %res<br>
+}<br>
+<br>
+define {%vec, double*} @test_neon_ld1_notpost_lane(double* %addr, i32 %offset, %vec %in) {<br>
+; CHECK-LABEL: test_neon_ld1_notpost_lane:<br>
+; CHECK-NOT: ld1.d { {{v[0-9]+}} }[0], [{{x[0-9]+|sp}}], {{x[0-9]+|sp}}<br>
+; CHECK: add w0, w0, w1, lsl #3<br>
+; CHECK: ret<br>
+<br>
+  %loaded = load double, double* %addr, align 8<br>
+  %newvec = insertelement %vec %in, double %loaded, i32 0<br>
+<br>
+  %addr.new = getelementptr double, double* %addr, i32 %offset<br>
+<br>
+  %res.tmp = insertvalue {%vec, double*} undef, %vec %newvec, 0<br>
+  %res = insertvalue {%vec, double*} %res.tmp, double* %addr.new, 1<br>
+<br>
+  ret {%vec, double*} %res<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-null.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-null.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-null.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-null.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-null.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,28 @@<br>
+; RUN: llc -fast-isel=true  -global-isel=false -O0 -mtriple=arm64_32-apple-ios %s -o - | FileCheck %s<br>
+; RUN: llc -fast-isel=false -global-isel=false -O0 -mtriple=arm64_32-apple-ios %s -o - | FileCheck %s<br>
+<br>
+define void @test_store(i8** %p) {<br>
+; CHECK-LABEL: test_store:<br>
+; CHECK: mov [[R1:w[0-9]+]], wzr<br>
+; CHECK: str [[R1]], [x0]<br>
+<br>
+  store i8* null, i8** %p<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_phi(i8** %p) {<br>
+; CHECK-LABEL: test_phi:<br>
+; CHECK: mov [[R1:x[0-9]+]], xzr<br>
+; CHECK: str [[R1]], [sp]<br>
+; CHECK: b [[BB:LBB[0-9_]+]]<br>
+; CHECK: [[BB]]:<br>
+; CHECK: ldr x0, [sp]<br>
+; CHECK: str w0, [x{{.*}}]<br>
+<br>
+bb0:<br>
+  br label %bb1<br>
+bb1:<br>
+  %tmp0 = phi i8* [ null, %bb0 ]<br>
+  store i8* %tmp0, i8** %p<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-pointer-extend.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-pointer-extend.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-pointer-extend.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-pointer-extend.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-pointer-extend.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,49 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios7.0 %s -o - | FileCheck %s<br>
+<br>
+define void @pass_pointer(i64 %in) {<br>
+; CHECK-LABEL: pass_pointer:<br>
+; CHECK: and x0, x0, #0xffffffff<br>
+; CHECK: bl _take_pointer<br>
+<br>
+  %in32 = trunc i64 %in to i32<br>
+  %ptr = inttoptr i32 %in32 to i8*<br>
+  call i64 @take_pointer(i8* %ptr)<br>
+  ret void<br>
+}<br>
+<br>
+define i64 @take_pointer(i8* %ptr) nounwind {<br>
+; CHECK-LABEL: take_pointer:<br>
+; CHECK-NEXT: %bb.0<br>
+; CHECK-NEXT: ret<br>
+<br>
+  %val = ptrtoint i8* %ptr to i32<br>
+  %res = zext i32 %val to i64<br>
+  ret i64 %res<br>
+}<br>
+<br>
+define i32 @callee_ptr_stack_slot([8 x i64], i8*, i32 %val) {<br>
+; CHECK-LABEL: callee_ptr_stack_slot:<br>
+; CHECK: ldr w0, [sp, #4]<br>
+<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define void @caller_ptr_stack_slot(i8* %ptr) {<br>
+; CHECK-LABEL: caller_ptr_stack_slot:<br>
+; CHECK-DAG: mov [[VAL:w[0-9]]], #42<br>
+; CHECK: stp w0, [[VAL]], [sp]<br>
+<br>
+  call i32 @callee_ptr_stack_slot([8 x i64] undef, i8* %ptr, i32 42)<br>
+  ret void<br>
+}<br>
+<br>
+define i8* @return_ptr(i64 %in, i64 %r) {<br>
+; CHECK-LABEL: return_ptr:<br>
+; CHECK: sdiv [[VAL64:x[0-9]+]], x0, x1<br>
+; CHECK: and x0, [[VAL64]], #0xffffffff<br>
+<br>
+  %sum = sdiv i64 %in, %r<br>
+  %sum32 = trunc i64 %sum to i32<br>
+  %res = inttoptr i32 %sum32 to i8*<br>
+  ret i8* %res<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-stack-pointers.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-stack-pointers.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-stack-pointers.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-stack-pointers.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-stack-pointers.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,13 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios9.0 -o - %s | FileCheck %s<br>
+<br>
+declare void @callee([8 x i64], i8*, i8*)<br>
+<br>
+; Make sure we don't accidentally store X0 or XZR, which might well<br>
+; clobber other arguments or data.<br>
+define void @test_stack_ptr_32bits(i8* %in) {<br>
+; CHECK-LABEL: test_stack_ptr_32bits:<br>
+; CHECK-DAG: stp wzr, w0, [sp]<br>
+<br>
+  call void @callee([8 x i64] undef, i8* null, i8* %in)<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-tls.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-tls.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-tls.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-tls.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-tls.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,22 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios %s -o - | FileCheck %s<br>
+<br>
+define i32 @test_thread_local() {<br>
+; CHECK-LABEL: test_thread_local:<br>
+; CHECK: adrp x[[TMP:[0-9]+]], _var@TLVPPAGE<br>
+; CHECK: ldr w0, [x[[TMP]], _var@TLVPPAGEOFF]<br>
+; CHECK: ldr w[[DEST:[0-9]+]], [x0]<br>
+; CHECK: blr x[[DEST]]<br>
+<br>
+  %val = load i32, i32* @var<br>
+  ret i32 %val<br>
+}<br>
+<br>
+@var = thread_local global i32 zeroinitializer<br>
+<br>
+; CHECK: .tbss _var$tlv$init, 4, 2<br>
+<br>
+; CHECK-LABEL: __DATA,__thread_vars<br>
+; CHECK: _var:<br>
+; CHECK:    .long __tlv_bootstrap<br>
+; CHECK:    .long 0<br>
+; CHECK:    .long _var$tlv$init<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32-va.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-va.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32-va.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32-va.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32-va.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,56 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios %s -o - | FileCheck %s<br>
+<br>
+define void @test_va_copy(i8* %dst, i8* %src) {<br>
+; CHECK-LABEL: test_va_copy:<br>
+; CHECK: ldr [[PTR:w[0-9]+]], [x1]<br>
+; CHECK: str [[PTR]], [x0]<br>
+<br>
+  call void @llvm.va_copy(i8* %dst, i8* %src)<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_va_start(i32, ...)  {<br>
+; CHECK-LABEL: test_va_start<br>
+; CHECK: add x[[LIST:[0-9]+]], sp, #16<br>
+; CHECK: str w[[LIST]],<br>
+  %slot = alloca i8*, align 4<br>
+  %list = bitcast i8** %slot to i8*<br>
+  call void @llvm.va_start(i8* %list)<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_va_start_odd([8 x i64], i32, ...) {<br>
+; CHECK-LABEL: test_va_start_odd:<br>
+; CHECK: add x[[LIST:[0-9]+]], sp, #20<br>
+; CHECK: str w[[LIST]],<br>
+  %slot = alloca i8*, align 4<br>
+  %list = bitcast i8** %slot to i8*<br>
+  call void @llvm.va_start(i8* %list)<br>
+  ret void<br>
+}<br>
+<br>
+define i8* @test_va_arg(i8** %list) {<br>
+; CHECK-LABEL: test_va_arg:<br>
+; CHECK: ldr w[[LOC:[0-9]+]], [x0]<br>
+; CHECK: add [[NEXTLOC:w[0-9]+]], w[[LOC]], #4<br>
+; CHECK: str [[NEXTLOC]], [x0]<br>
+; CHECK: ldr w0, [x[[LOC]]]<br>
+  %res = va_arg i8** %list, i8*<br>
+  ret i8* %res<br>
+}<br>
+<br>
+define i8* @really_test_va_arg(i8** %list, i1 %tst) {<br>
+; CHECK-LABEL: really_test_va_arg:<br>
+; CHECK: ldr w[[LOC:[0-9]+]], [x0]<br>
+; CHECK: add [[NEXTLOC:w[0-9]+]], w[[LOC]], #4<br>
+; CHECK: str [[NEXTLOC]], [x0]<br>
+; CHECK: ldr w[[VAARG:[0-9]+]], [x[[LOC]]]<br>
+; CHECK: csel x0, x[[VAARG]], xzr<br>
+  %tmp = va_arg i8** %list, i8*<br>
+  %res = select i1 %tst, i8* %tmp, i8* null<br>
+  ret i8* %res<br>
+}<br>
+<br>
+declare void @llvm.va_start(i8*) <br>
+<br>
+declare void @llvm.va_copy(i8*, i8*)<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/arm64_32.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64_32.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64_32.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64_32.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,715 @@<br>
+; RUN: llc -mtriple=arm64_32-apple-ios7.0 %s -filetype=obj -o - -disable-post-ra -frame-pointer=all | \<br>
+; RUN:     llvm-objdump -private-headers - | \<br>
+; RUN:     FileCheck %s --check-prefix=CHECK-MACHO<br>
+; RUN: llc -mtriple=arm64_32-apple-ios7.0 %s -o - -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -frame-pointer=all | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT<br>
+; RUN: llc -mtriple=arm64_32-apple-ios7.0 %s -o - -fast-isel -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -frame-pointer=all | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FAST<br>
+<br>
+; CHECK-MACHO: Mach header<br>
+; CHECK-MACHO: MH_MAGIC ARM64_32 V8<br>
+<br>
+@var64 = global i64 zeroinitializer, align 8<br>
+@var32 = global i32 zeroinitializer, align 4<br>
+<br>
+@var_got = external global i8<br>
+<br>
+define i32* @test_global_addr() {<br>
+; CHECK-LABEL: test_global_addr:<br>
+; CHECK: adrp [[PAGE:x[0-9]+]], _var32@PAGE<br>
+; CHECK: add x0, [[PAGE]], _var32@PAGEOFF<br>
+  ret i32* @var32<br>
+}<br>
+<br>
+; ADRP is necessarily 64-bit. The important point to check is that, however that<br>
+; gets truncated to 32-bits, it's free. No need to zero out higher bits of that<br>
+; register.<br>
+define i64 @test_global_addr_extension() {<br>
+; CHECK-LABEL: test_global_addr_extension:<br>
+; CHECK: adrp [[PAGE:x[0-9]+]], _var32@PAGE<br>
+; CHECK: add x0, [[PAGE]], _var32@PAGEOFF<br>
+; CHECK-NOT: and<br>
+; CHECK: ret<br>
+<br>
+  ret i64 ptrtoint(i32* @var32 to i64)<br>
+}<br>
+<br>
+define i32 @test_global_value() {<br>
+; CHECK-LABEL: test_global_value:<br>
+; CHECK: adrp x[[PAGE:[0-9]+]], _var32@PAGE<br>
+; CHECK: ldr w0, [x[[PAGE]], _var32@PAGEOFF]<br>
+  %val = load i32, i32* @var32, align 4<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Because the addition may wrap, it is not safe to use "ldr w0, [xN, #32]" here.<br>
+define i32 @test_unsafe_indexed_add() {<br>
+; CHECK-LABEL: test_unsafe_indexed_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: add w[[ADDR:[0-9]+]], w[[VAR32]], #32<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i32<br>
+  %addr_plus_32 = add i32 %addr_int, 32<br>
+  %addr = inttoptr i32 %addr_plus_32 to i32*<br>
+  %val = load i32, i32* %addr, align 4<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Since we've promised there is no unsigned overflow, @var32 must be at least<br>
+; 32-bytes below 2^32, and we can use the load this time.<br>
+define i32 @test_safe_indexed_add() {<br>
+; CHECK-LABEL: test_safe_indexed_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: add w[[ADDR:[0-9]+]], w[[VAR32]], #32<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i64<br>
+  %addr_plus_32 = add nuw i64 %addr_int, 32<br>
+  %addr = inttoptr i64 %addr_plus_32 to i32*<br>
+  %val = load i32, i32* %addr, align 4<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i32 @test_safe_indexed_or(i32 %in) {<br>
+; CHECK-LABEL: test_safe_indexed_or:<br>
+; CHECK: and [[TMP:w[0-9]+]], {{w[0-9]+}}, #0xfffffff0<br>
+; CHECK: orr w[[ADDR:[0-9]+]], [[TMP]], #0x4<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = and i32 %in, -16<br>
+  %addr_plus_4 = or i32 %addr_int, 4<br>
+  %addr = inttoptr i32 %addr_plus_4 to i32*<br>
+  %val = load i32, i32* %addr, align 4<br>
+  ret i32 %val<br>
+}<br>
+<br>
+<br>
+; Promising nsw is not sufficient because the addressing mode basically<br>
+; calculates "zext(base) + zext(offset)" and nsw only guarantees<br>
+; "sext(base) + sext(offset) == base + offset".<br>
+define i32 @test_unsafe_nsw_indexed_add() {<br>
+; CHECK-LABEL: test_unsafe_nsw_indexed_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: add w[[ADDR:[0-9]+]], w[[VAR32]], #32<br>
+; CHECK-NOT: ubfx<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i32<br>
+  %addr_plus_32 = add nsw i32 %addr_int, 32<br>
+  %addr = inttoptr i32 %addr_plus_32 to i32*<br>
+  %val = load i32, i32* %addr, align 4<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Because the addition may wrap, it is not safe to use "ldr w0, [xN, #32]" here.<br>
+define i32 @test_unsafe_unscaled_add() {<br>
+; CHECK-LABEL: test_unsafe_unscaled_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: add w[[ADDR:[0-9]+]], w[[VAR32]], #3<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i32<br>
+  %addr_plus_3 = add i32 %addr_int, 3<br>
+  %addr = inttoptr i32 %addr_plus_3 to i32*<br>
+  %val = load i32, i32* %addr, align 1<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Since we've promised there is no unsigned overflow, @var32 must be at least<br>
+; 32-bytes below 2^32, and we can use the load this time.<br>
+define i32 @test_safe_unscaled_add() {<br>
+; CHECK-LABEL: test_safe_unscaled_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: add w[[ADDR:[0-9]+]], w[[VAR32]], #3<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i32<br>
+  %addr_plus_3 = add nuw i32 %addr_int, 3<br>
+  %addr = inttoptr i32 %addr_plus_3 to i32*<br>
+  %val = load i32, i32* %addr, align 1<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Promising nsw is not sufficient because the addressing mode basically<br>
+; calculates "zext(base) + zext(offset)" and nsw only guarantees<br>
+; "sext(base) + sext(offset) == base + offset".<br>
+define i32 @test_unsafe_nsw_unscaled_add() {<br>
+; CHECK-LABEL: test_unsafe_nsw_unscaled_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: add w[[ADDR:[0-9]+]], w[[VAR32]], #3<br>
+; CHECK-NOT: ubfx<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i32<br>
+  %addr_plus_3 = add nsw i32 %addr_int, 3<br>
+  %addr = inttoptr i32 %addr_plus_3 to i32*<br>
+  %val = load i32, i32* %addr, align 1<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Because the addition may wrap, it is not safe to use "ldur w0, [xN, #-3]"<br>
+; here.<br>
+define i32 @test_unsafe_negative_unscaled_add() {<br>
+; CHECK-LABEL: test_unsafe_negative_unscaled_add:<br>
+; CHECK: add x[[VAR32:[0-9]+]], {{x[0-9]+}}, _var32@PAGEOFF<br>
+; CHECK: sub w[[ADDR:[0-9]+]], w[[VAR32]], #3<br>
+; CHECK: ldr w0, [x[[ADDR]]]<br>
+  %addr_int = ptrtoint i32* @var32 to i32<br>
+  %addr_minus_3 = add i32 %addr_int, -3<br>
+  %addr = inttoptr i32 %addr_minus_3 to i32*<br>
+  %val = load i32, i32* %addr, align 1<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i8* @test_got_addr() {<br>
+; CHECK-LABEL: test_got_addr:<br>
+; CHECK: adrp x[[PAGE:[0-9]+]], _var_got@GOTPAGE<br>
+; CHECK: ldr w0, [x[[PAGE]], _var_got@GOTPAGEOFF]<br>
+  ret i8* @var_got<br>
+}<br>
+<br>
+define float @test_va_arg_f32(i8** %list) {<br>
+; CHECK-LABEL: test_va_arg_f32:<br>
+<br>
+; CHECK: ldr w[[START:[0-9]+]], [x0]<br>
+; CHECK: add [[AFTER:w[0-9]+]], w[[START]], #8<br>
+; CHECK: str [[AFTER]], [x0]<br>
+<br>
+  ; Floating point arguments get promoted to double as per C99.<br>
+; CHECK: ldr [[DBL:d[0-9]+]], [x[[START]]]<br>
+; CHECK: fcvt s0, [[DBL]]<br>
+  %res = va_arg i8** %list, float<br>
+  ret float %res<br>
+}<br>
+<br>
+; Interesting point is that the slot is 4 bytes.<br>
+define i8 @test_va_arg_i8(i8** %list) {<br>
+; CHECK-LABEL: test_va_arg_i8:<br>
+<br>
+; CHECK: ldr w[[START:[0-9]+]], [x0]<br>
+; CHECK: add [[AFTER:w[0-9]+]], w[[START]], #4<br>
+; CHECK: str [[AFTER]], [x0]<br>
+<br>
+  ; i8 gets promoted to int (again, as per C99).<br>
+; CHECK: ldr w0, [x[[START]]]<br>
+<br>
+  %res = va_arg i8** %list, i8<br>
+  ret i8 %res<br>
+}<br>
+<br>
+; Interesting point is that the slot needs aligning (again, min size is 4<br>
+; bytes).<br>
+define i64 @test_va_arg_i64(i64** %list) {<br>
+; CHECK-LABEL: test_va_arg_i64:<br>
+<br>
+  ; Update the list for the next user (minimum slot size is 4, but the actual<br>
+  ; argument is 8 which had better be reflected!)<br>
+; CHECK: ldr w[[UNALIGNED_START:[0-9]+]], [x0]<br>
+; CHECK: add [[ALIGN_TMP:x[0-9]+]], x[[UNALIGNED_START]], #7<br>
+; CHECK: and x[[START:[0-9]+]], [[ALIGN_TMP]], #0x1fffffff8<br>
+; CHECK: add w[[AFTER:[0-9]+]], w[[START]], #8<br>
+; CHECK: str w[[AFTER]], [x0]<br>
+<br>
+; CHECK: ldr x0, [x[[START]]]<br>
+<br>
+  %res = va_arg i64** %list, i64<br>
+  ret i64 %res<br>
+}<br>
+<br>
+declare void @bar(...)<br>
+define void @test_va_call(i8 %l, i8 %r, float %in, i8* %ptr) {<br>
+; CHECK-LABEL: test_va_call:<br>
+; CHECK: add [[SUM:w[0-9]+]], {{w[0-9]+}}, w1<br>
+<br>
+; CHECK-DAG: str w2, [sp, #32]<br>
+; CHECK-DAG: str xzr, [sp, #24]<br>
+; CHECK-DAG: str s0, [sp, #16]<br>
+; CHECK-DAG: str xzr, [sp, #8]<br>
+; CHECK-DAG: str [[SUM]], [sp]<br>
+<br>
+  ; Add them to ensure real promotion occurs.<br>
+  %sum = add i8 %l, %r<br>
+  call void(...) @bar(i8 %sum, i64 0, float %in, double 0.0, i8* %ptr)<br>
+  ret void<br>
+}<br>
+<br>
+declare i8* @llvm.frameaddress(i32)<br>
+<br>
+define i8* @test_frameaddr() {<br>
+; CHECK-LABEL: test_frameaddr:<br>
+; CHECK: ldr {{w0|x0}}, [x29]<br>
+  %val = call i8* @llvm.frameaddress(i32 1)<br>
+  ret i8* %val<br>
+}<br>
+<br>
+declare i8* @llvm.returnaddress(i32)<br>
+<br>
+define i8* @test_toplevel_returnaddr() {<br>
+; CHECK-LABEL: test_toplevel_returnaddr:<br>
+; CHECK: mov x0, x30<br>
+  %val = call i8* @llvm.returnaddress(i32 0)<br>
+  ret i8* %val<br>
+}<br>
+<br>
+define i8* @test_deep_returnaddr() {<br>
+; CHECK-LABEL: test_deep_returnaddr:<br>
+; CHECK: ldr x[[FRAME_REC:[0-9]+]], [x29]<br>
+; CHECK: ldr x0, [x[[FRAME_REC]], #8]<br>
+  %val = call i8* @llvm.returnaddress(i32 1)<br>
+  ret i8* %val<br>
+}<br>
+<br>
+define void @test_indirect_call(void()* %func) {<br>
+; CHECK-LABEL: test_indirect_call:<br>
+; CHECK: blr x0<br>
+  call void() %func()<br>
+  ret void<br>
+}<br>
+<br>
+; Safe to use the unextended address here<br>
+define void @test_indirect_safe_call(i32* %weird_funcs) {<br>
+; CHECK-LABEL: test_indirect_safe_call:<br>
+; CHECK: add w[[ADDR32:[0-9]+]], w0, #4<br>
+; CHECK-OPT-NOT: ubfx<br>
+; CHECK: blr x[[ADDR32]]<br>
+  %addr = getelementptr i32, i32* %weird_funcs, i32 1<br>
+  %func = bitcast i32* %addr to void()*<br>
+  call void() %func()<br>
+  ret void<br>
+}<br>
+<br>
+declare void @simple()<br>
+define void @test_simple_tail_call() {<br>
+; CHECK-LABEL: test_simple_tail_call:<br>
+; CHECK: b _simple<br>
+  tail call void @simple()<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_indirect_tail_call(void()* %func) {<br>
+; CHECK-LABEL: test_indirect_tail_call:<br>
+; CHECK: br x0<br>
+  tail call void() %func()<br>
+  ret void<br>
+}<br>
+<br>
+; Safe to use the unextended address here<br>
+define void @test_indirect_safe_tail_call(i32* %weird_funcs) {<br>
+; CHECK-LABEL: test_indirect_safe_tail_call:<br>
+; CHECK: add w[[ADDR32:[0-9]+]], w0, #4<br>
+; CHECK-OPT-NOT: ubfx<br>
+; CHECK-OPT: br x[[ADDR32]]<br>
+  %addr = getelementptr i32, i32* %weird_funcs, i32 1<br>
+  %func = bitcast i32* %addr to void()*<br>
+  tail call void() %func()<br>
+  ret void<br>
+}<br>
+<br>
+; For the "armv7k" slice, Clang will be emitting some small structs as [N x<br>
+; i32]. For ABI compatibility with arm64_32 these need to be passed in *X*<br>
+; registers (e.g. [2 x i32] would be packed into a single register).<br>
+<br>
+define i32 @test_in_smallstruct_low([3 x i32] %in) {<br>
+; CHECK-LABEL: test_in_smallstruct_low:<br>
+; CHECK: mov x0, x1<br>
+  %val = extractvalue [3 x i32] %in, 2<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i32 @test_in_smallstruct_high([3 x i32] %in) {<br>
+; CHECK-LABEL: test_in_smallstruct_high:<br>
+; CHECK: lsr x0, x0, #32<br>
+  %val = extractvalue [3 x i32] %in, 1<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; The 64-bit DarwinPCS ABI has the quirk that structs on the stack are always<br>
+; 64-bit aligned. This must not happen for arm64_32 since othwerwise va_arg will<br>
+; be incompatible with the armv7k ABI.<br>
+define i32 @test_in_smallstruct_stack([8 x i64], i32, [3 x i32] %in) {<br>
+; CHECK-LABEL: test_in_smallstruct_stack:<br>
+; CHECK: ldr w0, [sp, #4]<br>
+  %val = extractvalue [3 x i32] %in, 0<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define [2 x i32] @test_ret_smallstruct([3 x i32] %in) {<br>
+; CHECK-LABEL: test_ret_smallstruct:<br>
+; CHECK: mov x0, #1<br>
+; CHECK: movk x0, #2, lsl #32<br>
+<br>
+  ret [2 x i32] [i32 1, i32 2]<br>
+}<br>
+<br>
+declare void @smallstruct_callee([4 x i32])<br>
+define void @test_call_smallstruct() {<br>
+; CHECK-LABEL: test_call_smallstruct:<br>
+; CHECK: mov x0, #1<br>
+; CHECK: movk x0, #2, lsl #32<br>
+; CHECK: mov x1, #3<br>
+; CHECK: movk x1, #4, lsl #32<br>
+; CHECK: bl _smallstruct_callee<br>
+<br>
+  call void @smallstruct_callee([4 x i32] [i32 1, i32 2, i32 3, i32 4])<br>
+  ret void<br>
+}<br>
+<br>
+declare void @smallstruct_callee_stack([8 x i64], i32, [2 x i32])<br>
+define void @test_call_smallstruct_stack() {<br>
+; CHECK-LABEL: test_call_smallstruct_stack:<br>
+; CHECK: mov [[VAL:x[0-9]+]], #1<br>
+; CHECK: movk [[VAL]], #2, lsl #32<br>
+; CHECK: stur [[VAL]], [sp, #4]<br>
+<br>
+  call void @smallstruct_callee_stack([8 x i64] undef, i32 undef, [2 x i32] [i32 1, i32 2])<br>
+  ret void<br>
+}<br>
+<br>
+declare [3 x i32] @returns_smallstruct()<br>
+define i32 @test_use_smallstruct_low() {<br>
+; CHECK-LABEL: test_use_smallstruct_low:<br>
+; CHECK: bl _returns_smallstruct<br>
+; CHECK: mov x0, x1<br>
+<br>
+  %struct = call [3 x i32] @returns_smallstruct()<br>
+  %val = extractvalue [3 x i32] %struct, 2<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i32 @test_use_smallstruct_high() {<br>
+; CHECK-LABEL: test_use_smallstruct_high:<br>
+; CHECK: bl _returns_smallstruct<br>
+; CHECK: lsr x0, x0, #32<br>
+<br>
+  %struct = call [3 x i32] @returns_smallstruct()<br>
+  %val = extractvalue [3 x i32] %struct, 1<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; If a small struct can't be allocated to x0-x7, the remaining registers should<br>
+; be marked as unavailable and subsequent GPR arguments should also be on the<br>
+; stack. Obviously the struct itself should be passed entirely on the stack.<br>
+define i32 @test_smallstruct_padding([7 x i64], [4 x i32] %struct, i32 %in) {<br>
+; CHECK-LABEL: test_smallstruct_padding:<br>
+; CHECK-DAG: ldr [[IN:w[0-9]+]], [sp, #16]<br>
+; CHECK-DAG: ldr [[LHS:w[0-9]+]], [sp]<br>
+; CHECK: add w0, [[LHS]], [[IN]]<br>
+  %lhs = extractvalue [4 x i32] %struct, 0<br>
+  %sum = add i32 %lhs, %in<br>
+  ret i32 %sum<br>
+}<br>
+<br>
+declare void @take_small_smallstruct(i64, [1 x i32])<br>
+define void @test_small_smallstruct() {<br>
+; CHECK-LABEL: test_small_smallstruct:<br>
+; CHECK-DAG: mov w0, #1<br>
+; CHECK-DAG: mov w1, #2<br>
+; CHECK: bl _take_small_smallstruct<br>
+  call void @take_small_smallstruct(i64 1, [1 x i32] [i32 2])<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_bare_frameaddr(i8** %addr) {<br>
+; CHECK-LABEL: test_bare_frameaddr:<br>
+; CHECK: add x[[LOCAL:[0-9]+]], sp, #{{[0-9]+}}<br>
+; CHECK: str w[[LOCAL]],<br>
+<br>
+  %ptr = alloca i8<br>
+  store i8* %ptr, i8** %addr, align 4<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_sret_use([8 x i64]* sret %out) {<br>
+; CHECK-LABEL: test_sret_use:<br>
+; CHECK: str xzr, [x8]<br>
+  %addr = getelementptr [8 x i64], [8 x i64]* %out, i32 0, i32 0<br>
+  store i64 0, i64* %addr<br>
+  ret void<br>
+}<br>
+<br>
+define i64 @test_sret_call() {<br>
+; CHECK-LABEL: test_sret_call:<br>
+; CHECK: mov x8, sp<br>
+; CHECK: bl _test_sret_use<br>
+  %arr = alloca [8 x i64]<br>
+  call void @test_sret_use([8 x i64]* sret %arr)<br>
+<br>
+  %addr = getelementptr [8 x i64], [8 x i64]* %arr, i32 0, i32 0<br>
+  %val = load i64, i64* %addr<br>
+  ret i64 %val<br>
+}<br>
+<br>
+define double @test_constpool() {<br>
+; CHECK-LABEL: test_constpool:<br>
+; CHECK: adrp x[[PAGE:[0-9]+]], [[POOL:lCPI[0-9]+_[0-9]+]]@PAGE<br>
+; CHECK: ldr d0, [x[[PAGE]], [[POOL]]@PAGEOFF]<br>
+  ret double 1.0e-6<br>
+}<br>
+<br>
+define i8* @test_blockaddress() {<br>
+; CHECK-LABEL: test_blockaddress:<br>
+; CHECK: [[BLOCK:Ltmp[0-9]+]]:<br>
+; CHECK: adrp [[PAGE:x[0-9]+]], [[BLOCK]]@PAGE<br>
+; CHECK: add x0, [[PAGE]], [[BLOCK]]@PAGEOFF<br>
+  br label %dest<br>
+dest:<br>
+  ret i8* blockaddress(@test_blockaddress, %dest)<br>
+}<br>
+<br>
+define i8* @test_indirectbr(i8* %dest) {<br>
+; CHECK-LABEL: test_indirectbr:<br>
+; CHECK: br x0<br>
+  indirectbr i8* %dest, [label %true, label %false]<br>
+<br>
+true:<br>
+  ret i8* blockaddress(@test_indirectbr, %true)<br>
+false:<br>
+  ret i8* blockaddress(@test_indirectbr, %false)<br>
+}<br>
+<br>
+; ISelDAGToDAG tries to fold an offset FI load (in this case var+4) into the<br>
+; actual load instruction. This needs to be done slightly carefully since we<br>
+; claim the FI in the process -- it doesn't need extending.<br>
+define float @test_frameindex_offset_load() {<br>
+; CHECK-LABEL: test_frameindex_offset_load:<br>
+; CHECK: ldr s0, [sp, #4]<br>
+  %arr = alloca float, i32 4, align 8<br>
+  %addr = getelementptr inbounds float, float* %arr, i32 1<br>
+<br>
+  %val = load float, float* %addr, align 4<br>
+  ret float %val<br>
+}<br>
+<br>
+define void @test_unaligned_frameindex_offset_store() {<br>
+; CHECK-LABEL: test_unaligned_frameindex_offset_store:<br>
+; CHECK: mov x[[TMP:[0-9]+]], sp<br>
+; CHECK: orr w[[ADDR:[0-9]+]], w[[TMP]], #0x2<br>
+; CHECK: mov [[VAL:w[0-9]+]], #42<br>
+; CHECK: str [[VAL]], [x[[ADDR]]]<br>
+  %arr = alloca [4 x i32]<br>
+<br>
+  %<a href="http://addr.int" rel="noreferrer" target="_blank">addr.int</a> = ptrtoint [4 x i32]* %arr to i32<br>
+  %addr.nextint = add nuw i32 %<a href="http://addr.int" rel="noreferrer" target="_blank">addr.int</a>, 2<br>
+  %addr.next = inttoptr i32 %addr.nextint to i32*<br>
+  store i32 42, i32* %addr.next<br>
+  ret void<br>
+}<br>
+<br>
+<br>
+define {i64, i64*} @test_pre_idx(i64* %addr) {<br>
+; CHECK-LABEL: test_pre_idx:<br>
+<br>
+; CHECK: add w[[ADDR:[0-9]+]], w0, #8<br>
+; CHECK: ldr x0, [x[[ADDR]]]<br>
+  %<a href="http://addr.int" rel="noreferrer" target="_blank">addr.int</a> = ptrtoint i64* %addr to i32<br>
+  %<a href="http://addr.next.int" rel="noreferrer" target="_blank">addr.next.int</a> = add nuw i32 %<a href="http://addr.int" rel="noreferrer" target="_blank">addr.int</a>, 8<br>
+  %addr.next = inttoptr i32 %<a href="http://addr.next.int" rel="noreferrer" target="_blank">addr.next.int</a> to i64*<br>
+  %val = load i64, i64* %addr.next<br>
+<br>
+  %tmp = insertvalue {i64, i64*} undef, i64 %val, 0<br>
+  %res = insertvalue {i64, i64*} %tmp, i64* %addr.next, 1<br>
+<br>
+  ret {i64, i64*} %res<br>
+}<br>
+<br>
+; Forming a post-indexed load is invalid here since the GEP needs to work when<br>
+; %addr wraps round to 0.<br>
+define {i64, i64*} @test_invalid_pre_idx(i64* %addr) {<br>
+; CHECK-LABEL: test_invalid_pre_idx:<br>
+; CHECK: add w1, w0, #8<br>
+; CHECK: ldr x0, [x1]<br>
+  %addr.next = getelementptr i64, i64* %addr, i32 1<br>
+  %val = load i64, i64* %addr.next<br>
+<br>
+  %tmp = insertvalue {i64, i64*} undef, i64 %val, 0<br>
+  %res = insertvalue {i64, i64*} %tmp, i64* %addr.next, 1<br>
+<br>
+  ret {i64, i64*} %res<br>
+}<br>
+<br>
+declare void @callee([8 x i32]*)<br>
+define void @test_stack_guard() ssp {<br>
+; CHECK-LABEL: test_stack_guard:<br>
+; CHECK: adrp x[[GUARD_GOTPAGE:[0-9]+]], ___stack_chk_guard@GOTPAGE<br>
+; CHECK: ldr w[[GUARD_ADDR:[0-9]+]], [x[[GUARD_GOTPAGE]], ___stack_chk_guard@GOTPAGEOFF]<br>
+; CHECK: ldr [[GUARD_VAL:w[0-9]+]], [x[[GUARD_ADDR]]]<br>
+; CHECK: stur [[GUARD_VAL]], [x29, #[[GUARD_OFFSET:-[0-9]+]]]<br>
+<br>
+; CHECK: add x0, sp, #{{[0-9]+}}<br>
+; CHECK: bl _callee<br>
+<br>
+; CHECK-OPT: adrp x[[GUARD_GOTPAGE:[0-9]+]], ___stack_chk_guard@GOTPAGE<br>
+; CHECK-OPT: ldr w[[GUARD_ADDR:[0-9]+]], [x[[GUARD_GOTPAGE]], ___stack_chk_guard@GOTPAGEOFF]<br>
+; CHECK-OPT: ldr [[GUARD_VAL:w[0-9]+]], [x[[GUARD_ADDR]]]<br>
+; CHECK-OPT: ldur [[NEW_VAL:w[0-9]+]], [x29, #[[GUARD_OFFSET]]]<br>
+; CHECK-OPT: cmp [[GUARD_VAL]], [[NEW_VAL]]<br>
+; CHECK-OPT: <a href="http://b.ne" rel="noreferrer" target="_blank">b.ne</a> [[FAIL:LBB[0-9]+_[0-9]+]]<br>
+<br>
+; CHECK-OPT: [[FAIL]]:<br>
+; CHECK-OPT-NEXT: bl ___stack_chk_fail<br>
+  %arr = alloca [8 x i32]<br>
+  call void @callee([8 x i32]* %arr)<br>
+  ret void<br>
+}<br>
+<br>
+declare i32 @__gxx_personality_v0(...)<br>
+declare void @eat_landingpad_args(i32, i8*, i32)<br>
+@_ZTI8Whatever = external global i8<br>
+define void @test_landingpad_marshalling() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {<br>
+; CHECK-LABEL: test_landingpad_marshalling:<br>
+; CHECK-OPT: mov x2, x1<br>
+; CHECK-OPT: mov x1, x0<br>
+; CHECK: bl _eat_landingpad_args<br>
+  invoke void @callee([8 x i32]* undef) to label %done unwind label %lpad<br>
+<br>
+lpad:                                             ; preds = %entry<br>
+  %exc = landingpad { i8*, i32 }<br>
+          catch i8* @_ZTI8Whatever<br>
+  %pointer = extractvalue { i8*, i32 } %exc, 0<br>
+  %selector = extractvalue { i8*, i32 } %exc, 1<br>
+  call void @eat_landingpad_args(i32 undef, i8* %pointer, i32 %selector)<br>
+  ret void<br>
+<br>
+done:<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_dynamic_stackalloc() {<br>
+; CHECK-LABEL: test_dynamic_stackalloc:<br>
+; CHECK: sub [[REG:x[0-9]+]], sp, #32<br>
+; CHECK: mov sp, [[REG]]<br>
+; CHECK-OPT-NOT: ubfx<br>
+; CHECK: bl _callee<br>
+  br label %next<br>
+<br>
+next:<br>
+  %val = alloca [8 x i32]<br>
+  call void @callee([8 x i32]* %val)<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_asm_memory(i32* %base.addr) {<br>
+; CHECK-LABEL: test_asm_memory:<br>
+; CHECK: add w[[ADDR:[0-9]+]], w0, #4<br>
+; CHECK: str wzr, [x[[ADDR]]<br>
+  %addr = getelementptr i32, i32* %base.addr, i32 1<br>
+  call void asm sideeffect "str wzr, $0", "*m"(i32* %addr)<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_unsafe_asm_memory(i64 %val) {<br>
+; CHECK-LABEL: test_unsafe_asm_memory:<br>
+; CHECK: and x[[ADDR:[0-9]+]], x0, #0xffffffff<br>
+; CHECK: str wzr, [x[[ADDR]]]<br>
+  %addr_int = trunc i64 %val to i32<br>
+  %addr = inttoptr i32 %addr_int to i32*<br>
+  call void asm sideeffect "str wzr, $0", "*m"(i32* %addr)<br>
+  ret void<br>
+}<br>
+<br>
+define [9 x i8*] @test_demoted_return(i8* %in) {<br>
+; CHECK-LABEL: test_demoted_return:<br>
+; CHECK: str w0, [x8, #32]<br>
+  %res = insertvalue [9 x i8*] undef, i8* %in, 8<br>
+  ret [9 x i8*] %res<br>
+}<br>
+<br>
+define i8* @test_inttoptr(i64 %in) {<br>
+; CHECK-LABEL: test_inttoptr:<br>
+; CHECK: and x0, x0, #0xffffffff<br>
+  %res = inttoptr i64 %in to i8*<br>
+  ret i8* %res<br>
+}<br>
+<br>
+declare i32 @llvm.get.dynamic.area.offset.i32()<br>
+define i32 @test_dynamic_area() {<br>
+; CHECK-LABEL: test_dynamic_area:<br>
+; CHECK: mov w0, wzr<br>
+  %res = call i32 @llvm.get.dynamic.area.offset.i32()<br>
+  ret i32 %res<br>
+}<br>
+<br>
+define void @test_pointer_vec_store(<2 x i8*>* %addr) {<br>
+; CHECK-LABEL: test_pointer_vec_store:<br>
+; CHECK: str xzr, [x0]<br>
+; CHECK-NOT: str<br>
+; CHECK-NOT: stp<br>
+<br>
+  store <2 x i8*> zeroinitializer, <2 x i8*>* %addr, align 16<br>
+  ret void<br>
+}<br>
+<br>
+define <2 x i8*> @test_pointer_vec_load(<2 x i8*>* %addr) {<br>
+; CHECK-LABEL: test_pointer_vec_load:<br>
+; CHECK: ldr d[[TMP:[0-9]+]], [x0]<br>
+; CHECK: ushll.2d v0, v[[TMP]], #0<br>
+  %val = load <2 x i8*>, <2 x i8*>* %addr, align 16<br>
+  ret <2 x i8*> %val<br>
+}<br>
+<br>
+define void @test_inline_asm_mem_pointer(i32* %in) {<br>
+; CHECK-LABEL: test_inline_asm_mem_pointer:<br>
+; CHECK: str w0,<br>
+  tail call void asm sideeffect "ldr x0, $0", "rm"(i32* %in)<br>
+  ret void<br>
+}<br>
+<br>
+<br>
+define void @test_struct_hi(i32 %hi) nounwind {<br>
+; CHECK-LABEL: test_struct_hi:<br>
+; CHECK: mov w[[IN:[0-9]+]], w0<br>
+; CHECK: bl _get_int<br>
+; CHECK-NEXT: bfi x0, x[[IN]], #32, #32<br>
+; CHECK-NEXT: bl _take_pair<br>
+  %val.64 = call i64 @get_int()<br>
+  %val.32 = trunc i64 %val.64 to i32<br>
+<br>
+  %pair.0 = insertvalue [2 x i32] undef, i32 %val.32, 0<br>
+  %pair.1 = insertvalue [2 x i32] %pair.0, i32 %hi, 1<br>
+  call void @take_pair([2 x i32] %pair.1)<br>
+<br>
+  ret void<br>
+}<br>
+declare void @take_pair([2 x i32])<br>
+declare i64 @get_int()<br>
+<br>
+define i1 @test_icmp_ptr(i8* %in) {<br>
+; CHECK-LABEL: test_icmp_ptr<br>
+; CHECK: ubfx x0, x0, #31, #1<br>
+  %res = icmp slt i8* %in, null<br>
+  ret i1 %res<br>
+}<br>
+<br>
+define void @test_multiple_icmp_ptr(i8* %l, i8* %r) {<br>
+; CHECK-LABEL: test_multiple_icmp_ptr:<br>
+; CHECK: tbnz w0, #31, [[FALSEBB:LBB[0-9]+_[0-9]+]]<br>
+; CHECK: tbnz w1, #31, [[FALSEBB]]<br>
+  %tst1 = icmp sgt i8* %l, inttoptr (i32 -1 to i8*)<br>
+  %tst2 = icmp sgt i8* %r, inttoptr (i32 -1 to i8*)<br>
+  %tst = and i1 %tst1, %tst2<br>
+  br i1 %tst, label %true, label %false<br>
+<br>
+true:<br>
+  call void(...) @bar()<br>
+  ret void<br>
+<br>
+false:<br>
+  ret void<br>
+}<br>
+<br>
+define { [18 x i8] }* @test_gep_nonpow2({ [18 x i8] }* %a0, i32 %a1) {<br>
+; CHECK-LABEL: test_gep_nonpow2:<br>
+; CHECK:      mov w[[SIZE:[0-9]+]], #18<br>
+; CHECK-NEXT: smaddl x0, w1, w[[SIZE]], x0<br>
+; CHECK-NEXT: ret<br>
+  %tmp0 = getelementptr inbounds { [18 x i8] }, { [18 x i8] }* %a0, i32 %a1<br>
+  ret { [18 x i8] }* %tmp0<br>
+}<br>
+<br>
+define void @test_bzero(i64 %in)  {<br>
+; CHECK-LABEL: test_bzero:<br>
+; CHECK-DAG: lsr x1, x0, #32<br>
+; CHECK-DAG: and x0, x0, #0xffffffff<br>
+; CHECK: bl _bzero<br>
+<br>
+  %ptr.i32 = trunc i64 %in to i32<br>
+  %size.64 = lshr i64 %in, 32<br>
+  %size = trunc i64 %size.64 to i32<br>
+  %ptr = inttoptr i32 %ptr.i32 to i8*<br>
+  tail call void @llvm.memset.p0i8.i32(i8* align 4 %ptr, i8 0, i32 %size, i1 false)<br>
+  ret void<br>
+}<br>
+<br>
+declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1)<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/fastcc-reserved.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fastcc-reserved.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fastcc-reserved.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/fastcc-reserved.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/fastcc-reserved.ll Thu Sep 12 03:22:23 2019<br>
@@ -4,7 +4,7 @@<br>
 ; call-frame is not reserved (hence disable-fp-elim), but where<br>
 ; callee-pop can occur (hence tailcallopt).<br>
<br>
-declare fastcc void @will_pop([8 x i32], i32 %val)<br>
+declare fastcc void @will_pop([8 x i64], i32 %val)<br>
<br>
 define fastcc void @foo(i32 %in) {<br>
 ; CHECK-LABEL: foo:<br>
@@ -18,7 +18,7 @@ define fastcc void @foo(i32 %in) {<br>
 ; Reserve space for call-frame:<br>
 ; CHECK: str w{{[0-9]+}}, [sp, #-16]!<br>
<br>
-  call fastcc void @will_pop([8 x i32] undef, i32 42)<br>
+  call fastcc void @will_pop([8 x i64] undef, i32 42)<br>
 ; CHECK: bl will_pop<br>
<br>
 ; Since @will_pop is fastcc with tailcallopt, it will put the stack<br>
@@ -31,7 +31,7 @@ define fastcc void @foo(i32 %in) {<br>
   ret void<br>
 }<br>
<br>
-declare void @wont_pop([8 x i32], i32 %val)<br>
+declare void @wont_pop([8 x i64], i32 %val)<br>
<br>
 define void @foo1(i32 %in) {<br>
 ; CHECK-LABEL: foo1:<br>
@@ -44,7 +44,7 @@ define void @foo1(i32 %in) {<br>
 ; Reserve space for call-frame<br>
 ; CHECK: str w{{[0-9]+}}, [sp, #-16]!<br>
<br>
-  call void @wont_pop([8 x i32] undef, i32 42)<br>
+  call void @wont_pop([8 x i64] undef, i32 42)<br>
 ; CHECK: bl wont_pop<br>
<br>
 ; This time we *do* need to unreserve the call-frame<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/fastcc.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fastcc.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fastcc.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/fastcc.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/fastcc.ll Thu Sep 12 03:22:23 2019<br>
@@ -18,7 +18,7 @@ define fastcc void @func_stack0() {<br>
 ; CHECK-TAIL: str w{{[0-9]+}}, [sp]<br>
<br>
<br>
-  call fastcc void @func_stack8([8 x i32] undef, i32 42)<br>
+  call fastcc void @func_stack8([8 x i64] undef, i32 42)<br>
 ; CHECK:  bl func_stack8<br>
 ; CHECK-NOT: sub sp, sp,<br>
 ; CHECK-NOT: [sp, #{{[-0-9]+}}]!<br>
@@ -28,7 +28,7 @@ define fastcc void @func_stack0() {<br>
 ; CHECK-TAIL: stp xzr, xzr, [sp, #-16]!<br>
<br>
<br>
-  call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9)<br>
+  call fastcc void @func_stack32([8 x i64] undef, i128 0, i128 9)<br>
 ; CHECK: bl func_stack32<br>
 ; CHECK-NOT: sub sp, sp,<br>
<br>
@@ -56,7 +56,7 @@ define fastcc void @func_stack0() {<br>
 ; CHECK-TAIL-NEXT: ret<br>
 }<br>
<br>
-define fastcc void @func_stack8([8 x i32], i32 %stacked) {<br>
+define fastcc void @func_stack8([8 x i64], i32 %stacked) {<br>
 ; CHECK-LABEL: func_stack8:<br>
 ; CHECK: sub sp, sp, #48<br>
 ; CHECK: stp x29, x30, [sp, #32]<br>
@@ -71,7 +71,7 @@ define fastcc void @func_stack8([8 x i32<br>
 ; CHECK-TAIL: str w{{[0-9]+}}, [sp]<br>
<br>
<br>
-  call fastcc void @func_stack8([8 x i32] undef, i32 42)<br>
+  call fastcc void @func_stack8([8 x i64] undef, i32 42)<br>
 ; CHECK:  bl func_stack8<br>
 ; CHECK-NOT: sub sp, sp,<br>
 ; CHECK-NOT: [sp, #{{[-0-9]+}}]!<br>
@@ -82,7 +82,7 @@ define fastcc void @func_stack8([8 x i32<br>
 ; CHECK-TAIL: stp xzr, xzr, [sp, #-16]!<br>
<br>
<br>
-  call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9)<br>
+  call fastcc void @func_stack32([8 x i64] undef, i128 0, i128 9)<br>
 ; CHECK: bl func_stack32<br>
 ; CHECK-NOT: sub sp, sp,<br>
<br>
@@ -109,7 +109,7 @@ define fastcc void @func_stack8([8 x i32<br>
 ; CHECK-TAIL-NEXT: ret<br>
 }<br>
<br>
-define fastcc void @func_stack32([8 x i32], i128 %stacked0, i128 %stacked1) {<br>
+define fastcc void @func_stack32([8 x i64], i128 %stacked0, i128 %stacked1) {<br>
 ; CHECK-LABEL: func_stack32:<br>
 ; CHECK: add x29, sp, #32<br>
<br>
@@ -117,7 +117,7 @@ define fastcc void @func_stack32([8 x i3<br>
 ; CHECK-TAIL: add x29, sp, #32<br>
<br>
<br>
-  call fastcc void @func_stack8([8 x i32] undef, i32 42)<br>
+  call fastcc void @func_stack8([8 x i64] undef, i32 42)<br>
 ; CHECK:  bl func_stack8<br>
 ; CHECK-NOT: sub sp, sp,<br>
 ; CHECK-NOT: [sp, #{{[-0-9]+}}]!<br>
@@ -127,7 +127,7 @@ define fastcc void @func_stack32([8 x i3<br>
 ; CHECK-TAIL: stp xzr, xzr, [sp, #-16]!<br>
<br>
<br>
-  call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9)<br>
+  call fastcc void @func_stack32([8 x i64] undef, i128 0, i128 9)<br>
 ; CHECK: bl func_stack32<br>
 ; CHECK-NOT: sub sp, sp,<br>
<br>
@@ -155,7 +155,7 @@ define fastcc void @func_stack32([8 x i3<br>
 }<br>
<br>
 ; Check that arg stack pop is done after callee-save restore when no frame pointer is used.<br>
-define fastcc void @func_stack32_leaf([8 x i32], i128 %stacked0, i128 %stacked1) {<br>
+define fastcc void @func_stack32_leaf([8 x i64], i128 %stacked0, i128 %stacked1) {<br>
 ; CHECK-LABEL: func_stack32_leaf:<br>
 ; CHECK: str     x20, [sp, #-16]!<br>
 ; CHECK: nop<br>
@@ -186,7 +186,7 @@ define fastcc void @func_stack32_leaf([8<br>
 }<br>
<br>
 ; Check that arg stack pop is done after callee-save restore when no frame pointer is used.<br>
-define fastcc void @func_stack32_leaf_local([8 x i32], i128 %stacked0, i128 %stacked1) {<br>
+define fastcc void @func_stack32_leaf_local([8 x i64], i128 %stacked0, i128 %stacked1) {<br>
 ; CHECK-LABEL: func_stack32_leaf_local:<br>
 ; CHECK: sub     sp, sp, #32<br>
 ; CHECK-NEXT: str     x20, [sp, #16]<br>
@@ -222,7 +222,7 @@ define fastcc void @func_stack32_leaf_lo<br>
 }<br>
<br>
 ; Check that arg stack pop is done after callee-save restore when no frame pointer is used.<br>
-define fastcc void @func_stack32_leaf_local_nocs([8 x i32], i128 %stacked0, i128 %stacked1) {<br>
+define fastcc void @func_stack32_leaf_local_nocs([8 x i64], i128 %stacked0, i128 %stacked1) {<br>
 ; CHECK-LABEL: func_stack32_leaf_local_nocs:<br>
 ; CHECK: sub     sp, sp, #16<br>
 ; CHECK: add     sp, sp, #16<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/jump-table-32.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/jump-table-32.ll?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/jump-table-32.ll?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/jump-table-32.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/jump-table-32.ll Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,42 @@<br>
+; RUN: llc -verify-machineinstrs -o - %s -mtriple=arm64_32-apple-ios7.0 -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s<br>
+<br>
+define i32 @test_jumptable(i32 %in) {<br>
+; CHECK: test_jumptable<br>
+<br>
+  switch i32 %in, label %def [<br>
+    i32 0, label %lbl1<br>
+    i32 1, label %lbl2<br>
+    i32 2, label %lbl3<br>
+    i32 4, label %lbl4<br>
+  ]<br>
+; CHECK: adrp    [[JTPAGE:x[0-9]+]], LJTI0_0@PAGE<br>
+; CHECK: mov     w[[INDEX:[0-9]+]], w0<br>
+; CHECK: add     x[[JT:[0-9]+]], [[JTPAGE]], LJTI0_0@PAGEOFF<br>
+; CHECK: adr     [[BASE_BLOCK:x[0-9]+]], LBB0_2<br>
+; CHECK: ldrb    w[[OFFSET:[0-9]+]], [x[[JT]], x[[INDEX]]]<br>
+; CHECK: add     [[DEST:x[0-9]+]], [[BASE_BLOCK]], x[[OFFSET]], lsl #2<br>
+; CHECK: br      [[DEST]]<br>
+<br>
+def:<br>
+  ret i32 0<br>
+<br>
+lbl1:<br>
+  ret i32 1<br>
+<br>
+lbl2:<br>
+  ret i32 2<br>
+<br>
+lbl3:<br>
+  ret i32 4<br>
+<br>
+lbl4:<br>
+  ret i32 8<br>
+<br>
+}<br>
+<br>
+; CHECK: LJTI0_0:<br>
+; CHECK-NEXT: .byte<br>
+; CHECK-NEXT: .byte<br>
+; CHECK-NEXT: .byte<br>
+; CHECK-NEXT: .byte<br>
+; CHECK-NEXT: .byte<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/sibling-call.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/sibling-call.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/sibling-call.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/sibling-call.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/sibling-call.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,8 +1,8 @@<br>
 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -aarch64-enable-ldst-opt=0 | FileCheck %s<br>
<br>
 declare void @callee_stack0()<br>
-declare void @callee_stack8([8 x i32], i64)<br>
-declare void @callee_stack16([8 x i32], i64, i64)<br>
+declare void @callee_stack8([8 x i64], i64)<br>
+declare void @callee_stack16([8 x i64], i64, i64)<br>
<br>
 define void @caller_to0_from0() nounwind {<br>
 ; CHECK-LABEL: caller_to0_from0:<br>
@@ -12,7 +12,7 @@ define void @caller_to0_from0() nounwind<br>
 ; CHECK-NEXT: b callee_stack0<br>
 }<br>
<br>
-define void @caller_to0_from8([8 x i32], i64) nounwind{<br>
+define void @caller_to0_from8([8 x i64], i64) nounwind{<br>
 ; CHECK-LABEL: caller_to0_from8:<br>
 ; CHECK-NEXT: // %bb.<br>
<br>
@@ -26,51 +26,51 @@ define void @caller_to8_from0() {<br>
<br>
 ; Caller isn't going to clean up any extra stack we allocate, so it<br>
 ; can't be a tail call.<br>
-  tail call void @callee_stack8([8 x i32] undef, i64 42)<br>
+  tail call void @callee_stack8([8 x i64] undef, i64 42)<br>
   ret void<br>
 ; CHECK: bl callee_stack8<br>
 }<br>
<br>
-define void @caller_to8_from8([8 x i32], i64 %a) {<br>
+define void @caller_to8_from8([8 x i64], i64 %a) {<br>
 ; CHECK-LABEL: caller_to8_from8:<br>
 ; CHECK-NOT: sub sp, sp,<br>
<br>
 ; This should reuse our stack area for the 42<br>
-  tail call void @callee_stack8([8 x i32] undef, i64 42)<br>
+  tail call void @callee_stack8([8 x i64] undef, i64 42)<br>
   ret void<br>
 ; CHECK: str {{x[0-9]+}}, [sp]<br>
 ; CHECK-NEXT: b callee_stack8<br>
 }<br>
<br>
-define void @caller_to16_from8([8 x i32], i64 %a) {<br>
+define void @caller_to16_from8([8 x i64], i64 %a) {<br>
 ; CHECK-LABEL: caller_to16_from8:<br>
<br>
 ; Shouldn't be a tail call: we can't use SP+8 because our caller might<br>
 ; have something there. This may sound obvious but implementation does<br>
 ; some funky aligning.<br>
-  tail call void @callee_stack16([8 x i32] undef, i64 undef, i64 undef)<br>
+  tail call void @callee_stack16([8 x i64] undef, i64 undef, i64 undef)<br>
 ; CHECK: bl callee_stack16<br>
   ret void<br>
 }<br>
<br>
-define void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) {<br>
+define void @caller_to8_from24([8 x i64], i64 %a, i64 %b, i64 %c) {<br>
 ; CHECK-LABEL: caller_to8_from24:<br>
 ; CHECK-NOT: sub sp, sp<br>
<br>
 ; Reuse our area, putting "42" at incoming sp<br>
-  tail call void @callee_stack8([8 x i32] undef, i64 42)<br>
+  tail call void @callee_stack8([8 x i64] undef, i64 42)<br>
   ret void<br>
 ; CHECK: str {{x[0-9]+}}, [sp]<br>
 ; CHECK-NEXT: b callee_stack8<br>
 }<br>
<br>
-define void @caller_to16_from16([8 x i32], i64 %a, i64 %b) {<br>
+define void @caller_to16_from16([8 x i64], i64 %a, i64 %b) {<br>
 ; CHECK-LABEL: caller_to16_from16:<br>
 ; CHECK-NOT: sub sp, sp,<br>
<br>
 ; Here we want to make sure that both loads happen before the stores:<br>
 ; otherwise either %a or %b will be wrongly clobbered.<br>
-  tail call void @callee_stack16([8 x i32] undef, i64 %b, i64 %a)<br>
+  tail call void @callee_stack16([8 x i64] undef, i64 %b, i64 %a)<br>
   ret void<br>
<br>
 ; CHECK: ldr [[VAL0:x[0-9]+]],<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/swift-return.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swift-return.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swift-return.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/swift-return.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/swift-return.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,5 +1,7 @@<br>
 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s<br>
 ; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s --check-prefix=CHECK-O0<br>
+; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s<br>
+; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s --check-prefix=CHECK-O0<br>
<br>
 ; CHECK-LABEL: test1<br>
 ; CHECK: bl      _gen<br>
@@ -8,7 +10,7 @@<br>
 ; CHECK-O0-LABEL: test1<br>
 ; CHECK-O0: bl      _gen<br>
 ; CHECK-O0: sxth    [[TMP:w.*]], w0<br>
-; CHECK-O0: add     w8, [[TMP]], w1, sxtb<br>
+; CHECK-O0: add     {{w[0-9]+}}, [[TMP]], w1, sxtb<br>
 define i16 @test1(i32) {<br>
 entry:<br>
   %call = call swiftcc { i16, i8 } @gen(i32 %0)<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/swiftcc.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swiftcc.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swiftcc.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/swiftcc.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/swiftcc.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,5 +1,7 @@<br>
 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s<br>
 ; RUN: llc -O0 -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s<br>
+; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s<br>
+; RUN: llc -O0 -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s<br>
<br>
 ; CHECK: t1<br>
 ; CHECK: fadd s0, s0, s1<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/swifterror.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swifterror.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swifterror.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/swifterror.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/swifterror.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,5 +1,7 @@<br>
-; RUN: llc -fast-isel-sink-local-values -verify-machineinstrs -frame-pointer=all -enable-shrink-wrap=false < %s -mtriple=aarch64-apple-ios -disable-post-ra | FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-APPLE %s<br>
-; RUN: llc -fast-isel-sink-local-values -verify-machineinstrs -frame-pointer=all -O0 -fast-isel < %s -mtriple=aarch64-apple-ios -disable-post-ra | FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-O0 %s<br>
+; RUN: llc -fast-isel-sink-local-values -verify-machineinstrs -frame-pointer=all -enable-shrink-wrap=false < %s -mtriple=aarch64-apple-ios -disable-post-ra | FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-APPLE --check-prefix=CHECK-APPLE-AARCH64 %s<br>
+; RUN: llc -fast-isel-sink-local-values -verify-machineinstrs -frame-pointer=all -O0 -fast-isel < %s -mtriple=aarch64-apple-ios -disable-post-ra | FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-O0 --check-prefix=CHECK-O0-AARCH64 %s<br>
+; RUN: llc -fast-isel-sink-local-values -verify-machineinstrs -frame-pointer=all -enable-shrink-wrap=false < %s -mtriple=arm64_32-apple-ios -disable-post-ra | FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-APPLE --check-prefix=CHECK-APPLE-ARM64_32 %s<br>
+; RUN: llc -fast-isel-sink-local-values -verify-machineinstrs -O0 -fast-isel < %s -mtriple=arm64_32-apple-ios -disable-post-ra | FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-O0 --check-prefix=CHECK-O0-ARM64_32 %s<br>
<br>
 declare i8* @malloc(i64)<br>
 declare void @free(i8*)<br>
@@ -40,7 +42,8 @@ define float @caller(i8* %error_ref) {<br>
 ; CHECK-APPLE: mov x21, xzr<br>
 ; CHECK-APPLE: bl {{.*}}foo<br>
 ; CHECK-APPLE: mov x0, x21<br>
-; CHECK-APPLE: cbnz x21<br>
+; CHECK-APPLE-AARCH64: cbnz x21<br>
+; CHECK-APPLE-ARM64_32: cbnz w0<br>
 ; Access part of the error object and save it to error_ref<br>
 ; CHECK-APPLE: ldrb [[CODE:w[0-9]+]], [x0, #8]<br>
 ; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]<br>
@@ -50,7 +53,8 @@ define float @caller(i8* %error_ref) {<br>
 ; CHECK-O0: mov x21<br>
 ; CHECK-O0: bl {{.*}}foo<br>
 ; CHECK-O0: mov [[ID:x[0-9]+]], x21<br>
-; CHECK-O0: cbnz x21<br>
+; CHECK-O0-AARCH64: cbnz x21<br>
+; CHECK-O0-ARM64_32: cmp x21, #0<br>
 entry:<br>
   %error_ptr_ref = alloca swifterror %swift_error*<br>
   store %swift_error* null, %swift_error** %error_ptr_ref<br>
@@ -76,7 +80,8 @@ define float @caller2(i8* %error_ref) {<br>
 ; CHECK-APPLE: fmov [[CMP:s[0-9]+]], #1.0<br>
 ; CHECK-APPLE: mov x21, xzr<br>
 ; CHECK-APPLE: bl {{.*}}foo<br>
-; CHECK-APPLE: cbnz x21<br>
+; CHECK-APPLE-AARCH64: cbnz x21<br>
+; CHECK-APPLE-ARM64_32: cbnz w21<br>
 ; CHECK-APPLE: fcmp s0, [[CMP]]<br>
 ; CHECK-APPLE: b.le<br>
 ; Access part of the error object and save it to error_ref<br>
@@ -89,7 +94,8 @@ define float @caller2(i8* %error_ref) {<br>
 ; CHECK-O0: mov x21<br>
 ; CHECK-O0: bl {{.*}}foo<br>
 ; CHECK-O0: mov [[ID:x[0-9]+]], x21<br>
-; CHECK-O0: cbnz x21<br>
+; CHECK-O0-AARCH64: cbnz x21<br>
+; CHECK-O0-ARM64_32: cmp x21, #0<br>
 entry:<br>
   %error_ptr_ref = alloca swifterror %swift_error*<br>
   br label %bb_loop<br>
@@ -171,29 +177,52 @@ define float @foo_loop(%swift_error** sw<br>
 ; CHECK-APPLE: mov x21, x0<br>
 ; CHECK-APPLE: ret<br>
<br>
-; CHECK-O0-LABEL: foo_loop:<br>
+; CHECK-O0-AARCH64-LABEL: foo_loop:<br>
 ; spill x21<br>
-; CHECK-O0: str x21, [sp, [[SLOT:#[0-9]+]]]<br>
-; CHECK-O0: b [[BB1:[A-Za-z0-9_]*]]<br>
-; CHECK-O0: [[BB1]]:<br>
-; CHECK-O0: ldr     x0, [sp, [[SLOT]]]<br>
-; CHECK-O0: str     x0, [sp, [[SLOT2:#[0-9]+]]]<br>
-; CHECK-O0: cbz {{.*}}, [[BB2:[A-Za-z0-9_]*]]<br>
-; CHECK-O0: mov w{{.*}}, #16<br>
-; CHECK-O0: malloc<br>
-; CHECK-O0: mov [[ID:x[0-9]+]], x0<br>
-; CHECK-O0: strb w{{.*}}, [{{.*}}[[ID]], #8]<br>
+; CHECK-O0-AARCH64: str x21, [sp, [[SLOT:#[0-9]+]]]<br>
+; CHECK-O0-AARCH64: b [[BB1:[A-Za-z0-9_]*]]<br>
+; CHECK-O0-AARCH64: [[BB1]]:<br>
+; CHECK-O0-AARCH64: ldr     x0, [sp, [[SLOT]]]<br>
+; CHECK-O0-AARCH64: str     x0, [sp, [[SLOT2:#[0-9]+]]]<br>
+; CHECK-O0-AARCH64: cbz {{.*}}, [[BB2:[A-Za-z0-9_]*]]<br>
+; CHECK-O0-AARCH64: mov w{{.*}}, #16<br>
+; CHECK-O0-AARCH64: malloc<br>
+; CHECK-O0-AARCH64: mov [[ID:x[0-9]+]], x0<br>
+; CHECK-O0-AARCH64: strb w{{.*}}, [{{.*}}[[ID]], #8]<br>
 ; spill x0<br>
-; CHECK-O0: str x0, [sp, [[SLOT2]]]<br>
-; CHECK-O0:[[BB2]]:<br>
-; CHECK-O0: ldr     x0, [sp, [[SLOT2]]]<br>
-; CHECK-O0: fcmp<br>
-; CHECK-O0: str     x0, [sp]<br>
-; CHECK-O0: b.le [[BB1]]<br>
+; CHECK-O0-AARCH64: str x0, [sp, [[SLOT2]]]<br>
+; CHECK-O0-AARCH64:[[BB2]]:<br>
+; CHECK-O0-AARCH64: ldr     x0, [sp, [[SLOT2]]]<br>
+; CHECK-O0-AARCH64: fcmp<br>
+; CHECK-O0-AARCH64: str     x0, [sp]<br>
+; CHECK-O0-AARCH64: b.le [[BB1]]<br>
 ; reload from stack<br>
-; CHECK-O0: ldr [[ID3:x[0-9]+]], [sp]<br>
-; CHECK-O0: mov x21, [[ID3]]<br>
-; CHECK-O0: ret<br>
+; CHECK-O0-AARCH64: ldr [[ID3:x[0-9]+]], [sp]<br>
+; CHECK-O0-AARCH64: mov x21, [[ID3]]<br>
+; CHECK-O0-AARCH64: ret<br>
+<br>
+; CHECK-O0-ARM64_32-LABEL: foo_loop:<br>
+; spill x21<br>
+; CHECK-O0-ARM64_32: str x21, [sp, [[SLOT:#[0-9]+]]]<br>
+; CHECK-O0-ARM64_32: b [[BB1:[A-Za-z0-9_]*]]<br>
+; CHECK-O0-ARM64_32: [[BB1]]:<br>
+; CHECK-O0-ARM64_32: ldr     x0, [sp, [[SLOT]]]<br>
+; CHECK-O0-ARM64_32: str     x0, [sp, [[SLOT2:#[0-9]+]]]<br>
+; CHECK-O0-ARM64_32: cbz {{.*}}, [[BB2:[A-Za-z0-9_]*]]<br>
+; CHECK-O0-ARM64_32: mov w{{.*}}, #16<br>
+; CHECK-O0-ARM64_32: malloc<br>
+; CHECK-O0-ARM64_32: mov {{.*}}, x0<br>
+; CHECK-O0-ARM64_32: strb w{{.*}},<br>
+; CHECK-O0-ARM64_32:[[BB2]]:<br>
+; CHECK-O0-ARM64_32: ldr     x0, [sp, [[SLOT2]]]<br>
+; CHECK-O0-ARM64_32: fcmp<br>
+; CHECK-O0-ARM64_32: str     x0, [sp[[OFFSET:.*]]]<br>
+; CHECK-O0-ARM64_32: b.le [[BB1]]<br>
+; reload from stack<br>
+; CHECK-O0-ARM64_32: ldr [[ID3:x[0-9]+]], [sp[[OFFSET]]]<br>
+; CHECK-O0-ARM64_32: mov x21, [[ID3]]<br>
+; CHECK-O0-ARM64_32: ret<br>
+<br>
 entry:<br>
   br label %bb_loop<br>
<br>
@@ -261,7 +290,8 @@ define float @caller3(i8* %error_ref) {<br>
 ; CHECK-APPLE: mov x21, xzr<br>
 ; CHECK-APPLE: bl {{.*}}foo_sret<br>
 ; CHECK-APPLE: mov x0, x21<br>
-; CHECK-APPLE: cbnz x21<br>
+; CHECK-APPLE-AARCH64: cbnz x21<br>
+; CHECK-APPLE-ARM64_32: cbnz w0<br>
 ; Access part of the error object and save it to error_ref<br>
 ; CHECK-APPLE: ldrb [[CODE:w[0-9]+]], [x0, #8]<br>
 ; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]<br>
@@ -273,7 +303,8 @@ define float @caller3(i8* %error_ref) {<br>
 ; CHECK-O0: mov x21<br>
 ; CHECK-O0: bl {{.*}}foo_sret<br>
 ; CHECK-O0: mov [[ID2:x[0-9]+]], x21<br>
-; CHECK-O0: cbnz x21<br>
+; CHECK-O0-AARCH64: cbnz x21<br>
+; CHECK-O0-ARM64_32: cmp x21, #0<br>
 ; Access part of the error object and save it to error_ref<br>
 ; reload from stack<br>
 ; CHECK-O0: ldrb [[CODE:w[0-9]+]]<br>
@@ -306,20 +337,22 @@ define float @foo_vararg(%swift_error**<br>
 ; CHECK-APPLE-LABEL: foo_vararg:<br>
 ; CHECK-APPLE: mov w0, #16<br>
 ; CHECK-APPLE: malloc<br>
-; CHECK-APPLE-DAG: mov [[ID:w[0-9]+]], #1<br>
-; CHECK-APPLE-DAG: add [[ARGS:x[0-9]+]], [[TMP:x[0-9]+]], #16<br>
-; CHECK-APPLE-DAG: strb [[ID]], [x0, #8]<br>
<br>
 ; First vararg<br>
-; CHECK-APPLE-DAG: ldr {{w[0-9]+}}, [{{.*}}[[TMP]], #16]<br>
+; CHECK-APPLE-AARCH64: ldr {{w[0-9]+}}, [{{.*}}[[TMP:x[0-9]+]], #16]<br>
+; CHECK-APPLE-AARCH64: mov [[ID:w[0-9]+]], #1<br>
+; CHECK-APPLE-AARCH64: add [[ARGS:x[0-9]+]], [[TMP]], #16<br>
+; CHECK-APPLE-AARCH64: strb [[ID]], [x0, #8]<br>
 ; Second vararg<br>
-; CHECK-APPLE-DAG: ldr {{w[0-9]+}}, [{{.*}}[[TMP]], #24]<br>
-; CHECK-APPLE-DAG: add {{x[0-9]+}}, {{x[0-9]+}}, #16<br>
+; CHECK-APPLE-AARCH64: ldr {{w[0-9]+}}, [{{.*}}[[TMP]], #24]<br>
 ; Third vararg<br>
-; CHECK-APPLE-DAG: ldr {{w[0-9]+}}, [{{.*}}[[TMP]], #32]<br>
+; CHECK-APPLE-AARCH64: ldr {{w[0-9]+}}, [{{.*}}[[TMP]], #32]<br>
+<br>
+; CHECK-APPLE-ARM64_32: mov [[ID:w[0-9]+]], #1<br>
+; CHECK-APPLE-ARM64_32: add [[ARGS:x[0-9]+]], [[TMP:x[0-9]+]], #16<br>
+; CHECK-APPLE-ARM64_32: strb [[ID]], [x0, #8]<br>
+<br>
<br>
-; CHECK-APPLE: mov x21, x0<br>
-; CHECK-APPLE-NOT: x21<br>
 entry:<br>
   %call = call i8* @malloc(i64 16)<br>
   %call.0 = bitcast i8* %call to %swift_error*<br>
@@ -347,18 +380,18 @@ entry:<br>
 define float @caller4(i8* %error_ref) {<br>
 ; CHECK-APPLE-LABEL: caller4:<br>
<br>
-; CHECK-APPLE: mov [[ID:x[0-9]+]], x0<br>
-; CHECK-APPLE: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #8]<br>
-; CHECK-APPLE: str {{x[0-9]+}}, [sp]<br>
-<br>
-; CHECK-APPLE: mov x21, xzr<br>
-; CHECK-APPLE: bl {{.*}}foo_vararg<br>
-; CHECK-APPLE: mov x0, x21<br>
-; CHECK-APPLE: cbnz x21<br>
+; CHECK-APPLE-AARCH64: mov [[ID:x[0-9]+]], x0<br>
+; CHECK-APPLE-AARCH64: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #8]<br>
+; CHECK-APPLE-AARCH64: str {{x[0-9]+}}, [sp]<br>
+<br>
+; CHECK-APPLE-AARCH64: mov x21, xzr<br>
+; CHECK-APPLE-AARCH64: bl {{.*}}foo_vararg<br>
+; CHECK-APPLE-AARCH64: mov x0, x21<br>
+; CHECK-APPLE-AARCH64: cbnz x21<br>
 ; Access part of the error object and save it to error_ref<br>
-; CHECK-APPLE: ldrb [[CODE:w[0-9]+]], [x0, #8]<br>
-; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]<br>
-; CHECK-APPLE: bl {{.*}}free<br>
+; CHECK-APPLE-AARCH64: ldrb [[CODE:w[0-9]+]], [x0, #8]<br>
+; CHECK-APPLE-AARCH64: strb [[CODE]], [{{.*}}[[ID]]]<br>
+; CHECK-APPLE-AARCH64: bl {{.*}}free<br>
 entry:<br>
   %error_ptr_ref = alloca swifterror %swift_error*<br>
   store %swift_error* null, %swift_error** %error_ptr_ref<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/swiftself.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swiftself.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/swiftself.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/swiftself.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/swiftself.ll Thu Sep 12 03:22:23 2019<br>
@@ -1,6 +1,7 @@<br>
-; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT %s<br>
+; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTAARCH64 %s<br>
 ; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s<br>
-; RUN: llc -verify-machineinstrs -mtriple=aarch64-unknown-linux-gnu -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT %s<br>
+; RUN: llc -verify-machineinstrs -mtriple=aarch64-unknown-linux-gnu -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTAARCH64 %s<br>
+; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTARM64_32 %s<br>
<br>
 ; Parameter with swiftself should be allocated to x20.<br>
 ; CHECK-LABEL: swiftself_param:<br>
@@ -48,8 +49,9 @@ define void @swiftself_passthrough(i8* s<br>
 ; We can use a tail call if the callee swiftself is the same as the caller one.<br>
 ; This should also work with fast-isel.<br>
 ; CHECK-LABEL: swiftself_tail:<br>
-; CHECK: b {{_?}}swiftself_param<br>
-; CHECK-NOT: ret<br>
+; OPTAARCH64: b {{_?}}swiftself_param<br>
+; OPTAARCH64-NOT: ret<br>
+; OPTARM64_32: bl {{_?}}swiftself_param<br>
 define i8* @swiftself_tail(i8* swiftself %addr0) {<br>
   call void asm sideeffect "", "~{x20}"()<br>
   %res = tail call i8* @swiftself_param(i8* swiftself %addr0)<br>
@@ -71,12 +73,19 @@ define i8* @swiftself_notail(i8* swiftse<br>
 ; we normally would. We marked the first parameter with swiftself which means it<br>
 ; will no longer be passed in x0.<br>
 declare swiftcc i8* @thisreturn_attribute(i8* returned swiftself)<br>
-; OPT-LABEL: swiftself_nothisreturn:<br>
-; OPT-DAG: ldr  x20, [x20]<br>
-; OPT-DAG: mov [[CSREG:x[1-9].*]], x8<br>
-; OPT: bl {{_?}}thisreturn_attribute<br>
-; OPT: str x0, {{\[}}[[CSREG]]<br>
-; OPT: ret<br>
+; OPTAARCH64-LABEL: swiftself_nothisreturn:<br>
+; OPTAARCH64-DAG: ldr  x20, [x20]<br>
+; OPTAARCH64-DAG: mov [[CSREG:x[1-9].*]], x8<br>
+; OPTAARCH64: bl {{_?}}thisreturn_attribute<br>
+; OPTAARCH64: str x0, {{\[}}[[CSREG]]<br>
+; OPTAARCH64: ret<br>
+<br>
+; OPTARM64_32-LABEL: swiftself_nothisreturn:<br>
+; OPTARM64_32-DAG: ldr  w20, [x20]<br>
+; OPTARM64_32-DAG: mov [[CSREG:x[1-9].*]], x8<br>
+; OPTARM64_32: bl {{_?}}thisreturn_attribute<br>
+; OPTARM64_32: str w0, {{\[}}[[CSREG]]<br>
+; OPTARM64_32: ret<br>
 define hidden swiftcc void @swiftself_nothisreturn(i8** noalias nocapture sret, i8** noalias nocapture readonly swiftself) {<br>
 entry:<br>
   %2 = load i8*, i8** %1, align 8<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/tail-call.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/tail-call.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/tail-call.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/tail-call.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/tail-call.ll Thu Sep 12 03:22:23 2019<br>
@@ -2,8 +2,8 @@<br>
 ; RUN: llc -global-isel -global-isel-abort=2 -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s --check-prefixes=GISEL,COMMON<br>
<br>
 declare fastcc void @callee_stack0()<br>
-declare fastcc void @callee_stack8([8 x i32], i64)<br>
-declare fastcc void @callee_stack16([8 x i32], i64, i64)<br>
+declare fastcc void @callee_stack8([8 x i64], i64)<br>
+declare fastcc void @callee_stack16([8 x i64], i64, i64)<br>
 declare extern_weak fastcc void @callee_weak()<br>
<br>
 define fastcc void @caller_to0_from0() nounwind {<br>
@@ -16,7 +16,7 @@ define fastcc void @caller_to0_from0() n<br>
 ; COMMON-NEXT: b callee_stack0<br>
 }<br>
<br>
-define fastcc void @caller_to0_from8([8 x i32], i64) {<br>
+define fastcc void @caller_to0_from8([8 x i64], i64) {<br>
 ; COMMON-LABEL: caller_to0_from8:<br>
<br>
   tail call fastcc void @callee_stack0()<br>
@@ -32,33 +32,33 @@ define fastcc void @caller_to8_from0() {<br>
<br>
 ; Key point is that the "42" should go #16 below incoming stack<br>
 ; pointer (we didn't have arg space to reuse).<br>
-  tail call fastcc void @callee_stack8([8 x i32] undef, i64 42)<br>
+  tail call fastcc void @callee_stack8([8 x i64] undef, i64 42)<br>
   ret void<br>
<br>
 ; COMMON: str {{x[0-9]+}}, [sp, #16]!<br>
 ; COMMON-NEXT: b callee_stack8<br>
 }<br>
<br>
-define fastcc void @caller_to8_from8([8 x i32], i64 %a) {<br>
+define fastcc void @caller_to8_from8([8 x i64], i64 %a) {<br>
 ; COMMON-LABEL: caller_to8_from8:<br>
 ; COMMON: sub sp, sp, #16<br>
<br>
 ; Key point is that the "%a" should go where at SP on entry.<br>
-  tail call fastcc void @callee_stack8([8 x i32] undef, i64 42)<br>
+  tail call fastcc void @callee_stack8([8 x i64] undef, i64 42)<br>
   ret void<br>
<br>
 ; COMMON: str {{x[0-9]+}}, [sp, #16]!<br>
 ; COMMON-NEXT: b callee_stack8<br>
 }<br>
<br>
-define fastcc void @caller_to16_from8([8 x i32], i64 %a) {<br>
+define fastcc void @caller_to16_from8([8 x i64], i64 %a) {<br>
 ; COMMON-LABEL: caller_to16_from8:<br>
 ; COMMON: sub sp, sp, #16<br>
<br>
 ; Important point is that the call reuses the "dead" argument space<br>
 ; above %a on the stack. If it tries to go below incoming-SP then the<br>
 ; callee will not deallocate the space, even in fastcc.<br>
-  tail call fastcc void @callee_stack16([8 x i32] undef, i64 42, i64 2)<br>
+  tail call fastcc void @callee_stack16([8 x i64] undef, i64 42, i64 2)<br>
<br>
 ; COMMON: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]!<br>
 ; COMMON-NEXT: b callee_stack16<br>
@@ -66,12 +66,12 @@ define fastcc void @caller_to16_from8([8<br>
 }<br>
<br>
<br>
-define fastcc void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) {<br>
+define fastcc void @caller_to8_from24([8 x i64], i64 %a, i64 %b, i64 %c) {<br>
 ; COMMON-LABEL: caller_to8_from24:<br>
 ; COMMON: sub sp, sp, #16<br>
<br>
 ; Key point is that the "%a" should go where at #16 above SP on entry.<br>
-  tail call fastcc void @callee_stack8([8 x i32] undef, i64 42)<br>
+  tail call fastcc void @callee_stack8([8 x i64] undef, i64 42)<br>
   ret void<br>
<br>
 ; COMMON: str {{x[0-9]+}}, [sp, #32]!<br>
@@ -79,13 +79,13 @@ define fastcc void @caller_to8_from24([8<br>
 }<br>
<br>
<br>
-define fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) {<br>
+define fastcc void @caller_to16_from16([8 x i64], i64 %a, i64 %b) {<br>
 ; COMMON-LABEL: caller_to16_from16:<br>
 ; COMMON: sub sp, sp, #16<br>
<br>
 ; Here we want to make sure that both loads happen before the stores:<br>
 ; otherwise either %a or %b will be wrongly clobbered.<br>
-  tail call fastcc void @callee_stack16([8 x i32] undef, i64 %b, i64 %a)<br>
+  tail call fastcc void @callee_stack16([8 x i64] undef, i64 %b, i64 %a)<br>
   ret void<br>
<br>
 ; COMMON: ldp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/umulo-128-legalisation-lowering.ll Thu Sep 12 03:22:23 2019<br>
@@ -27,8 +27,8 @@ define { i128, i8 } @muloti_test(i128 %l<br>
 ; AARCH-NEXT:    orr w10, w10, w11<br>
 ; AARCH-NEXT:    orr w9, w10, w9<br>
 ; AARCH-NEXT:    mul x0, x0, x2<br>
-; AARCH-NEXT:    mov x1, x8<br>
-; AARCH-NEXT:    mov w2, w9<br>
+; AARCH-DAG:    mov x1, x8<br>
+; AARCH-DAG:    mov w2, w9<br>
 ; AARCH-NEXT:    ret<br>
 start:<br>
   %0 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %l, i128 %r) #2<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/win64_vararg.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/win64_vararg.ll?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/win64_vararg.ll?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/win64_vararg.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/win64_vararg.ll Thu Sep 12 03:22:23 2019<br>
@@ -261,11 +261,11 @@ define i32 @snprintf(i8*, i64, i8*, ...)<br>
 ; CHECK-DAG: mov     w6,  w3<br>
 ; CHECK-DAG: mov     [[REG1:w[0-9]+]],  w2<br>
 ; CHECK: mov     w2, w1<br>
-; CHECK: str     w4,  [sp]<br>
 ; CHECK: fmov    x1,  d0<br>
 ; CHECK: fmov    x3,  d1<br>
 ; CHECK: fmov    x5,  d2<br>
 ; CHECK: fmov    x7,  d3<br>
+; CHECK: str     w4,  [sp]<br>
 ; CHECK: mov     w4,  [[REG1]]<br>
 ; CHECK: str     x30, [sp, #16]<br>
 ; CHECK: str     d4,  [sp, #8]<br>
<br>
Added: llvm/trunk/test/MC/AArch64/arm64_32-compact-unwind.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/arm64_32-compact-unwind.s?rev=371722&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/arm64_32-compact-unwind.s?rev=371722&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/AArch64/arm64_32-compact-unwind.s (added)<br>
+++ llvm/trunk/test/MC/AArch64/arm64_32-compact-unwind.s Thu Sep 12 03:22:23 2019<br>
@@ -0,0 +1,15 @@<br>
+; RUN: llvm-mc -triple=arm64_32-ios7.0 -filetype=obj %s -o %t<br>
+; RUN: llvm-objdump -s %t | FileCheck %s<br>
+<br>
+; The compact unwind format in ILP32 mode is pretty much the same, except<br>
+; references to addresses (function, personality, LSDA) are pointer-sized.<br>
+<br>
+; CHECK: Contents of section __compact_unwind:<br>
+; CHECK-NEXT:  0004 00000000 04000000 00000002 00000000<br>
+; CHECK-NEXT:  0014 00000000<br>
+        .globl  _test_compact_unwind<br>
+        .align  2<br>
+_test_compact_unwind:<br>
+        .cfi_startproc<br>
+        ret<br>
+        .cfi_endproc<br>
<br>
Modified: llvm/trunk/utils/TableGen/CallingConvEmitter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CallingConvEmitter.cpp?rev=371722&r1=371721&r2=371722&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CallingConvEmitter.cpp?rev=371722&r1=371721&r2=371722&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/utils/TableGen/CallingConvEmitter.cpp (original)<br>
+++ llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Thu Sep 12 03:22:23 2019<br>
@@ -264,6 +264,10 @@ void CallingConvEmitter::EmitAction(Reco<br>
       Record *DestTy = Action->getValueAsDef("DestTy");<br>
       O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";<br>
       O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";<br>
+    } else if (Action->isSubClassOf("CCTruncToType")) {<br>
+      Record *DestTy = Action->getValueAsDef("DestTy");<br>
+      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";<br>
+      O << IndentStr << "LocInfo = CCValAssign::Trunc;\n";<br>
     } else if (Action->isSubClassOf("CCPassIndirect")) {<br>
       Record *DestTy = Action->getValueAsDef("DestTy");<br>
       O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>