svn commit: r309152 - in vendor/llvm/dist: . include/llvm/Analysis include/llvm/ExecutionEngine include/llvm/IR lib/Analysis lib/CodeGen lib/Linker lib/Support/Unix lib/Target/ARM lib/Target/ARM/As...

Dimitry Andric dim at FreeBSD.org
Fri Nov 25 19:06:03 UTC 2016


Author: dim
Date: Fri Nov 25 19:05:59 2016
New Revision: 309152
URL: https://svnweb.freebsd.org/changeset/base/309152

Log:
  Vendor import of llvm release_39 branch r287912:
  https://llvm.org/svn/llvm-project/llvm/branches/release_39@287912

Added:
  vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll
  vendor/llvm/dist/test/CodeGen/PowerPC/atomic-minmax.ll
  vendor/llvm/dist/test/CodeGen/PowerPC/pr30451.ll
  vendor/llvm/dist/test/CodeGen/X86/branchfolding-undef.mir
  vendor/llvm/dist/test/CodeGen/X86/no-and8ri8.ll
  vendor/llvm/dist/test/CodeGen/X86/pr30298.ll
  vendor/llvm/dist/test/LTO/X86/Inputs/type-mapping-src.ll
  vendor/llvm/dist/test/LTO/X86/type-mapping-bug.ll
  vendor/llvm/dist/test/MC/ARM/ldr-pseudo-wide.s   (contents, props changed)
  vendor/llvm/dist/test/ThinLTO/X86/Inputs/crash_debuginfo.ll
  vendor/llvm/dist/test/ThinLTO/X86/Inputs/import_opaque_type.ll
  vendor/llvm/dist/test/ThinLTO/X86/crash_debuginfo.ll
  vendor/llvm/dist/test/ThinLTO/X86/import_opaque_type.ll
  vendor/llvm/dist/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll
  vendor/llvm/dist/test/Transforms/JumpThreading/pr27840.ll
Modified:
  vendor/llvm/dist/CMakeLists.txt
  vendor/llvm/dist/include/llvm/Analysis/LoopAccessAnalysis.h
  vendor/llvm/dist/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
  vendor/llvm/dist/include/llvm/IR/Intrinsics.td
  vendor/llvm/dist/include/llvm/IR/TypeFinder.h
  vendor/llvm/dist/lib/Analysis/LoopAccessAnalysis.cpp
  vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp
  vendor/llvm/dist/lib/Linker/IRMover.cpp
  vendor/llvm/dist/lib/Support/Unix/Signals.inc
  vendor/llvm/dist/lib/Target/ARM/ARMInstrThumb2.td
  vendor/llvm/dist/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
  vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.cpp
  vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.h
  vendor/llvm/dist/lib/Target/PowerPC/PPCInstr64Bit.td
  vendor/llvm/dist/lib/Target/PowerPC/PPCInstrInfo.td
  vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp
  vendor/llvm/dist/lib/Target/X86/X86InstrAVX512.td
  vendor/llvm/dist/lib/Transforms/Scalar/JumpThreading.cpp
  vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
  vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
  vendor/llvm/dist/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll
  vendor/llvm/dist/test/CodeGen/X86/avx-vbroadcast.ll
  vendor/llvm/dist/test/Transforms/LoopVectorize/runtime-check-readonly.ll
  vendor/llvm/dist/test/Transforms/LoopVectorize/tbaa-nodep.ll
  vendor/llvm/dist/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll

Modified: vendor/llvm/dist/CMakeLists.txt
==============================================================================
--- vendor/llvm/dist/CMakeLists.txt	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/CMakeLists.txt	Fri Nov 25 19:05:59 2016	(r309152)
@@ -27,7 +27,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR)
   set(LLVM_VERSION_MINOR 9)
 endif()
 if(NOT DEFINED LLVM_VERSION_PATCH)
-  set(LLVM_VERSION_PATCH 0)
+  set(LLVM_VERSION_PATCH 1)
 endif()
 if(NOT DEFINED LLVM_VERSION_SUFFIX)
   set(LLVM_VERSION_SUFFIX "")

Modified: vendor/llvm/dist/include/llvm/Analysis/LoopAccessAnalysis.h
==============================================================================
--- vendor/llvm/dist/include/llvm/Analysis/LoopAccessAnalysis.h	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/include/llvm/Analysis/LoopAccessAnalysis.h	Fri Nov 25 19:05:59 2016	(r309152)
@@ -334,9 +334,11 @@ public:
   struct PointerInfo {
     /// Holds the pointer value that we need to check.
     TrackingVH<Value> PointerValue;
-    /// Holds the pointer value at the beginning of the loop.
+    /// Holds the smallest byte address accessed by the pointer throughout all
+    /// iterations of the loop.
     const SCEV *Start;
-    /// Holds the pointer value at the end of the loop.
+    /// Holds the largest byte address accessed by the pointer throughout all
+    /// iterations of the loop, plus 1.
     const SCEV *End;
     /// Holds the information if this pointer is used for writing to memory.
     bool IsWritePtr;

Modified: vendor/llvm/dist/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
==============================================================================
--- vendor/llvm/dist/include/llvm/ExecutionEngine/RTDyldMemoryManager.h	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/include/llvm/ExecutionEngine/RTDyldMemoryManager.h	Fri Nov 25 19:05:59 2016	(r309152)
@@ -72,7 +72,7 @@ public:
   }
 
   void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
-    registerEHFramesInProcess(Addr, Size);
+    deregisterEHFramesInProcess(Addr, Size);
   }
 
   /// This method returns the address of the specified function or variable in

