Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Jan 2017 19:17:54 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r312704 - in vendor/llvm/dist: lib/Bitcode/Reader lib/Target/AArch64 lib/Target/ARM lib/Target/X86 lib/Transforms/Instrumentation lib/Transforms/Scalar test/CodeGen/AArch64 test/CodeGen...
Message-ID:  <201701241917.v0OJHsaj072176@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Tue Jan 24 19:17:53 2017
New Revision: 312704
URL: https://svnweb.freebsd.org/changeset/base/312704

Log:
  Vendor import of llvm release_40 branch r292951:
  https://llvm.org/svn/llvm-project/llvm/branches/release_40@292951

Added:
  vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt.mir
  vendor/llvm/dist/test/CodeGen/Thumb2/intrinsics-cc.ll
  vendor/llvm/dist/test/Transforms/NewGVN/pr31682.ll
  vendor/llvm/dist/test/tools/llvm-cxxfilt/invalid.test
Deleted:
  vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir
Modified:
  vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp
  vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp
  vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h
  vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
  vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp
  vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h
  vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp
  vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp
  vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp
  vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll
  vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll
  vendor/llvm/dist/test/CodeGen/X86/sse1.ll
  vendor/llvm/dist/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll
  vendor/llvm/dist/test/ThinLTO/X86/lazyload_metadata.ll
  vendor/llvm/dist/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
  vendor/llvm/dist/utils/release/test-release.sh

Modified: vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp
==============================================================================
--- vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -512,7 +512,7 @@ private:
   }
 
   Metadata *getFnMetadataByID(unsigned ID) {
-    return MDLoader->getMetadataFwdRef(ID);
+    return MDLoader->getMetadataFwdRefOrLoad(ID);
   }
 
   BasicBlock *getBasicBlock(unsigned ID) const {

Modified: vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp
==============================================================================
--- vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -485,8 +485,21 @@ public:
   Error parseMetadata(bool ModuleLevel);
 
   bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
-  Metadata *getMetadataFwdRef(unsigned Idx) {
-    return MetadataList.getMetadataFwdRef(Idx);
+
+  Metadata *getMetadataFwdRefOrLoad(unsigned ID) {
+    if (ID < MDStringRef.size())
+      return lazyLoadOneMDString(ID);
+    if (auto *MD = MetadataList.lookup(ID))
+      return MD;
+    // If lazy-loading is enabled, we try recursively to load the operand
+    // instead of creating a temporary.
+    if (ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
+      PlaceholderQueue Placeholders;
+      lazyLoadOneMetadata(ID, Placeholders);
+      resolveForwardRefsAndPlaceholders(Placeholders);
+      return MetadataList.lookup(ID);
+    }
+    return MetadataList.getMetadataFwdRef(ID);
   }
 
   MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
@@ -1727,8 +1740,8 @@ bool MetadataLoader::hasFwdRefs() const 
 
 /// Return the given metadata, creating a replaceable forward reference if
 /// necessary.
-Metadata *MetadataLoader::getMetadataFwdRef(unsigned Idx) {
-  return Pimpl->getMetadataFwdRef(Idx);
+Metadata *MetadataLoader::getMetadataFwdRefOrLoad(unsigned Idx) {
+  return Pimpl->getMetadataFwdRefOrLoad(Idx);
 }
 
 MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {

Modified: vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h
==============================================================================
--- vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h	Tue Jan 24 19:17:53 2017	(r312704)
@@ -63,7 +63,7 @@ public:
 
   /// Return the given metadata, creating a replaceable forward reference if
   /// necessary.
-  Metadata *getMetadataFwdRef(unsigned Idx);
+  Metadata *getMetadataFwdRefOrLoad(unsigned Idx);
 
   MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
 

Modified: vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -687,9 +687,30 @@ AArch64LoadStoreOpt::mergePairedInsns(Ma
   MachineInstrBuilder MIB;
   DebugLoc DL = I->getDebugLoc();
   MachineBasicBlock *MBB = I->getParent();
+  MachineOperand RegOp0 = getLdStRegOp(*RtMI);
+  MachineOperand RegOp1 = getLdStRegOp(*Rt2MI);
+  // Kill flags may become invalid when moving stores for pairing.
+  if (RegOp0.isUse()) {
+    if (!MergeForward) {
+      // Clear kill flags on store if moving upwards. Example:
+      //   STRWui %w0, ...
+      //   USE %w1
+      //   STRWui kill %w1  ; need to clear kill flag when moving STRWui upwards
+      RegOp0.setIsKill(false);
+      RegOp1.setIsKill(false);
+    } else {
+      // Clear kill flags of the first stores register. Example:
+      //   STRWui %w1, ...
+      //   USE kill %w1   ; need to clear kill flag when moving STRWui downwards
+      //   STRW %w0
+      unsigned Reg = getLdStRegOp(*I).getReg();
+      for (MachineInstr &MI : make_range(std::next(I), Paired))
+        MI.clearRegisterKills(Reg, TRI);
+    }
+  }
   MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
-            .addOperand(getLdStRegOp(*RtMI))
-            .addOperand(getLdStRegOp(*Rt2MI))
+            .addOperand(RegOp0)
+            .addOperand(RegOp1)
             .addOperand(BaseRegOp)
             .addImm(OffsetImm)
             .setMemRefs(I->mergeMemRefsWith(*Paired));

Modified: vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -97,171 +97,6 @@ namespace {
   };
 }
 
-void ARMTargetLowering::InitLibcallCallingConvs() {
-  // The builtins on ARM always use AAPCS, irrespective of wheter C is AAPCS or
-  // AAPCS_VFP.
-  for (const auto LC : {
-           RTLIB::SHL_I16,
-           RTLIB::SHL_I32,
-           RTLIB::SHL_I64,
-           RTLIB::SHL_I128,
-           RTLIB::SRL_I16,
-           RTLIB::SRL_I32,
-           RTLIB::SRL_I64,
-           RTLIB::SRL_I128,
-           RTLIB::SRA_I16,
-           RTLIB::SRA_I32,
-           RTLIB::SRA_I64,
-           RTLIB::SRA_I128,
-           RTLIB::MUL_I8,
-           RTLIB::MUL_I16,
-           RTLIB::MUL_I32,
-           RTLIB::MUL_I64,
-           RTLIB::MUL_I128,
-           RTLIB::MULO_I32,
-           RTLIB::MULO_I64,
-           RTLIB::MULO_I128,
-           RTLIB::SDIV_I8,
-           RTLIB::SDIV_I16,
-           RTLIB::SDIV_I32,
-           RTLIB::SDIV_I64,
-           RTLIB::SDIV_I128,
-           RTLIB::UDIV_I8,
-           RTLIB::UDIV_I16,
-           RTLIB::UDIV_I32,
-           RTLIB::UDIV_I64,
-           RTLIB::UDIV_I128,
-           RTLIB::SREM_I8,
-           RTLIB::SREM_I16,
-           RTLIB::SREM_I32,
-           RTLIB::SREM_I64,
-           RTLIB::SREM_I128,
-           RTLIB::UREM_I8,
-           RTLIB::UREM_I16,
-           RTLIB::UREM_I32,
-           RTLIB::UREM_I64,
-           RTLIB::UREM_I128,
-           RTLIB::SDIVREM_I8,
-           RTLIB::SDIVREM_I16,
-           RTLIB::SDIVREM_I32,
-           RTLIB::SDIVREM_I64,
-           RTLIB::SDIVREM_I128,
-           RTLIB::UDIVREM_I8,
-           RTLIB::UDIVREM_I16,
-           RTLIB::UDIVREM_I32,
-           RTLIB::UDIVREM_I64,
-           RTLIB::UDIVREM_I128,
-           RTLIB::NEG_I32,
-           RTLIB::NEG_I64,
-           RTLIB::ADD_F32,
-           RTLIB::ADD_F64,
-           RTLIB::ADD_F80,
-           RTLIB::ADD_F128,
-           RTLIB::SUB_F32,
-           RTLIB::SUB_F64,
-           RTLIB::SUB_F80,
-           RTLIB::SUB_F128,
-           RTLIB::MUL_F32,
-           RTLIB::MUL_F64,
-           RTLIB::MUL_F80,
-           RTLIB::MUL_F128,
-           RTLIB::DIV_F32,
-           RTLIB::DIV_F64,
-           RTLIB::DIV_F80,
-           RTLIB::DIV_F128,
-           RTLIB::POWI_F32,
-           RTLIB::POWI_F64,
-           RTLIB::POWI_F80,
-           RTLIB::POWI_F128,
-           RTLIB::FPEXT_F64_F128,
-           RTLIB::FPEXT_F32_F128,
-           RTLIB::FPEXT_F32_F64,
-           RTLIB::FPEXT_F16_F32,
-           RTLIB::FPROUND_F32_F16,
-           RTLIB::FPROUND_F64_F16,
-           RTLIB::FPROUND_F80_F16,
-           RTLIB::FPROUND_F128_F16,
-           RTLIB::FPROUND_F64_F32,
-           RTLIB::FPROUND_F80_F32,
-           RTLIB::FPROUND_F128_F32,
-           RTLIB::FPROUND_F80_F64,
-           RTLIB::FPROUND_F128_F64,
-           RTLIB::FPTOSINT_F32_I32,
-           RTLIB::FPTOSINT_F32_I64,
-           RTLIB::FPTOSINT_F32_I128,
-           RTLIB::FPTOSINT_F64_I32,
-           RTLIB::FPTOSINT_F64_I64,
-           RTLIB::FPTOSINT_F64_I128,
-           RTLIB::FPTOSINT_F80_I32,
-           RTLIB::FPTOSINT_F80_I64,
-           RTLIB::FPTOSINT_F80_I128,
-           RTLIB::FPTOSINT_F128_I32,
-           RTLIB::FPTOSINT_F128_I64,
-           RTLIB::FPTOSINT_F128_I128,
-           RTLIB::FPTOUINT_F32_I32,
-           RTLIB::FPTOUINT_F32_I64,
-           RTLIB::FPTOUINT_F32_I128,
-           RTLIB::FPTOUINT_F64_I32,
-           RTLIB::FPTOUINT_F64_I64,
-           RTLIB::FPTOUINT_F64_I128,
-           RTLIB::FPTOUINT_F80_I32,
-           RTLIB::FPTOUINT_F80_I64,
-           RTLIB::FPTOUINT_F80_I128,
-           RTLIB::FPTOUINT_F128_I32,
-           RTLIB::FPTOUINT_F128_I64,
-           RTLIB::FPTOUINT_F128_I128,
-           RTLIB::SINTTOFP_I32_F32,
-           RTLIB::SINTTOFP_I32_F64,
-           RTLIB::SINTTOFP_I32_F80,
-           RTLIB::SINTTOFP_I32_F128,
-           RTLIB::SINTTOFP_I64_F32,
-           RTLIB::SINTTOFP_I64_F64,
-           RTLIB::SINTTOFP_I64_F80,
-           RTLIB::SINTTOFP_I64_F128,
-           RTLIB::SINTTOFP_I128_F32,
-           RTLIB::SINTTOFP_I128_F64,
-           RTLIB::SINTTOFP_I128_F80,
-           RTLIB::SINTTOFP_I128_F128,
-           RTLIB::UINTTOFP_I32_F32,
-           RTLIB::UINTTOFP_I32_F64,
-           RTLIB::UINTTOFP_I32_F80,
-           RTLIB::UINTTOFP_I32_F128,
-           RTLIB::UINTTOFP_I64_F32,
-           RTLIB::UINTTOFP_I64_F64,
-           RTLIB::UINTTOFP_I64_F80,
-           RTLIB::UINTTOFP_I64_F128,
-           RTLIB::UINTTOFP_I128_F32,
-           RTLIB::UINTTOFP_I128_F64,
-           RTLIB::UINTTOFP_I128_F80,
-           RTLIB::UINTTOFP_I128_F128,
-           RTLIB::OEQ_F32,
-           RTLIB::OEQ_F64,
-           RTLIB::OEQ_F128,
-           RTLIB::UNE_F32,
-           RTLIB::UNE_F64,
-           RTLIB::UNE_F128,
-           RTLIB::OGE_F32,
-           RTLIB::OGE_F64,
-           RTLIB::OGE_F128,
-           RTLIB::OLT_F32,
-           RTLIB::OLT_F64,
-           RTLIB::OLT_F128,
-           RTLIB::OLE_F32,
-           RTLIB::OLE_F64,
-           RTLIB::OLE_F128,
-           RTLIB::OGT_F32,
-           RTLIB::OGT_F64,
-           RTLIB::OGT_F128,
-           RTLIB::UO_F32,
-           RTLIB::UO_F64,
-           RTLIB::UO_F128,
-           RTLIB::O_F32,
-           RTLIB::O_F64,
-           RTLIB::O_F128,
-       })
-  setLibcallCallingConv(LC, CallingConv::ARM_AAPCS);
-}
-
 // The APCS parameter registers.
 static const MCPhysReg GPRArgRegs[] = {
   ARM::R0, ARM::R1, ARM::R2, ARM::R3
@@ -349,7 +184,22 @@ ARMTargetLowering::ARMTargetLowering(con
 
   setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
 
-  InitLibcallCallingConvs();
+  if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetIOS() &&
+      !Subtarget->isTargetWatchOS()) {
+    const auto &E = Subtarget->getTargetTriple().getEnvironment();
+
+    bool IsHFTarget = E == Triple::EABIHF || E == Triple::GNUEABIHF ||
+                      E == Triple::MuslEABIHF;
+    // Windows is a special case.  Technically, we will replace all of the "GNU"
+    // calls with calls to MSVCRT if appropriate and adjust the calling
+    // convention then.
+    IsHFTarget = IsHFTarget || Subtarget->isTargetWindows();
+
+    for (int LCID = 0; LCID < RTLIB::UNKNOWN_LIBCALL; ++LCID)
+      setLibcallCallingConv(static_cast<RTLIB::Libcall>(LCID),
+                            IsHFTarget ? CallingConv::ARM_AAPCS_VFP
+                                       : CallingConv::ARM_AAPCS);
+  }
 
   if (Subtarget->isTargetMachO()) {
     // Uses VFP for Thumb libfuncs if available.

Modified: vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h
==============================================================================
--- vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h	Tue Jan 24 19:17:53 2017	(r312704)
@@ -538,8 +538,6 @@ class InstrItineraryData;
 
     bool HasStandaloneRem = true;
 
-    void InitLibcallCallingConvs();
-
     void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
     void addDRTypeForNEON(MVT VT);
     void addQRTypeForNEON(MVT VT);

Modified: vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -28788,10 +28788,12 @@ static SDValue combineExtractVectorElt(S
   return SDValue();
 }
 
-/// If a vector select has an operand that is -1 or 0, simplify the select to a
-/// bitwise logic operation.
-static SDValue combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
-                                                const X86Subtarget &Subtarget) {
+/// If a vector select has an operand that is -1 or 0, try to simplify the
+/// select to a bitwise logic operation.
+static SDValue
+combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
+                                 TargetLowering::DAGCombinerInfo &DCI,
+                                 const X86Subtarget &Subtarget) {
   SDValue Cond = N->getOperand(0);
   SDValue LHS = N->getOperand(1);
   SDValue RHS = N->getOperand(2);
@@ -28853,18 +28855,28 @@ static SDValue combineVSelectWithAllOnes
     }
   }
 
-  if (!TValIsAllOnes && !FValIsAllZeros)
+  // vselect Cond, 111..., 000... -> Cond
+  if (TValIsAllOnes && FValIsAllZeros)
+    return DAG.getBitcast(VT, Cond);
+
+  if (!DCI.isBeforeLegalize() && !TLI.isTypeLegal(CondVT))
     return SDValue();
 
-  SDValue Ret;
-  if (TValIsAllOnes && FValIsAllZeros)
-    Ret = Cond;
-  else if (TValIsAllOnes)
-    Ret = DAG.getNode(ISD::OR, DL, CondVT, Cond, DAG.getBitcast(CondVT, RHS));
-  else if (FValIsAllZeros)
-    Ret = DAG.getNode(ISD::AND, DL, CondVT, Cond, DAG.getBitcast(CondVT, LHS));
+  // vselect Cond, 111..., X -> or Cond, X
+  if (TValIsAllOnes) {
+    SDValue CastRHS = DAG.getBitcast(CondVT, RHS);
+    SDValue Or = DAG.getNode(ISD::OR, DL, CondVT, Cond, CastRHS);
+    return DAG.getBitcast(VT, Or);
+  }
 
-  return DAG.getBitcast(VT, Ret);
+  // vselect Cond, X, 000... -> and Cond, X
+  if (FValIsAllZeros) {
+    SDValue CastLHS = DAG.getBitcast(CondVT, LHS);
+    SDValue And = DAG.getNode(ISD::AND, DL, CondVT, Cond, CastLHS);
+    return DAG.getBitcast(VT, And);
+  }
+
+  return SDValue();
 }
 
 static SDValue combineSelectOfTwoConstants(SDNode *N, SelectionDAG &DAG) {
@@ -29353,7 +29365,7 @@ static SDValue combineSelect(SDNode *N, 
     }
   }
 
-  if (SDValue V = combineVSelectWithAllOnesOrZeros(N, DAG, Subtarget))
+  if (SDValue V = combineVSelectWithAllOnesOrZeros(N, DAG, DCI, Subtarget))
     return V;
 
   // If this is a *dynamic* select (non-constant condition) and we can match

Modified: vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp
==============================================================================
--- vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -600,6 +600,22 @@ private:
   void initializeCallbacks(Module &M);
 
   bool InstrumentGlobals(IRBuilder<> &IRB, Module &M);
+  void InstrumentGlobalsCOFF(IRBuilder<> &IRB, Module &M,
+                             ArrayRef<GlobalVariable *> ExtendedGlobals,
+                             ArrayRef<Constant *> MetadataInitializers);
+  void InstrumentGlobalsMachO(IRBuilder<> &IRB, Module &M,
+                              ArrayRef<GlobalVariable *> ExtendedGlobals,
+                              ArrayRef<Constant *> MetadataInitializers);
+  void
+  InstrumentGlobalsWithMetadataArray(IRBuilder<> &IRB, Module &M,
+                                     ArrayRef<GlobalVariable *> ExtendedGlobals,
+                                     ArrayRef<Constant *> MetadataInitializers);
+
+  GlobalVariable *CreateMetadataGlobal(Module &M, Constant *Initializer,
+                                       StringRef OriginalName);
+  void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata);
+  IRBuilder<> CreateAsanModuleDtor(Module &M);
+
   bool ShouldInstrumentGlobal(GlobalVariable *G);
   bool ShouldUseMachOGlobalsSection() const;
   StringRef getGlobalMetadataSection() const;
@@ -1553,17 +1569,173 @@ void AddressSanitizerModule::initializeC
 
   // Declare the functions that find globals in a shared object and then invoke
   // the (un)register function on them.
-  AsanRegisterImageGlobals = checkSanitizerInterfaceFunction(
-      M.getOrInsertFunction(kAsanRegisterImageGlobalsName,
-      IRB.getVoidTy(), IntptrTy, nullptr));
+  AsanRegisterImageGlobals =
+      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+          kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
   AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage);
 
-  AsanUnregisterImageGlobals = checkSanitizerInterfaceFunction(
-      M.getOrInsertFunction(kAsanUnregisterImageGlobalsName,
-      IRB.getVoidTy(), IntptrTy, nullptr));
+  AsanUnregisterImageGlobals =
+      checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+          kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
   AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
 }
 