Modified: vendor/llvm/dist/include/llvm/IR/Intrinsics.td
==============================================================================
--- vendor/llvm/dist/include/llvm/IR/Intrinsics.td	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/include/llvm/IR/Intrinsics.td	Fri Nov 25 19:05:59 2016	(r309152)
@@ -668,13 +668,12 @@ def int_masked_gather: Intrinsic<[llvm_a
                                  [LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
                                   LLVMVectorSameWidth<0, llvm_i1_ty>,
                                   LLVMMatchType<0>],
-                                 [IntrReadMem, IntrArgMemOnly]>;
+				  [IntrReadMem]>;
 
 def int_masked_scatter: Intrinsic<[],
                                   [llvm_anyvector_ty,
                                    LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
-                                   LLVMVectorSameWidth<0, llvm_i1_ty>],
-                                  [IntrArgMemOnly]>;
+                                   LLVMVectorSameWidth<0, llvm_i1_ty>]>;
 
 // Test whether a pointer is associated with a type metadata identifier.
 def int_type_test : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty],

Modified: vendor/llvm/dist/include/llvm/IR/TypeFinder.h
==============================================================================
--- vendor/llvm/dist/include/llvm/IR/TypeFinder.h	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/include/llvm/IR/TypeFinder.h	Fri Nov 25 19:05:59 2016	(r309152)
@@ -59,6 +59,8 @@ public:
 
   StructType *&operator[](unsigned Idx) { return StructTypes[Idx]; }
 
+  DenseSet<const MDNode *> &getVisitedMetadata() { return VisitedMetadata; }
+
 private:
   /// incorporateType - This method adds the type to the list of used
   /// structures if it's not in there already.

Modified: vendor/llvm/dist/lib/Analysis/LoopAccessAnalysis.cpp
==============================================================================
--- vendor/llvm/dist/lib/Analysis/LoopAccessAnalysis.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Analysis/LoopAccessAnalysis.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -148,6 +148,19 @@ const SCEV *llvm::replaceSymbolicStrideS
   return OrigSCEV;
 }
 
+/// Calculate Start and End points of memory access.
+/// Let's assume A is the first access and B is a memory access on N-th loop
+/// iteration. Then B is calculated as:  
+///   B = A + Step*N . 
+/// Step value may be positive or negative.
+/// N is a calculated back-edge taken count:
+///     N = (TripCount > 0) ? RoundDown(TripCount -1 , VF) : 0
+/// Start and End points are calculated in the following way:
+/// Start = UMIN(A, B) ; End = UMAX(A, B) + SizeOfElt,
+/// where SizeOfElt is the size of single memory access in bytes.
+///
+/// There is no conflict when the intervals are disjoint:
+/// NoConflict = (P2.Start >= P1.End) || (P1.Start >= P2.End)
 void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, bool WritePtr,
                                     unsigned DepSetId, unsigned ASId,
                                     const ValueToValueMap &Strides,
@@ -176,12 +189,17 @@ void RuntimePointerChecking::insert(Loop
       if (CStep->getValue()->isNegative())
         std::swap(ScStart, ScEnd);
     } else {
-      // Fallback case: the step is not constant, but the we can still
+      // Fallback case: the step is not constant, but we can still
       // get the upper and lower bounds of the interval by using min/max
       // expressions.
       ScStart = SE->getUMinExpr(ScStart, ScEnd);
       ScEnd = SE->getUMaxExpr(AR->getStart(), ScEnd);
     }
+    // Add the size of the pointed element to ScEnd.
+    unsigned EltSize =
+      Ptr->getType()->getPointerElementType()->getScalarSizeInBits() / 8;
+    const SCEV *EltSizeSCEV = SE->getConstant(ScEnd->getType(), EltSize);
+    ScEnd = SE->getAddExpr(ScEnd, EltSizeSCEV);
   }
 
   Pointers.emplace_back(Ptr, ScStart, ScEnd, WritePtr, DepSetId, ASId, Sc);
@@ -1863,9 +1881,17 @@ std::pair<Instruction *, Instruction *> 
     Value *End0 =   ChkBuilder.CreateBitCast(A.End,   PtrArithTy1, "bc");
     Value *End1 =   ChkBuilder.CreateBitCast(B.End,   PtrArithTy0, "bc");
 
-    Value *Cmp0 = ChkBuilder.CreateICmpULE(Start0, End1, "bound0");
+    // [A|B].Start points to the first accessed byte under base [A|B].
+    // [A|B].End points to the last accessed byte, plus one.
+    // There is no conflict when the intervals are disjoint:
+    // NoConflict = (B.Start >= A.End) || (A.Start >= B.End)
+    //
+    // bound0 = (B.Start < A.End)
+    // bound1 = (A.Start < B.End)
+    //  IsConflict = bound0 & bound1
+    Value *Cmp0 = ChkBuilder.CreateICmpULT(Start0, End1, "bound0");
     FirstInst = getFirstInst(FirstInst, Cmp0, Loc);
-    Value *Cmp1 = ChkBuilder.CreateICmpULE(Start1, End0, "bound1");
+    Value *Cmp1 = ChkBuilder.CreateICmpULT(Start1, End0, "bound1");
     FirstInst = getFirstInst(FirstInst, Cmp1, Loc);
     Value *IsConflict = ChkBuilder.CreateAnd(Cmp0, Cmp1, "found.conflict");
     FirstInst = getFirstInst(FirstInst, IsConflict, Loc);

Modified: vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp
==============================================================================
--- vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -776,9 +776,8 @@ bool BranchFolder::CreateCommonTailOnlyB
 }
 
 static void
-mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos,
-                              MachineBasicBlock &MBBCommon) {
-  // Merge MMOs from memory operations in the common block.
+mergeOperations(MachineBasicBlock::iterator MBBIStartPos,
+                MachineBasicBlock &MBBCommon) {
   MachineBasicBlock *MBB = MBBIStartPos->getParent();
   // Note CommonTailLen does not necessarily matches the size of
   // the common BB nor all its instructions because of debug
@@ -808,8 +807,18 @@ mergeMMOsFromMemoryOperations(MachineBas
            "Reached BB end within common tail length!");
     assert(MBBICommon->isIdenticalTo(*MBBI) && "Expected matching MIIs!");
 
+    // Merge MMOs from memory operations in the common block.
     if (MBBICommon->mayLoad() || MBBICommon->mayStore())
       MBBICommon->setMemRefs(MBBICommon->mergeMemRefsWith(*MBBI));
+    // Drop undef flags if they aren't present in all merged instructions.
+    for (unsigned I = 0, E = MBBICommon->getNumOperands(); I != E; ++I) {
+      MachineOperand &MO = MBBICommon->getOperand(I);
+      if (MO.isReg() && MO.isUndef()) {
+        const MachineOperand &OtherMO = MBBI->getOperand(I);
+        if (!OtherMO.isUndef())
+          MO.setIsUndef(false);
+      }
+    }
 
     ++MBBI;
     ++MBBICommon;
@@ -928,8 +937,8 @@ bool BranchFolder::TryTailMergeBlocks(Ma
         continue;
       DEBUG(dbgs() << "BB#" << SameTails[i].getBlock()->getNumber()
                    << (i == e-1 ? "" : ", "));
-      // Merge MMOs from memory operations as needed.
-      mergeMMOsFromMemoryOperations(SameTails[i].getTailStartPos(), *MBB);
+      // Merge operations (MMOs, undef flags)
+      mergeOperations(SameTails[i].getTailStartPos(), *MBB);
       // Hack the end off BB i, making it jump to BB commonTailIndex instead.
       ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB);
       // BB i is no longer a predecessor of SuccBB; remove it from the worklist.

Modified: vendor/llvm/dist/lib/Linker/IRMover.cpp
==============================================================================
--- vendor/llvm/dist/lib/Linker/IRMover.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Linker/IRMover.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -694,6 +694,14 @@ void IRLinker::computeTypeMapping() {
     if (!ST->hasName())
       continue;
 
+    if (TypeMap.DstStructTypesSet.hasType(ST)) {
+      // This is actually a type from the destination module.
+      // getIdentifiedStructTypes() can have found it by walking debug info
+      // metadata nodes, some of which get linked by name when ODR Type Uniquing
+      // is enabled on the Context, from the source to the destination module.
+      continue;
+    }
+
     // Check to see if there is a dot in the name followed by a digit.
     size_t DotPos = ST->getName().rfind('.');
     if (DotPos == 0 || DotPos == StringRef::npos ||
@@ -1336,13 +1344,19 @@ bool IRMover::IdentifiedStructTypeSet::h
 
 IRMover::IRMover(Module &M) : Composite(M) {
   TypeFinder StructTypes;
-  StructTypes.run(M, true);
+  StructTypes.run(M, /* OnlyNamed */ false);
   for (StructType *Ty : StructTypes) {
     if (Ty->isOpaque())
       IdentifiedStructTypes.addOpaque(Ty);
     else
       IdentifiedStructTypes.addNonOpaque(Ty);
   }
+  // Self-map metadatas in the destination module. This is needed when
+  // DebugTypeODRUniquing is enabled on the LLVMContext, since metadata in the
+  // destination module may be reached from the source module.
+  for (auto *MD : StructTypes.getVisitedMetadata()) {
+    SharedMDs[MD].reset(const_cast<MDNode *>(MD));
+  }
 }
 
 Error IRMover::move(

Modified: vendor/llvm/dist/lib/Support/Unix/Signals.inc
==============================================================================
--- vendor/llvm/dist/lib/Support/Unix/Signals.inc	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Support/Unix/Signals.inc	Fri Nov 25 19:05:59 2016	(r309152)
@@ -412,7 +412,7 @@ void llvm::sys::PrintStackTrace(raw_ostr
 
   if (printSymbolizedStackTrace(Argv0, StackTrace, depth, OS))
     return;
-#if HAVE_DLFCN_H && __GNUG__
+#if HAVE_DLFCN_H && __GNUG__ && !defined(__CYGWIN__)
   int width = 0;
   for (int i = 0; i < depth; ++i) {
     Dl_info dlinfo;

Modified: vendor/llvm/dist/lib/Target/ARM/ARMInstrThumb2.td
==============================================================================
--- vendor/llvm/dist/lib/Target/ARM/ARMInstrThumb2.td	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/ARM/ARMInstrThumb2.td	Fri Nov 25 19:05:59 2016	(r309152)
@@ -4819,6 +4819,10 @@ def : t2InstAlias<"add${p} $Rd, pc, $imm
 def t2LDRConstPool
   : t2AsmPseudo<"ldr${p} $Rt, $immediate",
                 (ins GPRnopc:$Rt, const_pool_asm_imm:$immediate, pred:$p)>;
+// Version w/ the .w suffix.
+def : t2InstAlias<"ldr${p}.w $Rt, $immediate",
+                  (t2LDRConstPool GPRnopc:$Rt,
+                  const_pool_asm_imm:$immediate, pred:$p)>;
 
 // PLD/PLDW/PLI with alternate literal form.
 def : t2InstAlias<"pld${p} $addr",

Modified: vendor/llvm/dist/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/ARM/AsmParser/ARMAsmParser.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/ARM/AsmParser/ARMAsmParser.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -6933,6 +6933,9 @@ bool ARMAsmParser::processInstruction(MC
     else if (Inst.getOpcode() == ARM::t2LDRConstPool)
       TmpInst.setOpcode(ARM::t2LDRpci);
     const ARMOperand &PoolOperand =
+      (static_cast<ARMOperand &>(*Operands[2]).isToken() &&
+       static_cast<ARMOperand &>(*Operands[2]).getToken() == ".w") ?
+      static_cast<ARMOperand &>(*Operands[4]) :
       static_cast<ARMOperand &>(*Operands[3]);
     const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
     // If SubExprVal is a constant we may be able to use a MOV

Modified: vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -665,9 +665,10 @@ PPCTargetLowering::PPCTargetLowering(con
       addRegisterClass(MVT::v2i64, &PPC::VRRCRegClass);
       addRegisterClass(MVT::v1i128, &PPC::VRRCRegClass);
     }
+
     if (Subtarget.hasP9Vector()) {
-      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Legal);
-      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
+      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Custom);
+      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);
     }
   }
 
@@ -7846,6 +7847,17 @@ SDValue PPCTargetLowering::LowerSCALAR_T
   return DAG.getLoad(Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
 }
 
+SDValue PPCTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
+                                                  SelectionDAG &DAG) const {
+  assert(Op.getOpcode() == ISD::INSERT_VECTOR_ELT &&
+         "Should only be called for ISD::INSERT_VECTOR_ELT");
+  ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(2));
+  // We have legal lowering for constant indices but not for variable ones.
+  if (C)
+    return Op;
+  return SDValue();
+}
+
 SDValue PPCTargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
                                                    SelectionDAG &DAG) const {
   SDLoc dl(Op);
@@ -8248,6 +8260,7 @@ SDValue PPCTargetLowering::LowerOperatio
   case ISD::SCALAR_TO_VECTOR:   return LowerSCALAR_TO_VECTOR(Op, DAG);
   case ISD::SIGN_EXTEND_INREG:  return LowerSIGN_EXTEND_INREG(Op, DAG);
   case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
+  case ISD::INSERT_VECTOR_ELT:  return LowerINSERT_VECTOR_ELT(Op, DAG);
   case ISD::MUL:                return LowerMUL(Op, DAG);
 
   // For counter-based loop handling.
@@ -8372,7 +8385,9 @@ Instruction* PPCTargetLowering::emitTrai
 MachineBasicBlock *
 PPCTargetLowering::EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *BB,
                                     unsigned AtomicSize,
-                                    unsigned BinOpcode) const {
+                                    unsigned BinOpcode,
+                                    unsigned CmpOpcode,
+                                    unsigned CmpPred) const {
   // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
 
@@ -8412,8 +8427,12 @@ PPCTargetLowering::EmitAtomicBinary(Mach
   DebugLoc dl = MI.getDebugLoc();
 
   MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *loop2MBB =
+    CmpOpcode ? F->CreateMachineBasicBlock(LLVM_BB) : nullptr;
   MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
   F->insert(It, loopMBB);
+  if (CmpOpcode)
+    F->insert(It, loop2MBB);
   F->insert(It, exitMBB);
   exitMBB->splice(exitMBB->begin(), BB,
                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
@@ -8435,11 +8454,40 @@ PPCTargetLowering::EmitAtomicBinary(Mach
   //   st[wd]cx. r0, ptr
   //   bne- loopMBB
   //   fallthrough --> exitMBB
+
+  // For max/min...
+  //  loopMBB:
+  //   l[wd]arx dest, ptr
+  //   cmpl?[wd] incr, dest
+  //   bgt exitMBB
+  //  loop2MBB:
+  //   st[wd]cx. dest, ptr
+  //   bne- loopMBB
+  //   fallthrough --> exitMBB
+
   BB = loopMBB;
   BuildMI(BB, dl, TII->get(LoadMnemonic), dest)
     .addReg(ptrA).addReg(ptrB);
   if (BinOpcode)
     BuildMI(BB, dl, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
+  if (CmpOpcode) {
+    // Signed comparisons of byte or halfword values must be sign-extended.
+    if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
+      unsigned ExtReg =  RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
+      BuildMI(BB, dl, TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
+              ExtReg).addReg(dest);
+      BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
+        .addReg(incr).addReg(ExtReg);
+    } else
+      BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
+        .addReg(incr).addReg(dest);
+
+    BuildMI(BB, dl, TII->get(PPC::BCC))
+      .addImm(CmpPred).addReg(PPC::CR0).addMBB(exitMBB);
+    BB->addSuccessor(loop2MBB);
+    BB->addSuccessor(exitMBB);
+    BB = loop2MBB;
+  }
   BuildMI(BB, dl, TII->get(StoreMnemonic))
     .addReg(TmpReg).addReg(ptrA).addReg(ptrB);
   BuildMI(BB, dl, TII->get(PPC::BCC))
@@ -8457,10 +8505,13 @@ MachineBasicBlock *
 PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI,
                                             MachineBasicBlock *BB,
                                             bool is8bit, // operation
-                                            unsigned BinOpcode) const {
+                                            unsigned BinOpcode,
+                                            unsigned CmpOpcode,
+                                            unsigned CmpPred) const {
   // If we support part-word atomic mnemonics, just use them
   if (Subtarget.hasPartwordAtomics())
-    return EmitAtomicBinary(MI, BB, is8bit ? 1 : 2, BinOpcode);
+    return EmitAtomicBinary(MI, BB, is8bit ? 1 : 2, BinOpcode,
+                            CmpOpcode, CmpPred);
 
   // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
@@ -8482,8 +8533,12 @@ PPCTargetLowering::EmitPartwordAtomicBin
   DebugLoc dl = MI.getDebugLoc();
 
   MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *loop2MBB =
+    CmpOpcode ? F->CreateMachineBasicBlock(LLVM_BB) : nullptr;
   MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
   F->insert(It, loopMBB);
+  if (CmpOpcode)
+    F->insert(It, loop2MBB);
   F->insert(It, exitMBB);
   exitMBB->splice(exitMBB->begin(), BB,
                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
@@ -8568,6 +8623,32 @@ PPCTargetLowering::EmitPartwordAtomicBin
     .addReg(TmpDestReg).addReg(MaskReg);
   BuildMI(BB, dl, TII->get(is64bit ? PPC::AND8 : PPC::AND), Tmp3Reg)
     .addReg(TmpReg).addReg(MaskReg);
+  if (CmpOpcode) {
+    // For unsigned comparisons, we can directly compare the shifted values.
+    // For signed comparisons we shift and sign extend.
+    unsigned SReg = RegInfo.createVirtualRegister(RC);
+    BuildMI(BB, dl, TII->get(is64bit ? PPC::AND8 : PPC::AND), SReg)
+      .addReg(TmpDestReg).addReg(MaskReg);
+    unsigned ValueReg = SReg;
+    unsigned CmpReg = Incr2Reg;
+    if (CmpOpcode == PPC::CMPW) {
+      ValueReg = RegInfo.createVirtualRegister(RC);
+      BuildMI(BB, dl, TII->get(PPC::SRW), ValueReg)
+        .addReg(SReg).addReg(ShiftReg);
+      unsigned ValueSReg = RegInfo.createVirtualRegister(RC);
+      BuildMI(BB, dl, TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
+        .addReg(ValueReg);
+      ValueReg = ValueSReg;
+      CmpReg = incr;
+    }
+    BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
+      .addReg(CmpReg).addReg(ValueReg);
+    BuildMI(BB, dl, TII->get(PPC::BCC))
+      .addImm(CmpPred).addReg(PPC::CR0).addMBB(exitMBB);
+    BB->addSuccessor(loop2MBB);
+    BB->addSuccessor(exitMBB);
+    BB = loop2MBB;
+  }
   BuildMI(BB, dl, TII->get(is64bit ? PPC::OR8 : PPC::OR), Tmp4Reg)
     .addReg(Tmp3Reg).addReg(Tmp2Reg);
   BuildMI(BB, dl, TII->get(PPC::STWCX))
@@ -9074,6 +9155,42 @@ PPCTargetLowering::EmitInstrWithCustomIn
   else if (MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
     BB = EmitAtomicBinary(MI, BB, 8, PPC::SUBF8);
 
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
+    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPW, PPC::PRED_GE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
+    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPW, PPC::PRED_GE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
+    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPW, PPC::PRED_GE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
+    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPD, PPC::PRED_GE);
+
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
+    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPW, PPC::PRED_LE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
+    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPW, PPC::PRED_LE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
+    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPW, PPC::PRED_LE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
+    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPD, PPC::PRED_LE);
+
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
+    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPLW, PPC::PRED_GE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
+    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPLW, PPC::PRED_GE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
+    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPLW, PPC::PRED_GE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
+    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPLD, PPC::PRED_GE);
+
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
+    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPLW, PPC::PRED_LE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
+    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPLW, PPC::PRED_LE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
+    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPLW, PPC::PRED_LE);
+  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
+    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPLD, PPC::PRED_LE);
+
   else if (MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
     BB = EmitPartwordAtomicBinary(MI, BB, true, 0);
   else if (MI.getOpcode() == PPC::ATOMIC_SWAP_I16)

Modified: vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.h
==============================================================================
--- vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.h	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/PowerPC/PPCISelLowering.h	Fri Nov 25 19:05:59 2016	(r309152)
@@ -585,11 +585,15 @@ namespace llvm {
     MachineBasicBlock *EmitAtomicBinary(MachineInstr &MI,
                                         MachineBasicBlock *MBB,
                                         unsigned AtomicSize,
-                                        unsigned BinOpcode) const;
+                                        unsigned BinOpcode,
+                                        unsigned CmpOpcode = 0,
+                                        unsigned CmpPred = 0) const;
     MachineBasicBlock *EmitPartwordAtomicBinary(MachineInstr &MI,
                                                 MachineBasicBlock *MBB,
                                                 bool is8bit,
-                                                unsigned Opcode) const;
+                                                unsigned Opcode,
+                                                unsigned CmpOpcode = 0,
+                                                unsigned CmpPred = 0) const;
 
     MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
                                         MachineBasicBlock *MBB) const;
@@ -824,6 +828,7 @@ namespace llvm {
     SDValue LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;

Modified: vendor/llvm/dist/lib/Target/PowerPC/PPCInstr64Bit.td
==============================================================================
--- vendor/llvm/dist/lib/Target/PowerPC/PPCInstr64Bit.td	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/PowerPC/PPCInstr64Bit.td	Fri Nov 25 19:05:59 2016	(r309152)
@@ -224,6 +224,18 @@ let usesCustomInserter = 1 in {
     def ATOMIC_LOAD_NAND_I64 : Pseudo<
       (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_NAND_I64",
       [(set i64:$dst, (atomic_load_nand_64 xoaddr:$ptr, i64:$incr))]>;
+    def ATOMIC_LOAD_MIN_I64 : Pseudo<
+      (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_MIN_I64",
+      [(set i64:$dst, (atomic_load_min_64 xoaddr:$ptr, i64:$incr))]>;
+    def ATOMIC_LOAD_MAX_I64 : Pseudo<
+      (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_MAX_I64",
+      [(set i64:$dst, (atomic_load_max_64 xoaddr:$ptr, i64:$incr))]>;
+    def ATOMIC_LOAD_UMIN_I64 : Pseudo<
+      (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_UMIN_I64",
+      [(set i64:$dst, (atomic_load_umin_64 xoaddr:$ptr, i64:$incr))]>;
+    def ATOMIC_LOAD_UMAX_I64 : Pseudo<
+      (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_UMAX_I64",
+      [(set i64:$dst, (atomic_load_umax_64 xoaddr:$ptr, i64:$incr))]>;
 
     def ATOMIC_CMP_SWAP_I64 : Pseudo<
       (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$old, g8rc:$new), "#ATOMIC_CMP_SWAP_I64",

Modified: vendor/llvm/dist/lib/Target/PowerPC/PPCInstrInfo.td
==============================================================================
--- vendor/llvm/dist/lib/Target/PowerPC/PPCInstrInfo.td	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/PowerPC/PPCInstrInfo.td	Fri Nov 25 19:05:59 2016	(r309152)
@@ -1509,6 +1509,18 @@ let usesCustomInserter = 1 in {
     def ATOMIC_LOAD_NAND_I8 : Pseudo<
       (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I8",
       [(set i32:$dst, (atomic_load_nand_8 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_MIN_I8 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MIN_I8",
+      [(set i32:$dst, (atomic_load_min_8 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_MAX_I8 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MAX_I8",
+      [(set i32:$dst, (atomic_load_max_8 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_UMIN_I8 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMIN_I8",
+      [(set i32:$dst, (atomic_load_umin_8 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_UMAX_I8 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMAX_I8",
+      [(set i32:$dst, (atomic_load_umax_8 xoaddr:$ptr, i32:$incr))]>;
     def ATOMIC_LOAD_ADD_I16 : Pseudo<
       (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I16",
       [(set i32:$dst, (atomic_load_add_16 xoaddr:$ptr, i32:$incr))]>;
@@ -1527,6 +1539,18 @@ let usesCustomInserter = 1 in {
     def ATOMIC_LOAD_NAND_I16 : Pseudo<
       (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I16",
       [(set i32:$dst, (atomic_load_nand_16 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_MIN_I16 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MIN_I16",
+      [(set i32:$dst, (atomic_load_min_16 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_MAX_I16 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MAX_I16",
+      [(set i32:$dst, (atomic_load_max_16 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_UMIN_I16 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMIN_I16",
+      [(set i32:$dst, (atomic_load_umin_16 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_UMAX_I16 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMAX_I16",
+      [(set i32:$dst, (atomic_load_umax_16 xoaddr:$ptr, i32:$incr))]>;
     def ATOMIC_LOAD_ADD_I32 : Pseudo<
       (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I32",
       [(set i32:$dst, (atomic_load_add_32 xoaddr:$ptr, i32:$incr))]>;
@@ -1545,6 +1569,18 @@ let usesCustomInserter = 1 in {
     def ATOMIC_LOAD_NAND_I32 : Pseudo<
       (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I32",
       [(set i32:$dst, (atomic_load_nand_32 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_MIN_I32 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MIN_I32",
+      [(set i32:$dst, (atomic_load_min_32 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_MAX_I32 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MAX_I32",
+      [(set i32:$dst, (atomic_load_max_32 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_UMIN_I32 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMIN_I32",
+      [(set i32:$dst, (atomic_load_umin_32 xoaddr:$ptr, i32:$incr))]>;
+    def ATOMIC_LOAD_UMAX_I32 : Pseudo<
+      (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMAX_I32",
+      [(set i32:$dst, (atomic_load_umax_32 xoaddr:$ptr, i32:$incr))]>;
 
     def ATOMIC_CMP_SWAP_I8 : Pseudo<
       (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I8",

Modified: vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -8656,6 +8656,17 @@ static SDValue lowerVectorShuffleAsBroad
     V = DAG.getLoad(SVT, DL, Ld->getChain(), NewAddr,
                     DAG.getMachineFunction().getMachineMemOperand(
                         Ld->getMemOperand(), Offset, SVT.getStoreSize()));
+
+    // Make sure the newly-created LOAD is in the same position as Ld in
+    // terms of dependency. We create a TokenFactor for Ld and V,
+    // and update uses of Ld's output chain to use the TokenFactor.
+    if (Ld->hasAnyUseOfValue(1)) {
+      SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
+                                     SDValue(Ld, 1), SDValue(V.getNode(), 1));
+      DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), NewChain);
+      DAG.UpdateNodeOperands(NewChain.getNode(), SDValue(Ld, 1),
+                             SDValue(V.getNode(), 1));
+    }
   } else if (!BroadcastFromReg) {
     // We can't broadcast from a vector register.
     return SDValue();
@@ -27516,7 +27527,8 @@ static SDValue reduceVMULWidth(SDNode *N
                                const X86Subtarget &Subtarget) {
   // pmulld is supported since SSE41. It is better to use pmulld
   // instead of pmullw+pmulhw.
-  if (Subtarget.hasSSE41())
+  // pmullw/pmulhw are not supported by SSE.
+  if (Subtarget.hasSSE41() || !Subtarget.hasSSE2())
     return SDValue();
 
   ShrinkMode Mode;

Modified: vendor/llvm/dist/lib/Target/X86/X86InstrAVX512.td
==============================================================================
--- vendor/llvm/dist/lib/Target/X86/X86InstrAVX512.td	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Target/X86/X86InstrAVX512.td	Fri Nov 25 19:05:59 2016	(r309152)
@@ -2124,7 +2124,7 @@ let Predicates = [HasAVX512] in {
             (COPY_TO_REGCLASS (i16 (EXTRACT_SUBREG $src, sub_16bit)), VK1)>;
 
   def : Pat<(i1 (trunc (i8 GR8:$src))),
-            (COPY_TO_REGCLASS (i16 (SUBREG_TO_REG (i64 0), (AND8ri8 $src, (i8 1)),
+            (COPY_TO_REGCLASS (i16 (SUBREG_TO_REG (i64 0), (AND8ri $src, (i8 1)),
                                     sub_8bit)), VK1)>;
 
   def : Pat<(i1 (trunc (i8 (assertzext_i1 GR8:$src)))),

Modified: vendor/llvm/dist/lib/Transforms/Scalar/JumpThreading.cpp
==============================================================================
--- vendor/llvm/dist/lib/Transforms/Scalar/JumpThreading.cpp	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/lib/Transforms/Scalar/JumpThreading.cpp	Fri Nov 25 19:05:59 2016	(r309152)
@@ -1322,6 +1322,10 @@ bool JumpThreadingPass::ProcessBranchOnX
   if (!isa<PHINode>(BB->front()))
     return false;
 
+  // If this BB is a landing pad, we won't be able to split the edge into it.
+  if (BB->isEHPad())
+    return false;
+
   // If we have a xor as the branch input to this block, and we know that the
   // LHS or RHS of the xor in any predecessor is true/false, then we can clone
   // the condition into the predecessor and fix that value to true, saving some

Added: vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll	Fri Nov 25 19:05:59 2016	(r309152)
@@ -0,0 +1,51 @@
+; RUN: opt -analyze --loop-accesses %s | FileCheck %s
+
+; This test verifies run-time boundary check of memory accesses.
+; The original loop:
+;   void fastCopy(const char* src, char* op) {
+;     int len = 32;
+;     while (len > 0) {
+;       *(reinterpret_cast<long long*>(op)) = *(reinterpret_cast<const long long*>(src));
+;       src += 8;
+;       op += 8;
+;       len -= 8;
+;     }
+;   }
+; Boundaries calculations before this patch:
+; (Low: %src High: (24 + %src))
+; and the actual distance between two pointers was 31,  (%op - %src = 31)
+; IsConflict = (24 > 31) = false -> execution is directed to the vectorized loop.
+; The loop was vectorized to 4, 32 byte memory access ( <4 x i64> ),
+; store a value at *%op touched memory under *%src.
+
+;CHECK: Printing analysis 'Loop Access Analysis' for function 'fastCopy'
+;CHECK: (Low: %op High: (32 + %op))
+;CHECK: (Low: %src High: (32 + %src))
+
+define void @fastCopy(i8* nocapture readonly %src, i8* nocapture %op) {
+entry:
+  br label %while.body.preheader
+
+while.body.preheader:                             ; preds = %entry
+  br label %while.body
+
+while.body:                                       ; preds = %while.body.preheader, %while.body
+  %len.addr.07 = phi i32 [ %sub, %while.body ], [ 32, %while.body.preheader ]
+  %op.addr.06 = phi i8* [ %add.ptr1, %while.body ], [ %op, %while.body.preheader ]
+  %src.addr.05 = phi i8* [ %add.ptr, %while.body ], [ %src, %while.body.preheader ]
+  %0 = bitcast i8* %src.addr.05 to i64*
+  %1 = load i64, i64* %0, align 8
+  %2 = bitcast i8* %op.addr.06 to i64*
+  store i64 %1, i64* %2, align 8
+  %add.ptr = getelementptr inbounds i8, i8* %src.addr.05, i64 8
+  %add.ptr1 = getelementptr inbounds i8, i8* %op.addr.06, i64 8
+  %sub = add nsw i32 %len.addr.07, -8
+  %cmp = icmp sgt i32 %len.addr.07, 8
+  br i1 %cmp, label %while.body, label %while.end.loopexit
+
+while.end.loopexit:                               ; preds = %while.body
+  br label %while.end
+
+while.end:                                        ; preds = %while.end.loopexit, %entry
+  ret void
+}

Modified: vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
==============================================================================
--- vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll	Fri Nov 25 19:05:59 2016	(r309152)
@@ -96,15 +96,15 @@ for.end:                                
 ; CHECK-NEXT:       %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind
 ; CHECK-NEXT:   Grouped accesses:
 ; CHECK-NEXT:    Group {{.*}}[[ZERO]]:
-; CHECK-NEXT:       (Low: %c High: (78 + %c))
+; CHECK-NEXT:       (Low: %c High: (80 + %c))
 ; CHECK-NEXT:         Member: {(2 + %c)<nsw>,+,4}
 ; CHECK-NEXT:         Member: {%c,+,4}
 ; CHECK-NEXT:     Group {{.*}}[[ONE]]:
-; CHECK-NEXT:       (Low: %a High: (40 + %a))
+; CHECK-NEXT:       (Low: %a High: (42 + %a))
 ; CHECK-NEXT:         Member: {(2 + %a)<nsw>,+,2}
 ; CHECK-NEXT:         Member: {%a,+,2}
 ; CHECK-NEXT:     Group {{.*}}[[TWO]]:
-; CHECK-NEXT:       (Low: %b High: (38 + %b))
+; CHECK-NEXT:       (Low: %b High: (40 + %b))
 ; CHECK-NEXT:         Member: {%b,+,2}
 
 define void @testg(i16* %a,
@@ -168,15 +168,15 @@ for.end:                                
 ; CHECK-NEXT:         %arrayidxB = getelementptr i16, i16* %b, i64 %ind
 ; CHECK-NEXT:   Grouped accesses:
 ; CHECK-NEXT:     Group {{.*}}[[ZERO]]:
-; CHECK-NEXT:       (Low: %c High: (78 + %c))
+; CHECK-NEXT:       (Low: %c High: (80 + %c))
 ; CHECK-NEXT:         Member: {(2 + %c)<nsw>,+,4}
 ; CHECK-NEXT:         Member: {%c,+,4}
 ; CHECK-NEXT:     Group {{.*}}[[ONE]]:
-; CHECK-NEXT:       (Low: %a High: (40 + %a))
+; CHECK-NEXT:       (Low: %a High: (42 + %a))
 ; CHECK-NEXT:         Member: {(2 + %a),+,2}
 ; CHECK-NEXT:         Member: {%a,+,2}
 ; CHECK-NEXT:     Group {{.*}}[[TWO]]:
-; CHECK-NEXT:       (Low: %b High: (38 + %b))
+; CHECK-NEXT:       (Low: %b High: (40 + %b))
 ; CHECK-NEXT:         Member: {%b,+,2}
 
 define void @testh(i16* %a,
@@ -247,13 +247,13 @@ for.end:                                
 ; CHECK-NEXT:       %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2
 ; CHECK-NEXT:   Grouped accesses:
 ; CHECK-NEXT:     Group {{.*}}[[ZERO]]:
-; CHECK-NEXT:       (Low: ((2 * %offset) + %a)<nsw> High: (9998 + (2 * %offset) + %a))
+; CHECK-NEXT:       (Low: ((2 * %offset) + %a)<nsw> High: (10000 + (2 * %offset) + %a))
 ; CHECK-NEXT:         Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body>
 ; CHECK-NEXT:     Group {{.*}}[[ONE]]:
-; CHECK-NEXT:       (Low: %a High: (9998 + %a))
+; CHECK-NEXT:       (Low: %a High: (10000 + %a))
 ; CHECK-NEXT:         Member: {%a,+,2}<%for.body>
 ; CHECK-NEXT:     Group {{.*}}[[TWO]]:
-; CHECK-NEXT:       (Low: (20000 + %a) High: (29998 + %a))
+; CHECK-NEXT:       (Low: (20000 + %a) High: (30000 + %a))
 ; CHECK-NEXT:         Member: {(20000 + %a),+,2}<%for.body>
 
 define void @testi(i16* %a,

Modified: vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
==============================================================================
--- vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll	Fri Nov 25 18:57:14 2016	(r309151)
+++ vendor/llvm/dist/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll	Fri Nov 25 19:05:59 2016	(r309152)
@@ -16,7 +16,7 @@ target datalayout = "e-m:e-i64:64-i128:1
 target triple = "aarch64--linux-gnueabi"
 
 ; CHECK: function 'f':
-; CHECK: (Low: (20000 + %a) High: (60000 + %a)<nsw>)
+; CHECK: (Low: (20000 + %a) High: (60004 + %a))
 
 @B = common global i32* null, align 8
 @A = common global i32* null, align 8
@@ -59,7 +59,7 @@ for.end:                                
 ; Here it is not obvious what the limits are, since 'step' could be negative.
 
 ; CHECK: Low: (-1 + (-1 * ((-60001 + (-1 * %a)) umax (-60001 + (40000 * %step) + (-1 * %a)))))
-; CHECK: High: ((60000 + %a)<nsw> umax (60000 + (-40000 * %step) + %a))
+; CHECK: High: (4 + ((60000 + %a)<nsw> umax (60000 + (-40000 * %step) + %a)))
 
 define void @g(i64 %step) {
 entry:

Added: vendor/llvm/dist/test/CodeGen/PowerPC/atomic-minmax.ll
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/llvm/dist/test/CodeGen/PowerPC/atomic-minmax.ll	Fri Nov 25 19:05:59 2016	(r309152)
@@ -0,0 +1,435 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+define void @a32min(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 {
+entry:
+  %0 = atomicrmw min i32* %minimum, i32 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a32min
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpw 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: stwcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a32max(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 {
+entry:
+  %0 = atomicrmw max i32* %minimum, i32 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a32max
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpw 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: stwcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a32umin(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 {
+entry:
+  %0 = atomicrmw umin i32* %minimum, i32 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a32umin
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmplw 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: stwcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a32umax(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 {
+entry:
+  %0 = atomicrmw umax i32* %minimum, i32 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a32umax
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmplw 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: stwcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a16min(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 {
+entry:
+  %0 = atomicrmw min i16* %minimum, i16 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a16min
+; CHECK: lharx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpw 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: sthcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a16max(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 {
+entry:
+  %0 = atomicrmw max i16* %minimum, i16 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a16max
+; CHECK: lharx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpw 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: sthcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a16umin(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 {
+entry:
+  %0 = atomicrmw umin i16* %minimum, i16 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a16umin
+; CHECK: lharx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmplw 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: sthcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a16umax(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 {
+entry:
+  %0 = atomicrmw umax i16* %minimum, i16 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a16umax
+; CHECK: lharx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmplw 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: sthcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a8min(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 {
+entry:
+  %0 = atomicrmw min i8* %minimum, i8 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a8min
+; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpw 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: stbcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a8max(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 {
+entry:
+  %0 = atomicrmw max i8* %minimum, i8 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a8max
+; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpw 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: stbcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a8umin(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 {
+entry:
+  %0 = atomicrmw umin i8* %minimum, i8 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a8umin
+; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmplw 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: stbcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a8umax(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 {
+entry:
+  %0 = atomicrmw umax i8* %minimum, i8 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a8umax
+; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmplw 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: stbcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a64min(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 {
+entry:
+  %0 = atomicrmw min i64* %minimum, i64 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a64min
+; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpd 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: stdcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a64max(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 {
+entry:
+  %0 = atomicrmw max i64* %minimum, i64 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a64max
+; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpd 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: stdcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a64umin(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 {
+entry:
+  %0 = atomicrmw umin i64* %minimum, i64 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a64umin
+; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpld 4, [[OLDV]]
+; CHECK: bgelr 0
+; CHECK: stdcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @a64umax(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 {
+entry:
+  %0 = atomicrmw umax i64* %minimum, i64 %val monotonic
+  ret void
+
+; CHECK-LABEL: @a64umax
+; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: cmpld 4, [[OLDV]]
+; CHECK: blelr 0
+; CHECK: stdcx. 4, 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae16min(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 {
+entry:
+  %0 = atomicrmw min i16* %minimum, i16 %val monotonic
+  ret void
+
+; CHECK-LABEL: @ae16min
+; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 27
+; CHECK-DAG: li [[M1:[0-9]+]], 0
+; CHECK-DAG: rldicr 3, 3, 0, 61
+; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 16
+; CHECK-DAG: ori [[M2:[0-9]+]], [[M1]], 65535
+; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]]
+; CHECK-DAG: slw [[M:[0-9]+]], [[M2]], [[SA]]
+; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]]
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]]
+; CHECK: extsh [[SESMOLDV:[0-9]+]], [[SMOLDV]]
+; CHECK: cmpw 0, 4, [[SESMOLDV]]

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


More information about the svn-src-all mailing list