+// Put the metadata and the instrumented global in the same group. This ensures
+// that the metadata is discarded if the instrumented global is discarded.
+void AddressSanitizerModule::SetComdatForGlobalMetadata(
+    GlobalVariable *G, GlobalVariable *Metadata) {
+  Module &M = *G->getParent();
+  Comdat *C = G->getComdat();
+  if (!C) {
+    if (!G->hasName()) {
+      // If G is unnamed, it must be internal. Give it an artificial name
+      // so we can put it in a comdat.
+      assert(G->hasLocalLinkage());
+      G->setName(Twine(kAsanGenPrefix) + "_anon_global");
+    }
+    C = M.getOrInsertComdat(G->getName());
+    // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
+    if (TargetTriple.isOSBinFormatCOFF())
+      C->setSelectionKind(Comdat::NoDuplicates);
+    G->setComdat(C);
+  }
+
+  assert(G->hasComdat());
+  Metadata->setComdat(G->getComdat());
+}
+
+// Create a separate metadata global and put it in the appropriate ASan
+// global registration section.
+GlobalVariable *
+AddressSanitizerModule::CreateMetadataGlobal(Module &M, Constant *Initializer,
+                                             StringRef OriginalName) {
+  GlobalVariable *Metadata =
+      new GlobalVariable(M, Initializer->getType(), false,
+                         GlobalVariable::InternalLinkage, Initializer,
+                         Twine("__asan_global_") +
+                             GlobalValue::getRealLinkageName(OriginalName));
+  Metadata->setSection(getGlobalMetadataSection());
+  return Metadata;
+}
+
+IRBuilder<> AddressSanitizerModule::CreateAsanModuleDtor(Module &M) {
+  Function *AsanDtorFunction =
+      Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
+                       GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
+  BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
+  appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
+
+  return IRBuilder<>(ReturnInst::Create(*C, AsanDtorBB));
+}
+
+void AddressSanitizerModule::InstrumentGlobalsCOFF(
+    IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
+    ArrayRef<Constant *> MetadataInitializers) {
+  assert(ExtendedGlobals.size() == MetadataInitializers.size());
+  auto &DL = M.getDataLayout();
+
+  for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
+    Constant *Initializer = MetadataInitializers[i];
+    GlobalVariable *G = ExtendedGlobals[i];
+    GlobalVariable *Metadata =
+        CreateMetadataGlobal(M, Initializer, G->getName());
+
+    // The MSVC linker always inserts padding when linking incrementally. We
+    // cope with that by aligning each struct to its size, which must be a power
+    // of two.
+    unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
+    assert(isPowerOf2_32(SizeOfGlobalStruct) &&
+           "global metadata will not be padded appropriately");
+    Metadata->setAlignment(SizeOfGlobalStruct);
+
+    SetComdatForGlobalMetadata(G, Metadata);
+  }
+}
+
+void AddressSanitizerModule::InstrumentGlobalsMachO(
+    IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
+    ArrayRef<Constant *> MetadataInitializers) {
+  assert(ExtendedGlobals.size() == MetadataInitializers.size());
+
+  // On recent Mach-O platforms, use a structure which binds the liveness of
+  // the global variable to the metadata struct. Keep the list of "Liveness" GV
+  // created to be added to llvm.compiler.used
+  StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
+  SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
+
+  for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
+    Constant *Initializer = MetadataInitializers[i];
+    GlobalVariable *G = ExtendedGlobals[i];
+    GlobalVariable *Metadata =
+        CreateMetadataGlobal(M, Initializer, G->getName());
+
+    // On recent Mach-O platforms, we emit the global metadata in a way that
+    // allows the linker to properly strip dead globals.
+    auto LivenessBinder = ConstantStruct::get(
+        LivenessTy, Initializer->getAggregateElement(0u),
+        ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
+    GlobalVariable *Liveness = new GlobalVariable(
+        M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
+        Twine("__asan_binder_") + G->getName());
+    Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
+    LivenessGlobals[i] = Liveness;
+  }
+
+  // Update llvm.compiler.used, adding the new liveness globals. This is
+  // needed so that during LTO these variables stay alive. The alternative
+  // would be to have the linker handling the LTO symbols, but libLTO
+  // current API does not expose access to the section for each symbol.
+  if (!LivenessGlobals.empty())
+    appendToCompilerUsed(M, LivenessGlobals);
+
+  // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
+  // to look up the loaded image that contains it. Second, we can store in it
+  // whether registration has already occurred, to prevent duplicate
+  // registration.
+  //
+  // common linkage ensures that there is only one global per shared library.
+  GlobalVariable *RegisteredFlag = new GlobalVariable(
+      M, IntptrTy, false, GlobalVariable::CommonLinkage,
+      ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
+  RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
+
+  IRB.CreateCall(AsanRegisterImageGlobals,
+                 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
+
+  // We also need to unregister globals at the end, e.g., when a shared library
+  // gets closed.
+  IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
+  IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
+                      {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
+}
+
+void AddressSanitizerModule::InstrumentGlobalsWithMetadataArray(
+    IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
+    ArrayRef<Constant *> MetadataInitializers) {
+  assert(ExtendedGlobals.size() == MetadataInitializers.size());
+  unsigned N = ExtendedGlobals.size();
+  assert(N > 0);
+
+  // On platforms that don't have a custom metadata section, we emit an array
+  // of global metadata structures.
+  ArrayType *ArrayOfGlobalStructTy =
+      ArrayType::get(MetadataInitializers[0]->getType(), N);
+  auto AllGlobals = new GlobalVariable(
+      M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
+      ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
+
+  IRB.CreateCall(AsanRegisterGlobals,
+                 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
+                  ConstantInt::get(IntptrTy, N)});
+
+  // We also need to unregister globals at the end, e.g., when a shared library
+  // gets closed.
+  IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
+  IRB_Dtor.CreateCall(AsanUnregisterGlobals,
+                      {IRB.CreatePointerCast(AllGlobals, IntptrTy),
+                       ConstantInt::get(IntptrTy, N)});
+}
+
 // This function replaces all global variables with new variables that have
 // trailing redzones. It also creates a function that poisons
 // redzones and inserts this function into llvm.global_ctors.
@@ -1580,9 +1752,6 @@ bool AddressSanitizerModule::InstrumentG
   if (n == 0) return false;
 
   auto &DL = M.getDataLayout();
-  bool UseComdatMetadata = TargetTriple.isOSBinFormatCOFF();
-  bool UseMachOGlobalsSection = ShouldUseMachOGlobalsSection();
-  bool UseMetadataArray = !(UseComdatMetadata || UseMachOGlobalsSection);
 
   // A global is described by a structure
   //   size_t beg;
@@ -1597,19 +1766,8 @@ bool AddressSanitizerModule::InstrumentG
   StructType *GlobalStructTy =
       StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
                       IntptrTy, IntptrTy, IntptrTy, nullptr);
-  unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(GlobalStructTy);
-  assert(isPowerOf2_32(SizeOfGlobalStruct) &&
-         "global metadata will not be padded appropriately");
-  SmallVector<Constant *, 16> Initializers(UseMetadataArray ? n : 0);
-
-  // On recent Mach-O platforms, use a structure which binds the liveness of
-  // the global variable to the metadata struct. Keep the list of "Liveness" GV
-  // created to be added to llvm.compiler.used
-  StructType *LivenessTy  = nullptr;
-  if (UseMachOGlobalsSection)
-    LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
-  SmallVector<GlobalValue *, 16> LivenessGlobals(
-      UseMachOGlobalsSection ? n : 0);
+  SmallVector<GlobalVariable *, 16> NewGlobals(n);
+  SmallVector<Constant *, 16> Initializers(n);
 
   bool HasDynamicallyInitializedGlobals = false;
 
@@ -1681,25 +1839,7 @@ bool AddressSanitizerModule::InstrumentG
         ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true));
     NewGlobal->takeName(G);
     G->eraseFromParent();
-    G = NewGlobal;
-
-    if (UseComdatMetadata) {
-      // Get or create a COMDAT for G so that we can use it with our metadata.
-      Comdat *C = G->getComdat();
-      if (!C) {
-        if (!G->hasName()) {
-          // If G is unnamed, it must be internal. Give it an artificial name
-          // so we can put it in a comdat.
-          assert(G->hasLocalLinkage());
-          G->setName(Twine(kAsanGenPrefix) + "_anon_global");
-        }
-        C = M.getOrInsertComdat(G->getName());
-        // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
-        if (TargetTriple.isOSBinFormatCOFF())
-          C->setSelectionKind(Comdat::NoDuplicates);
-        G->setComdat(C);
-      }
-    }
+    NewGlobals[i] = NewGlobal;
 
     Constant *SourceLoc;
     if (!MD.SourceLoc.empty()) {
@@ -1750,117 +1890,21 @@ bool AddressSanitizerModule::InstrumentG
 
     DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
 
-    // If we aren't using separate metadata globals, add it to the initializer
-    // list and continue.
-    if (UseMetadataArray) {
-      Initializers[i] = Initializer;
-      continue;
-    }
-
-    // Create a separate metadata global and put it in the appropriate ASan
-    // global registration section.
-    GlobalVariable *Metadata = new GlobalVariable(
-        M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
-        Initializer, Twine("__asan_global_") +
-                             GlobalValue::getRealLinkageName(G->getName()));
-    Metadata->setSection(getGlobalMetadataSection());
-
-    // We don't want any padding, but we also need a reasonable alignment.
-    // The MSVC linker always inserts padding when linking incrementally. We
-    // cope with that by aligning each struct to its size, which must be a power
-    // of two.
-    Metadata->setAlignment(SizeOfGlobalStruct);
-
-    // On platforms that support comdats, put the metadata and the
-    // instrumented global in the same group. This ensures that the metadata
-    // is discarded if the instrumented global is discarded.
-    if (UseComdatMetadata) {
-      assert(G->hasComdat());
-      Metadata->setComdat(G->getComdat());
-      continue;
-    }
-    assert(UseMachOGlobalsSection);
+    Initializers[i] = Initializer;
+  }
 
-    // On recent Mach-O platforms, we emit the global metadata in a way that
-    // allows the linker to properly strip dead globals.
-    auto LivenessBinder = ConstantStruct::get(
-        LivenessTy, Initializer->getAggregateElement(0u),
-        ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
-    GlobalVariable *Liveness = new GlobalVariable(
-        M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
-        Twine("__asan_binder_") + G->getName());
-    Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
-    LivenessGlobals[i] = Liveness;
+  if (TargetTriple.isOSBinFormatCOFF()) {
+    InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
+  } else if (ShouldUseMachOGlobalsSection()) {
+    InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
+  } else {
+    InstrumentGlobalsWithMetadataArray(IRB, M, NewGlobals, Initializers);
   }
 
   // Create calls for poisoning before initializers run and unpoisoning after.
   if (HasDynamicallyInitializedGlobals)
     createInitializerPoisonCalls(M, ModuleName);
 
-  // Platforms with a dedicated metadata section don't need to emit any more
-  // code.
-  if (UseComdatMetadata)
-    return true;
-
-  GlobalVariable *AllGlobals = nullptr;
-  GlobalVariable *RegisteredFlag = nullptr;
-
-  if (UseMachOGlobalsSection) {
-    // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
-    // to look up the loaded image that contains it. Second, we can store in it
-    // whether registration has already occurred, to prevent duplicate
-    // registration.
-    //
-    // common linkage ensures that there is only one global per shared library.
-    RegisteredFlag = new GlobalVariable(
-        M, IntptrTy, false, GlobalVariable::CommonLinkage,
-        ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
-    RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
-
-    // Update llvm.compiler.used, adding the new liveness globals. This is
-    // needed so that during LTO these variables stay alive. The alternative
-    // would be to have the linker handling the LTO symbols, but libLTO
-    // current API does not expose access to the section for each symbol.
-    if (!LivenessGlobals.empty())
-      appendToCompilerUsed(M, LivenessGlobals);
-  } else if (UseMetadataArray) {
-    // On platforms that don't have a custom metadata section, we emit an array
-    // of global metadata structures.
-    ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
-    AllGlobals = new GlobalVariable(
-        M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
-        ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
-  }
-
-  // Create a call to register the globals with the runtime.
-  if (UseMachOGlobalsSection) {
-    IRB.CreateCall(AsanRegisterImageGlobals,
-                   {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
-  } else {
-    IRB.CreateCall(AsanRegisterGlobals,
-                   {IRB.CreatePointerCast(AllGlobals, IntptrTy),
-                    ConstantInt::get(IntptrTy, n)});
-  }
-
-  // We also need to unregister globals at the end, e.g., when a shared library
-  // gets closed.
-  Function *AsanDtorFunction =
-      Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
-                       GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
-  BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
-  IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
-
-  if (UseMachOGlobalsSection) {
-    IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
-                        {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
-  } else {
-    IRB_Dtor.CreateCall(AsanUnregisterGlobals,
-                        {IRB.CreatePointerCast(AllGlobals, IntptrTy),
-                         ConstantInt::get(IntptrTy, n)});
-  }
-
-  appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
-
   DEBUG(dbgs() << M);
   return true;
 }

Modified: vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp
==============================================================================
--- vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp	Tue Jan 24 19:17:53 2017	(r312704)
@@ -85,6 +85,8 @@ STATISTIC(NumGVNLeaderChanges, "Number o
 STATISTIC(NumGVNSortedLeaderChanges, "Number of sorted leader changes");
 STATISTIC(NumGVNAvoidedSortedLeaderChanges,
           "Number of avoided sorted leader changes");
+STATISTIC(NumGVNNotMostDominatingLeader,
+          "Number of times a member dominated it's new classes' leader");
 
 //===----------------------------------------------------------------------===//
 //                                GVN Pass
@@ -1073,17 +1075,20 @@ void NewGVN::moveValueToNewCongruenceCla
   if (I == OldClass->NextLeader.first)
     OldClass->NextLeader = {nullptr, ~0U};
 
-  // The new instruction and new class leader may either be siblings in the
-  // dominator tree, or the new class leader should dominate the new member
-  // instruction.  We simply check that the member instruction does not properly
-  // dominate the new class leader.
-  assert(
-      !isa<Instruction>(NewClass->RepLeader) || !NewClass->RepLeader ||
-      I == NewClass->RepLeader ||
-      !DT->properlyDominates(
+  // It's possible, though unlikely, for us to discover equivalences such
+  // that the current leader does not dominate the old one.
+  // This statistic tracks how often this happens.
+  // We assert on phi nodes when this happens, currently, for debugging, because
+  // we want to make sure we name phi node cycles properly.
+  if (isa<Instruction>(NewClass->RepLeader) && NewClass->RepLeader &&
+      I != NewClass->RepLeader &&
+      DT->properlyDominates(
           I->getParent(),
-          cast<Instruction>(NewClass->RepLeader)->getParent()) &&
-          "New class for instruction should not be dominated by instruction");
+          cast<Instruction>(NewClass->RepLeader)->getParent())) {
+    ++NumGVNNotMostDominatingLeader;
+    assert(!isa<PHINode>(I) &&
+           "New class for instruction should not be dominated by instruction");
+  }
 
   if (NewClass->RepLeader != I) {
     auto DFSNum = InstrDFS.lookup(I);

Added: vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt.mir
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt.mir	Tue Jan 24 19:17:53 2017	(r312704)
@@ -0,0 +1,132 @@
+# RUN: llc -mtriple=aarch64--linux-gnu -run-pass=aarch64-ldst-opt %s -verify-machineinstrs -o - 2>&1 | FileCheck %s
+--- |
+  define void @promote-load-from-store() { ret void }
+  define void @store-pair() { ret void }
+  define void @store-pair-clearkill0() { ret void }
+  define void @store-pair-clearkill1() { ret void }
+...
+---
+name: promote-load-from-store
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: %w1, %x0, %lr
+
+    STRWui killed %w1, %x0, 0 :: (store 4)
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    %w0 = LDRHHui killed %x0, 1 :: (load 2)
+    RET %lr, implicit %w0
+
+...
+# Don't count transient instructions towards search limits.
+# CHECK-LABEL: name: promote-load-from-store
+# CHECK: STRWui %w1
+# CHECK: UBFMWri %w1
+---
+name: store-pair
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: %w1, %x0, %lr
+
+    STRWui %w1, %x0, 0 :: (store 4)
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    CFI_INSTRUCTION 0
+    STRWui killed %w1, killed %x0, 1 :: (store 4)
+    RET %lr
+
+...
+# CHECK-LABEL: name: store-pair
+# CHECK: STPWi
+---
+name: store-pair-clearkill0
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: %w1, %x0, %lr
+
+    STRWui %w1, %x0, 0 :: (store 4)
+    %w2 = COPY %w1
+    %x3 = COPY %x0
+    STRWui killed %w1, killed %x0, 1 :: (store 4)
+    RET %lr
+...
+# When merging a lower store with an upper one, we must clear kill flags on
+# the lower store.
+# CHECK-LABEL: store-pair-clearkill0
+# CHECK-NOT: STPWi %w1, killed %w1, %x0, 0 :: (store 4)
+# CHECK: STPWi %w1, %w1, %x0, 0 :: (store 4)
+# CHECK: %w2 = COPY %w1
+# CHECK: RET %lr
+---
+name: store-pair-clearkill1
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: %x0, %lr
+
+    %w1 = MOVi32imm 13
+    %w2 = MOVi32imm 7
+    STRWui %w1, %x0, 1 :: (store 4)
+    %w2 = COPY killed %w1
+    STRWui killed %w2, %x0, 0 :: (store 4)
+
+    %w1 = MOVi32imm 42
+    %w2 = MOVi32imm 7
+    STRWui %w1, %x0, 0 :: (store 4)
+    %w2 = COPY killed %w1
+    STRWui killed %w2, killed %x0, 1 :: (store 4)
+
+    RET %lr
+...
+# When merging an upper store with a lower one, kill flags along the way need
+# to be removed; In this case the kill flag on %w1.
+# CHECK-LABEL: store-pair-clearkill1
+# CHECK: %w1 = MOVi32imm
+# CHECK: %w2 = MOVi32imm
+# CHECK-NOT: %w2 = COPY killed %w1
+# CHECK: %w2 = COPY %w1
+# CHECK: STPWi killed %w2, %w1, %x0, 0
+
+# CHECK: %w1 = MOVi32imm
+# CHECK: %w2 = MOVi32imm
+# CHECK-NOT: %w2 = COPY killed %w1
+# CHECK: %w2 = COPY %w1
+# CHECK: STPWi %w1, killed %w2, killed %x0, 0

Modified: vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll
==============================================================================
--- vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll	Tue Jan 24 19:17:53 2017	(r312704)
@@ -18,7 +18,7 @@ declare double     @llvm.powi.f64(double
 define double @powi_d(double %a, i32 %b) {
 ; CHECK-LABEL: powi_d:
 ; SOFT: {{(bl|b)}} __powidf2
-; HARD: bl __powidf2
+; HARD: b __powidf2
   %1 = call double @llvm.powi.f64(double %a, i32 %b)
   ret double %1
 }

Modified: vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll
==============================================================================
--- vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll	Tue Jan 24 18:56:09 2017	(r312703)
+++ vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll	Tue Jan 24 19:17:53 2017	(r312704)
@@ -18,7 +18,7 @@ declare float     @llvm.powi.f32(float %
 define float @powi_f(float %a, i32 %b) {
 ; CHECK-LABEL: powi_f:
 ; SOFT: bl __powisf2
-; HARD: bl __powisf2
+; HARD: b __powisf2
   %1 = call float @llvm.powi.f32(float %a, i32 %b)
   ret float %1
 }

Added: vendor/llvm/dist/test/CodeGen/Thumb2/intrinsics-cc.ll
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/llvm/dist/test/CodeGen/Thumb2/intrinsics-cc.ll	Tue Jan 24 19:17:53 2017	(r312704)
@@ -0,0 +1,41 @@
+; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
+; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
+; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
+; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
+
+; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
+; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
+; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
+; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
+
+; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
+; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
+; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
+; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
+
+declare float @llvm.powi.f32(float, i32)
+
+define float @f(float %f, i32 %i) {
+entry:
+  %0 = call float @llvm.powi.f32(float %f, i32 %i)
+  ret float %0
+}
+
+; CHECK-MATCH: b __powisf2
+; CHECK-MISMATCH: bl __powisf2
+; CHECK-TO-SOFT: vmov s0, r0
+; CHECK-TO-HARD: vmov r0, s0
+
+declare double @llvm.powi.f64(double, i32)
+
+define double @g(double %d, i32 %i) {
+entry:
+  %0 = call double @llvm.powi.f64(double %d, i32 %i)
+  ret double %0
+}
+
+; CHECK-MATCH: b __powidf2
+; CHECK-MISMATCH: bl __powidf2
+; CHECK-TO-SOFT: vmov d0, r0, r1

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701241917.v0OJHsaj072176>