aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-11-25 19:05:59 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-11-25 19:05:59 +0000
commit6449741f4c1842221757c062f4abbae7bb524ba9 (patch)
tree5a2ca31d10f5ca2e8fb9c1ade59c306526de8329
parent60a9e02f5509f102642299ee408fab21b2ee30e4 (diff)
downloadsrc-6449741f4c1842221757c062f4abbae7bb524ba9.tar.gz
src-6449741f4c1842221757c062f4abbae7bb524ba9.zip
Vendor import of llvm release_39 branch r287912:vendor/llvm/llvm-release_39-r287912
Notes
Notes: svn path=/vendor/llvm/dist/; revision=309152 svn path=/vendor/llvm/llvm-release_39-r287912/; revision=309157; tag=vendor/llvm/llvm-release_39-r287912
-rw-r--r--CMakeLists.txt2
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h6
-rw-r--r--include/llvm/ExecutionEngine/RTDyldMemoryManager.h2
-rw-r--r--include/llvm/IR/Intrinsics.td5
-rw-r--r--include/llvm/IR/TypeFinder.h2
-rw-r--r--lib/Analysis/LoopAccessAnalysis.cpp32
-rw-r--r--lib/CodeGen/BranchFolding.cpp19
-rw-r--r--lib/Linker/IRMover.cpp16
-rw-r--r--lib/Support/Unix/Signals.inc2
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp3
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp127
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.h9
-rw-r--r--lib/Target/PowerPC/PPCInstr64Bit.td12
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td36
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp14
-rw-r--r--lib/Target/X86/X86InstrAVX512.td2
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp4
-rw-r--r--test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll51
-rw-r--r--test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll18
-rw-r--r--test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll4
-rw-r--r--test/CodeGen/PowerPC/atomic-minmax.ll435
-rw-r--r--test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll22
-rw-r--r--test/CodeGen/PowerPC/pr30451.ll69
-rw-r--r--test/CodeGen/X86/avx-vbroadcast.ll61
-rw-r--r--test/CodeGen/X86/branchfolding-undef.mir29
-rw-r--r--test/CodeGen/X86/no-and8ri8.ll18
-rw-r--r--test/CodeGen/X86/pr30298.ll43
-rw-r--r--test/LTO/X86/Inputs/type-mapping-src.ll20
-rw-r--r--test/LTO/X86/type-mapping-bug.ll50
-rw-r--r--test/MC/ARM/ldr-pseudo-wide.s71
-rw-r--r--test/ThinLTO/X86/Inputs/crash_debuginfo.ll33
-rw-r--r--test/ThinLTO/X86/Inputs/import_opaque_type.ll15
-rw-r--r--test/ThinLTO/X86/crash_debuginfo.ll46
-rw-r--r--test/ThinLTO/X86/import_opaque_type.ll27
-rw-r--r--test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll42
-rw-r--r--test/Transforms/JumpThreading/pr27840.ll33
-rw-r--r--test/Transforms/LoopVectorize/runtime-check-readonly.ll8
-rw-r--r--test/Transforms/LoopVectorize/tbaa-nodep.ll14
-rw-r--r--test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll6
40 files changed, 1361 insertions, 51 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 039315055444..b38f45d12689 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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 "")
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index ceee1be5e1e7..619fab283102 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -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;
diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
index adcb063f4544..9451fa57c0f6 100644
--- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
+++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -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
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 5ece731fa143..e9264ec59b55 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -668,13 +668,12 @@ def int_masked_gather: Intrinsic<[llvm_anyvector_ty],
[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],
diff --git a/include/llvm/IR/TypeFinder.h b/include/llvm/IR/TypeFinder.h
index d5baf7ab0b9e..046f85caec9d 100644
--- a/include/llvm/IR/TypeFinder.h
+++ b/include/llvm/IR/TypeFinder.h
@@ -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.
diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp
index 0d774cf08e2f..5214eb7c051c 100644
--- a/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/lib/Analysis/LoopAccessAnalysis.cpp
@@ -148,6 +148,19 @@ const SCEV *llvm::replaceSymbolicStrideSCEV(PredicatedScalarEvolution &PSE,
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 *Lp, Value *Ptr, bool WritePtr,
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 *> LoopAccessInfo::addRuntimeChecks(
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);
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 23e2aa70d0c7..5dacbf9e6b02 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -776,9 +776,8 @@ bool BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
}
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(MachineBasicBlock::iterator MBBIStartPos,
"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(MachineBasicBlock *SuccBB,
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.
diff --git a/lib/Linker/IRMover.cpp b/lib/Linker/IRMover.cpp
index 4935868c00f4..09c67bc47863 100644
--- a/lib/Linker/IRMover.cpp
+++ b/lib/Linker/IRMover.cpp
@@ -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::hasType(StructType *Ty) {
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(
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc
index 117d4e8bcb52..55fd76d375a2 100644
--- a/lib/Support/Unix/Signals.inc
+++ b/lib/Support/Unix/Signals.inc
@@ -412,7 +412,7 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
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;
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index fe699b284882..db8b9fb923bf 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -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",
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 7d49302f9a96..f5de8a3cd25e 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6933,6 +6933,9 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
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
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 3d06de804200..6dd73174565a 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -665,9 +665,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
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_TO_VECTOR(SDValue Op,
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::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
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::emitTrailingFence(IRBuilder<> &Builder,
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(MachineInstr &MI, MachineBasicBlock *BB,
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(MachineInstr &MI, MachineBasicBlock *BB,
// 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::EmitPartwordAtomicBinary(MachineInstr &MI,
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::EmitPartwordAtomicBinary(MachineInstr &MI,
.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::EmitInstrWithCustomInserter(MachineInstr &MI,
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)
diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h
index e3be8074e62e..e60504507d32 100644
--- a/lib/Target/PowerPC/PPCISelLowering.h
+++ b/lib/Target/PowerPC/PPCISelLowering.h
@@ -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;
diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td
index e7eb8a16180a..5e514c8e8cf6 100644
--- a/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -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",
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 4a42a947c6cb..a40d4e1a4a69 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -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",
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 2c548384f1cb..ca2053350138 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -8656,6 +8656,17 @@ static SDValue lowerVectorShuffleAsBroadcast(const SDLoc &DL, MVT VT,
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, SelectionDAG &DAG,
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;
diff --git a/lib/Target/X86/X86InstrAVX512.td b/lib/Target/X86/X86InstrAVX512.td
index de4129f86541..803a7e35c209 100644
--- a/lib/Target/X86/X86InstrAVX512.td
+++ b/lib/Target/X86/X86InstrAVX512.td
@@ -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)))),
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index d1769fc3ebb3..55ffc23e1308 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1322,6 +1322,10 @@ bool JumpThreadingPass::ProcessBranchOnXOR(BinaryOperator *BO) {
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
diff --git a/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll b/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll
new file mode 100644
index 000000000000..01813c8a8104
--- /dev/null
+++ b/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll
@@ -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
+}
diff --git a/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll b/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
index a9626f4dc710..2bae4867870a 100644
--- a/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
+++ b/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
@@ -96,15 +96,15 @@ for.end: ; preds = %for.body
; 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: ; preds = %for.body
; 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: ; preds = %for.body
; 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,
diff --git a/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll b/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
index 607e007f7a2d..405a47554e4e 100644
--- a/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
+++ b/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
@@ -16,7 +16,7 @@ target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
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: ; preds = %for.body
; 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:
diff --git a/test/CodeGen/PowerPC/atomic-minmax.ll b/test/CodeGen/PowerPC/atomic-minmax.ll
new file mode 100644
index 000000000000..5b9a15331897
--- /dev/null
+++ b/test/CodeGen/PowerPC/atomic-minmax.ll
@@ -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]]
+; CHECK: bgelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae16max(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 {
+entry:
+ %0 = atomicrmw max i16* %minimum, i16 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae16max
+; 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]]
+; CHECK: blelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae16umin(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 {
+entry:
+ %0 = atomicrmw umin i16* %minimum, i16 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae16umin
+; 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: cmplw 0, 4, [[MOLDV]]
+; CHECK: bgelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae16umax(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 {
+entry:
+ %0 = atomicrmw umax i16* %minimum, i16 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae16umax
+; 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: cmplw 0, 4, [[MOLDV]]
+; CHECK: blelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae8min(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 {
+entry:
+ %0 = atomicrmw min i8* %minimum, i8 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae8min
+; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28
+; CHECK-DAG: li [[M1:[0-9]+]], 255
+; CHECK-DAG: rldicr 3, 3, 0, 61
+; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24
+; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]]
+; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[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: extsb [[SESMOLDV:[0-9]+]], [[SMOLDV]]
+; CHECK: cmpw 0, 4, [[SESMOLDV]]
+; CHECK: bgelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae8max(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 {
+entry:
+ %0 = atomicrmw max i8* %minimum, i8 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae8max
+; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28
+; CHECK-DAG: li [[M1:[0-9]+]], 255
+; CHECK-DAG: rldicr 3, 3, 0, 61
+; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24
+; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]]
+; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[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: extsb [[SESMOLDV:[0-9]+]], [[SMOLDV]]
+; CHECK: cmpw 0, 4, [[SESMOLDV]]
+; CHECK: blelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae8umin(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 {
+entry:
+ %0 = atomicrmw umin i8* %minimum, i8 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae8umin
+; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28
+; CHECK-DAG: li [[M1:[0-9]+]], 255
+; CHECK-DAG: rldicr 3, 3, 0, 61
+; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24
+; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]]
+; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[SA]]
+; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]]
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: cmplw 0, 4, [[MOLDV]]
+; CHECK: bgelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+define void @ae8umax(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 {
+entry:
+ %0 = atomicrmw umax i8* %minimum, i8 %val monotonic
+ ret void
+
+; CHECK-LABEL: @ae8umax
+; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28
+; CHECK-DAG: li [[M1:[0-9]+]], 255
+; CHECK-DAG: rldicr 3, 3, 0, 61
+; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24
+; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]]
+; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[SA]]
+; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]]
+; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3
+; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: cmplw 0, 4, [[MOLDV]]
+; CHECK: blelr 0
+; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]]
+; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]]
+; CHECK: stwcx. [[NEWV]], 0, 3
+; CHECK: bne 0,
+; CHECK: blr
+}
+
+attributes #0 = { nounwind "target-cpu"="ppc64" }
+attributes #1 = { nounwind "target-cpu"="pwr8" }
+
diff --git a/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll b/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll
index ac187e084257..fa2844b8d551 100644
--- a/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll
+++ b/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll
@@ -968,3 +968,25 @@ entry:
%vecins = shufflevector <4 x float> %a, <4 x float> %a, <4 x i32> <i32 0, i32 1, i32 2, i32 6>
ret <4 x float> %vecins
}
+define <4 x float> @insertVarF(<4 x float> %a, float %f, i32 %el) {
+entry:
+; CHECK-LABEL: insertVarF
+; CHECK: stxsspx 1,
+; CHECK: lxvd2x
+; CHECK-BE-LABEL: insertVarF
+; CHECK-BE: stxsspx 1,
+; CHECK-BE: lxvw4x
+ %vecins = insertelement <4 x float> %a, float %f, i32 %el
+ ret <4 x float> %vecins
+}
+define <4 x i32> @insertVarI(<4 x i32> %a, i32 %i, i32 %el) {
+entry:
+; CHECK-LABEL: insertVarI
+; CHECK: stwx
+; CHECK: lxvd2x
+; CHECK-BE-LABEL: insertVarI
+; CHECK-BE: stwx
+; CHECK-BE: lxvw4x
+ %vecins = insertelement <4 x i32> %a, i32 %i, i32 %el
+ ret <4 x i32> %vecins
+}
diff --git a/test/CodeGen/PowerPC/pr30451.ll b/test/CodeGen/PowerPC/pr30451.ll
new file mode 100644
index 000000000000..930553451cf8
--- /dev/null
+++ b/test/CodeGen/PowerPC/pr30451.ll
@@ -0,0 +1,69 @@
+; RUN: llc < %s -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown | FileCheck %s
+define i8 @atomic_min_i8() {
+ top:
+ %0 = alloca i8, align 2
+ %1 = bitcast i8* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i8 -1, i8* %0, align 2
+ %2 = atomicrmw min i8* %0, i8 0 acq_rel
+ %3 = load atomic i8, i8* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i8 %3
+; CHECK-LABEL: atomic_min_i8
+; CHECK: lbarx [[DST:[0-9]+]],
+; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: bge 0
+}
+define i16 @atomic_min_i16() {
+ top:
+ %0 = alloca i16, align 2
+ %1 = bitcast i16* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i16 -1, i16* %0, align 2
+ %2 = atomicrmw min i16* %0, i16 0 acq_rel
+ %3 = load atomic i16, i16* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i16 %3
+; CHECK-LABEL: atomic_min_i16
+; CHECK: lharx [[DST:[0-9]+]],
+; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: bge 0
+}
+
+define i8 @atomic_max_i8() {
+ top:
+ %0 = alloca i8, align 2
+ %1 = bitcast i8* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i8 -1, i8* %0, align 2
+ %2 = atomicrmw max i8* %0, i8 0 acq_rel
+ %3 = load atomic i8, i8* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i8 %3
+; CHECK-LABEL: atomic_max_i8
+; CHECK: lbarx [[DST:[0-9]+]],
+; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: ble 0
+}
+define i16 @atomic_max_i16() {
+ top:
+ %0 = alloca i16, align 2
+ %1 = bitcast i16* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i16 -1, i16* %0, align 2
+ %2 = atomicrmw max i16* %0, i16 0 acq_rel
+ %3 = load atomic i16, i16* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i16 %3
+; CHECK-LABEL: atomic_max_i16
+; CHECK: lharx [[DST:[0-9]+]],
+; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: ble 0
+}
+
+declare void @llvm.lifetime.start(i64, i8*)
+declare void @llvm.lifetime.end(i64, i8*)
diff --git a/test/CodeGen/X86/avx-vbroadcast.ll b/test/CodeGen/X86/avx-vbroadcast.ll
index b312be9aa6b2..534670795894 100644
--- a/test/CodeGen/X86/avx-vbroadcast.ll
+++ b/test/CodeGen/X86/avx-vbroadcast.ll
@@ -546,3 +546,64 @@ define <4 x double> @splat_concat4(double* %p) {
%6 = shufflevector <2 x double> %3, <2 x double> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x double> %6
}
+
+;
+; When VBROADCAST replaces an existing load, ensure it still respects lifetime dependencies.
+;
+define float @broadcast_lifetime() nounwind {
+; X32-LABEL: broadcast_lifetime:
+; X32: ## BB#0:
+; X32-NEXT: pushl %esi
+; X32-NEXT: subl $56, %esp
+; X32-NEXT: leal {{[0-9]+}}(%esp), %esi
+; X32-NEXT: movl %esi, (%esp)
+; X32-NEXT: calll _gfunc
+; X32-NEXT: vbroadcastss {{[0-9]+}}(%esp), %xmm0
+; X32-NEXT: vmovaps %xmm0, {{[0-9]+}}(%esp) ## 16-byte Spill
+; X32-NEXT: movl %esi, (%esp)
+; X32-NEXT: calll _gfunc
+; X32-NEXT: vbroadcastss {{[0-9]+}}(%esp), %xmm0
+; X32-NEXT: vsubss {{[0-9]+}}(%esp), %xmm0, %xmm0 ## 16-byte Folded Reload
+; X32-NEXT: vmovss %xmm0, {{[0-9]+}}(%esp)
+; X32-NEXT: flds {{[0-9]+}}(%esp)
+; X32-NEXT: addl $56, %esp
+; X32-NEXT: popl %esi
+; X32-NEXT: retl
+;
+; X64-LABEL: broadcast_lifetime:
+; X64: ## BB#0:
+; X64-NEXT: subq $40, %rsp
+; X64-NEXT: leaq (%rsp), %rdi
+; X64-NEXT: callq _gfunc
+; X64-NEXT: vbroadcastss {{[0-9]+}}(%rsp), %xmm0
+; X64-NEXT: vmovaps %xmm0, {{[0-9]+}}(%rsp) ## 16-byte Spill
+; X64-NEXT: leaq (%rsp), %rdi
+; X64-NEXT: callq _gfunc
+; X64-NEXT: vbroadcastss {{[0-9]+}}(%rsp), %xmm0
+; X64-NEXT: vsubss {{[0-9]+}}(%rsp), %xmm0, %xmm0 ## 16-byte Folded Reload
+; X64-NEXT: addq $40, %rsp
+; X64-NEXT: retq
+ %1 = alloca <4 x float>, align 16
+ %2 = alloca <4 x float>, align 16
+ %3 = bitcast <4 x float>* %1 to i8*
+ %4 = bitcast <4 x float>* %2 to i8*
+
+ call void @llvm.lifetime.start(i64 16, i8* %3)
+ call void @gfunc(<4 x float>* %1)
+ %5 = load <4 x float>, <4 x float>* %1, align 16
+ call void @llvm.lifetime.end(i64 16, i8* %3)
+
+ call void @llvm.lifetime.start(i64 16, i8* %4)
+ call void @gfunc(<4 x float>* %2)
+ %6 = load <4 x float>, <4 x float>* %2, align 16
+ call void @llvm.lifetime.end(i64 16, i8* %4)
+
+ %7 = extractelement <4 x float> %5, i32 1
+ %8 = extractelement <4 x float> %6, i32 1
+ %9 = fsub float %8, %7
+ ret float %9
+}
+
+declare void @gfunc(<4 x float>*)
+declare void @llvm.lifetime.start(i64, i8*)
+declare void @llvm.lifetime.end(i64, i8*)
diff --git a/test/CodeGen/X86/branchfolding-undef.mir b/test/CodeGen/X86/branchfolding-undef.mir
new file mode 100644
index 000000000000..0da167b33257
--- /dev/null
+++ b/test/CodeGen/X86/branchfolding-undef.mir
@@ -0,0 +1,29 @@
+# RUN: llc -o - %s -march=x86 -run-pass branch-folder | FileCheck %s
+# Test that tail merging drops undef flags that aren't present on all
+# instructions to be merged.
+--- |
+ define void @func() { ret void }
+...
+---
+# CHECK-LABEL: name: func
+# CHECK: bb.1:
+# CHECK: %eax = MOV32ri 2
+# CHECK-NOT: RET
+# CHECK: bb.2:
+# CHECK-NOT: RET 0, undef %eax
+# CHECK: RET 0, %eax
+name: func
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1, %bb.2
+ JE_1 %bb.1, implicit undef %eflags
+ JMP_1 %bb.2
+
+ bb.1:
+ %eax = MOV32ri 2
+ RET 0, %eax
+
+ bb.2:
+ RET 0, undef %eax
+...
diff --git a/test/CodeGen/X86/no-and8ri8.ll b/test/CodeGen/X86/no-and8ri8.ll
new file mode 100644
index 000000000000..57f33226602e
--- /dev/null
+++ b/test/CodeGen/X86/no-and8ri8.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=x86_64-pc-linux -mattr=+avx512f --show-mc-encoding < %s | FileCheck %s
+
+declare i1 @bar()
+
+; CHECK-LABEL: @foo
+; CHECK-NOT: andb {{.*}} # encoding: [0x82,
+define i1 @foo(i1 %i) nounwind {
+entry:
+ br i1 %i, label %if, label %else
+
+if:
+ %r = call i1 @bar()
+ br label %else
+
+else:
+ %ret = phi i1 [%r, %if], [true, %entry]
+ ret i1 %ret
+}
diff --git a/test/CodeGen/X86/pr30298.ll b/test/CodeGen/X86/pr30298.ll
new file mode 100644
index 000000000000..1e6dad0b20d1
--- /dev/null
+++ b/test/CodeGen/X86/pr30298.ll
@@ -0,0 +1,43 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=i386-pc-linux-gnu -mattr=+sse < %s | FileCheck %s
+
+@c = external global i32*, align 8
+
+define void @mul_2xi8(i8* nocapture readonly %a, i8* nocapture readonly %b, i64 %index) nounwind {
+; CHECK-LABEL: mul_2xi8:
+; CHECK: # BB#0: # %entry
+; CHECK-NEXT: pushl %ebx
+; CHECK-NEXT: pushl %edi
+; CHECK-NEXT: pushl %esi
+; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT: movl c, %esi
+; CHECK-NEXT: movzbl 1(%edx,%ecx), %edi
+; CHECK-NEXT: movzbl (%edx,%ecx), %edx
+; CHECK-NEXT: movzbl 1(%eax,%ecx), %ebx
+; CHECK-NEXT: movzbl (%eax,%ecx), %eax
+; CHECK-NEXT: imull %edx, %eax
+; CHECK-NEXT: imull %edi, %ebx
+; CHECK-NEXT: movl %ebx, 4(%esi,%ecx,4)
+; CHECK-NEXT: movl %eax, (%esi,%ecx,4)
+; CHECK-NEXT: popl %esi
+; CHECK-NEXT: popl %edi
+; CHECK-NEXT: popl %ebx
+; CHECK-NEXT: retl
+entry:
+ %pre = load i32*, i32** @c
+ %tmp6 = getelementptr inbounds i8, i8* %a, i64 %index
+ %tmp7 = bitcast i8* %tmp6 to <2 x i8>*
+ %wide.load = load <2 x i8>, <2 x i8>* %tmp7, align 1
+ %tmp8 = zext <2 x i8> %wide.load to <2 x i32>
+ %tmp10 = getelementptr inbounds i8, i8* %b, i64 %index
+ %tmp11 = bitcast i8* %tmp10 to <2 x i8>*
+ %wide.load17 = load <2 x i8>, <2 x i8>* %tmp11, align 1
+ %tmp12 = zext <2 x i8> %wide.load17 to <2 x i32>
+ %tmp13 = mul nuw nsw <2 x i32> %tmp12, %tmp8
+ %tmp14 = getelementptr inbounds i32, i32* %pre, i64 %index
+ %tmp15 = bitcast i32* %tmp14 to <2 x i32>*
+ store <2 x i32> %tmp13, <2 x i32>* %tmp15, align 4
+ ret void
+}
diff --git a/test/LTO/X86/Inputs/type-mapping-src.ll b/test/LTO/X86/Inputs/type-mapping-src.ll
new file mode 100644
index 000000000000..3a80560a4486
--- /dev/null
+++ b/test/LTO/X86/Inputs/type-mapping-src.ll
@@ -0,0 +1,20 @@
+target triple = "x86_64-pc-windows-msvc18.0.0"
+
+%SrcType = type { i8 }
+@x = external global %SrcType
+
+%CommonStruct = type opaque
+@bar = internal global %CommonStruct* null, !dbg !0
+
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!12}
+!0 = distinct !DIGlobalVariable(name: "bar", linkageName: "bar", scope: !1, file: !2, line: 2, type: !5, isLocal: false, isDefinition: true)
+!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4)
+!2 = !DIFile(filename: "b", directory: "/")
+!3 = !{}
+!4 = !{!0}
+!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64)
+!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !2, line: 1, flags: DIFlagFwdDecl, identifier: ".?AUS@@")
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+
diff --git a/test/LTO/X86/type-mapping-bug.ll b/test/LTO/X86/type-mapping-bug.ll
new file mode 100644
index 000000000000..3a1891234c86
--- /dev/null
+++ b/test/LTO/X86/type-mapping-bug.ll
@@ -0,0 +1,50 @@
+; RUN: llvm-as -o %t.dst.bc %s
+; RUN: llvm-as -o %t.src.bc %S/Inputs/type-mapping-src.ll
+; RUN: llvm-lto %t.dst.bc %t.src.bc -o=/dev/null
+
+target triple = "x86_64-pc-windows-msvc18.0.0"
+
+; @x in Src will be linked with this @x, causing SrcType in Src to be mapped
+; to %DstType.
+%DstType = type { i8 }
+@x = global %DstType zeroinitializer
+
+; The Src module will re-use our DINode for this type.
+%CommonStruct = type { i32 }
+@foo = internal global %CommonStruct zeroinitializer, !dbg !5
+
+; That DINode will refer to this value, casted to %Tricky.1* (!11),
+; which will then show up in Src's getIdentifiedStructTypes().
+@templateValueParam = global i8 zeroinitializer
+
+; Because of the names, we would try to map %Tricky.1 to %Tricky --
+; mapping a Dst type to another Dst type! This would assert when
+; getting a mapping from %DstType, which has previously used as
+; a destination type. Since these types are not in the source module,
+; there should be no attempt to create a mapping involving them;
+; both types should be left as they are.
+%Tricky = type opaque
+%Tricky.1 = type { %DstType* }
+
+
+; Mark %Tricky used.
+@use = global %Tricky* zeroinitializer
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!19}
+!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4)
+!2 = !DIFile(filename: "a", directory: "/")
+!3 = !{}
+!4 = !{!5}
+!5 = distinct !DIGlobalVariable(name: "foo", linkageName: "foo", scope: !1, file: !2, line: 5, type: !6, isLocal: false, isDefinition: true)
+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !2, line: 5, size: 8, elements: !7, identifier: ".?AUS@@")
+!7 = !{!8}
+!8 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !6, baseType: !9)
+!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Template<&x>", file: !2, line: 3, size: 8, elements: !3, templateParams: !10, identifier: ".?AU?$Template@$1?x@@3UX@@A@@")
+!10 = !{!11}
+
+!11 = !DITemplateValueParameter(type: !12, value: %Tricky.1* bitcast (i8* @templateValueParam to %Tricky.1*))
+
+!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
+!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "X", file: !2, line: 1, size: 8, elements: !3, identifier: ".?AUX@@")
+!19 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/test/MC/ARM/ldr-pseudo-wide.s b/test/MC/ARM/ldr-pseudo-wide.s
new file mode 100644
index 000000000000..ae1799f706ac
--- /dev/null
+++ b/test/MC/ARM/ldr-pseudo-wide.s
@@ -0,0 +1,71 @@
+@ Test case for PR30352
+@ Check that ldr.w is:
+@ accepted and ignored for ARM
+@ accepted and propagated for Thumb2
+@ rejected as needing Thumb2 for Thumb
+
+@RUN: llvm-mc -triple armv5-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-ARM --check-prefix=CHECK %s
+@RUN: llvm-mc -triple armv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-DARWIN-ARM --check-prefix=CHECK-DARWIN %s
+@RUN: llvm-mc -triple thumbv7-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-THUMB2 --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-DARWIN-THUMB2 --check-prefix=CHECK-DARWIN %s
+@RUN: not llvm-mc -triple thumbv6-unknown-linux-gnueabi %s 2>&1 | FileCheck --check-prefix=CHECK-THUMB %s
+@RUN: not llvm-mc -triple thumbv6-base-apple-darwin %s 2>&1 | FileCheck --check-prefix=CHECK-THUMB %s
+@ CHECK-LABEL: f1:
+f1:
+ ldr r0, =0x10002
+@ CHECK-ARM: ldr r0, .Ltmp[[TMP0:[0-9]+]]
+@ CHECK-DARWIN-ARM: ldr r0, Ltmp0
+@ CHECK-THUMB2: ldr r0, .Ltmp[[TMP0:[0-9]+]]
+@ CHECK-DARWIN-THUMB2: ldr r0, Ltmp0
+
+ ldr.w r0, =0x10002
+@ CHECK-ARM: ldr r0, .Ltmp[[TMP1:[0-9]+]]
+@ CHECK-DARWIN-ARM: ldr r0, Ltmp1
+@ CHECK-THUMB2: ldr.w r0, .Ltmp[[TMP1:[0-9]+]]
+@ CHECK-DARWIN-THUMB2: ldr.w r0, Ltmp1
+@ CHECK-THUMB: error: instruction requires: thumb2
+@ CHECK-THUMB-NEXT: ldr.w r0, =0x10002
+
+@ CHECK-LABEL: f2:
+f2:
+ ldr r0, =foo
+@ CHECK-ARM: ldr r0, .Ltmp[[TMP2:[0-9]+]]
+@ CHECK-DARWIN-ARM: ldr r0, Ltmp2
+@ CHECK-THUMB2: ldr r0, .Ltmp[[TMP2:[0-9]+]]
+@ CHECK-DARWIN-THUMB2: ldr r0, Ltmp2
+
+ ldr.w r0, =foo
+@ CHECK-ARM: ldr r0, .Ltmp[[TMP3:[0-9]+]]
+@ CHECK-DARWIN-ARM: ldr r0, Ltmp3
+@ CHECK-THUMB2: ldr.w r0, .Ltmp[[TMP3:[0-9]+]]
+@ CHECK-DARWIN-THUMB2: ldr.w r0, Ltmp3
+@ CHECK-THUMB: error: instruction requires: thumb2
+@ CHECK-THUMB-NEXT: ldr.w r0, =foo
+
+@ CHECK-LABEL: f3:
+f3:
+ ldr.w r1, =0x1
+@ CHECK-ARM: mov r1, #1
+@ CHECK-DARWIN-ARM: mov r1, #1
+@ CHECK-THUMB2: mov.w r1, #1
+@ CHECK-DARWIN-THUMB2: mov.w r1, #1
+@ CHECK-THUMB: error: instruction requires: thumb2
+@ CHECK-THUMB-NEXT: ldr.w r1, =0x1
+
+@ CHECK: .Ltmp0:
+@ CHECK-NEXT: .long 65538
+@ CHECK: .Ltmp1:
+@ CHECK-NEXT: .long 65538
+@ CHECK: .Ltmp2:
+@ CHECK-NEXT: .long foo
+@ CHECK: .Ltmp3:
+@ CHECK-NEXT: .long foo
+
+@ CHECK-DARWIN: Ltmp0:
+@ CHECK-DARWIN-NEXT: .long 65538
+@ CHECK-DARWIN: Ltmp1:
+@ CHECK-DARWIN-NEXT: .long 65538
+@ CHECK-DARWIN: Ltmp2:
+@ CHECK-DARWIN-NEXT: .long foo
+@ CHECK-DARWIN: Ltmp3:
+@ CHECK-DARWIN-NEXT: .long foo
diff --git a/test/ThinLTO/X86/Inputs/crash_debuginfo.ll b/test/ThinLTO/X86/Inputs/crash_debuginfo.ll
new file mode 100644
index 000000000000..9bb9a2fb0c5c
--- /dev/null
+++ b/test/ThinLTO/X86/Inputs/crash_debuginfo.ll
@@ -0,0 +1,33 @@
+; ModuleID = 'test/ThinLTO/X86/Inputs/crash_debuginfo.ll'
+source_filename = "src.bc"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.0"
+
+%another_type = type { i32 }
+
+define void @bar(i32 %arg) {
+ %tmp = add i32 %arg, 0, !dbg !7
+ unreachable
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "Apple LLVM version 8.0.0 (clang-800.0.25.1)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !3, imports: !2)
+!1 = !DIFile(filename: "2.cpp", directory: "some_dir")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DIGlobalVariable(name: "a_global", linkageName: "a_global", scope: null, line: 52, type: !5, isLocal: true, isDefinition: true, variable: %another_type** undef)
+!5 = !DISubroutineType(types: !2)
+!6 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DILocation(line: 728, column: 71, scope: !8, inlinedAt: !14)
+!8 = distinct !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !5, isLocal: false, isDefinition: true, scopeLine: 727, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !10, variables: !11)
+!9 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "some_other_class", scope: !1, file: !1, line: 197, size: 192, align: 64, elements: !2, templateParams: !2, identifier: "some_other_class")
+!10 = !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !5, isLocal: false, isDefinition: false, scopeLine: 726, flags: DIFlagPrototyped, isOptimized: true)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "caster", scope: !8, file: !1, line: 728, type: !13)
+!13 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !8, file: !1, line: 728, size: 64, align: 64, elements: !2, identifier: "someclass")
+!14 = distinct !DILocation(line: 795, column: 16, scope: !15)
+!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 794, column: 7)
+!16 = distinct !DISubprogram(name: "operator()", linkageName: "some_special_function", scope: null, file: !1, line: 783, type: !5, isLocal: true, isDefinition: true, scopeLine: 784, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !17, variables: !2)
+!17 = !DISubprogram(name: "operator()", linkageName: "some_special_function", scope: null, file: !1, line: 783, type: !5, isLocal: false, isDefinition: false, scopeLine: 783, flags: DIFlagPrototyped, isOptimized: true)
diff --git a/test/ThinLTO/X86/Inputs/import_opaque_type.ll b/test/ThinLTO/X86/Inputs/import_opaque_type.ll
new file mode 100644
index 000000000000..fe2b2934724b
--- /dev/null
+++ b/test/ThinLTO/X86/Inputs/import_opaque_type.ll
@@ -0,0 +1,15 @@
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+%0 = type { i8 }
+
+%a = type { %0 * }
+
+define void @bar(%a *) {
+ ret void
+}
+
+define void @baz() {
+ call void @bar(%a *null)
+ ret void
+}
diff --git a/test/ThinLTO/X86/crash_debuginfo.ll b/test/ThinLTO/X86/crash_debuginfo.ll
new file mode 100644
index 000000000000..b250afab1ed6
--- /dev/null
+++ b/test/ThinLTO/X86/crash_debuginfo.ll
@@ -0,0 +1,46 @@
+; RUN: opt -module-summary -o %t-dst.bc %s
+; RUN: opt -module-summary -o %t-src.bc %p/Inputs/crash_debuginfo.ll
+; RUN: llvm-lto -thinlto -o %t-index %t-dst.bc %t-src.bc
+; RUN: opt -function-import -inline -summary-file %t-index.thinlto.bc %t-dst.bc -o %t.out
+; RUN: llvm-nm %t.out | FileCheck %s
+
+; Verify that we import bar and inline it. It use to crash importing due to ODR type uniquing
+; CHECK-NOT: bar
+; CHECK: foo
+; CHECK-NOT: bar
+
+; ModuleID = 'test/ThinLTO/X86/crash_debuginfo.ll'
+source_filename = "test/ThinLTO/X86/crash_debuginfo.ll"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.0"
+
+%some_type = type { i32 }
+
+define void @foo(i32 %arg) {
+ call void @bar(i32 %arg), !dbg !7
+ unreachable
+}
+
+declare void @bar(i32)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "Apple LLVM version 8.0.0 (clang-800.0.24.1)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2)
+!1 = !DIFile(filename: "1.cpp", directory: "/another_dir")
+!2 = !{!3}
+!3 = distinct !DIGlobalVariable(name: "_", linkageName: "some_global", scope: null, file: !1, line: 20, type: !4, isLocal: true, isDefinition: true, variable: %some_type* undef)
+!4 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "slice_nil", file: !1, line: 13, size: 64, align: 64, elements: !5, identifier: "_ZTSN5boost6python3api9slice_nilE")
+!5 = !{}
+!6 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DILocation(line: 728, column: 71, scope: !8, inlinedAt: !15)
+!8 = distinct !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !10, isLocal: false, isDefinition: true, scopeLine: 727, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !11, variables: !12)
+!9 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "some_other_class", file: !1, line: 197, size: 192, align: 64, elements: !5, templateParams: !5, identifier: "some_other_class")
+!10 = !DISubroutineType(types: !5)
+!11 = !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !10, isLocal: false, isDefinition: false, scopeLine: 726, flags: DIFlagPrototyped, isOptimized: true)
+!12 = !{!13}
+!13 = !DILocalVariable(name: "caster", scope: !8, file: !1, line: 728, type: !14)
+!14 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !8, file: !1, line: 728, size: 64, align: 64, elements: !5, identifier: "someclass")
+!15 = distinct !DILocation(line: 87, column: 9, scope: !16)
+!16 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !9, line: 73, type: !10, isLocal: false, isDefinition: true, scopeLine: 74, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !17, variables: !5)
+!17 = !DISubprogram(name: "foo", linkageName: "foo", scope: !9, file: !1, line: 83, type: !10, isLocal: false, isDefinition: false, scopeLine: 83, flags: DIFlagPrototyped, isOptimized: true)
diff --git a/test/ThinLTO/X86/import_opaque_type.ll b/test/ThinLTO/X86/import_opaque_type.ll
new file mode 100644
index 000000000000..bfa251abacab
--- /dev/null
+++ b/test/ThinLTO/X86/import_opaque_type.ll
@@ -0,0 +1,27 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/import_opaque_type.ll -o %t2.bc
+; RUN: llvm-lto -thinlto-action=thinlink -o %t3.bc %t.bc %t2.bc
+
+; Check that we import correctly the imported type to replace the opaque one here
+; RUN: llvm-lto -thinlto-action=import %t.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s
+
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+; CHECK: %0 = type { i8 }
+%0 = type opaque
+
+%a = type { %0 * }
+
+declare void @baz()
+define void @foo(%a *) {
+ call void @baz()
+ ret void
+}
+
+define i32 @main() {
+ call void @foo(%a *null)
+ ret i32 0
+}
diff --git a/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll b/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll
new file mode 100644
index 000000000000..3f8fdcc8eafb
--- /dev/null
+++ b/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll
@@ -0,0 +1,42 @@
+; RUN: opt < %s -basicaa -gvn -S | FileCheck %s
+
+declare void @llvm.masked.scatter.v2i32(<2 x i32> , <2 x i32*> , i32 , <2 x i1> )
+declare <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*>, i32, <2 x i1>, <2 x i32>)
+
+; This test ensures that masked scatter and gather operations, which take vectors of pointers,
+; do not have pointer aliasing ignored when being processed.
+; No scatter/gather calls should end up eliminated
+; CHECK: llvm.masked.gather
+; CHECK: llvm.masked.gather
+; CHECK: llvm.masked.scatter
+; CHECK: llvm.masked.gather
+; CHECK: llvm.masked.scatter
+; CHECK: llvm.masked.gather
+define spir_kernel void @test(<2 x i32*> %in1, <2 x i32*> %in2, i32* %out) {
+entry:
+ ; Just some temporary storage
+ %tmp.0 = alloca i32
+ %tmp.1 = alloca i32
+ %tmp.i = insertelement <2 x i32*> undef, i32* %tmp.0, i32 0
+ %tmp = insertelement <2 x i32*> %tmp.i, i32* %tmp.1, i32 1
+ ; Read from in1 and in2
+ %in1.v = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %in1, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1
+ %in2.v = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %in2, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1
+ ; Store in1 to the allocas
+ call void @llvm.masked.scatter.v2i32(<2 x i32> %in1.v, <2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>);
+ ; Read in1 from the allocas
+ ; This gather should alias the scatter we just saw
+ %tmp.v.0 = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1
+ ; Store in2 to the allocas
+ call void @llvm.masked.scatter.v2i32(<2 x i32> %in2.v, <2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>);
+ ; Read in2 from the allocas
+ ; This gather should alias the scatter we just saw, and not be eliminated
+ %tmp.v.1 = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1
+ ; Store in2 to out for good measure
+ %tmp.v.1.0 = extractelement <2 x i32> %tmp.v.1, i32 0
+ %tmp.v.1.1 = extractelement <2 x i32> %tmp.v.1, i32 1
+ store i32 %tmp.v.1.0, i32* %out
+ %out.1 = getelementptr i32, i32* %out, i32 1
+ store i32 %tmp.v.1.1, i32* %out.1
+ ret void
+}
diff --git a/test/Transforms/JumpThreading/pr27840.ll b/test/Transforms/JumpThreading/pr27840.ll
new file mode 100644
index 000000000000..cbee2af67fae
--- /dev/null
+++ b/test/Transforms/JumpThreading/pr27840.ll
@@ -0,0 +1,33 @@
+; RUN: opt -jump-threading -S < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+declare void @helper()
+declare i32 @__gxx_personality_v0(...)
+
+
+define void @pr27840(i8* %call, i1 %A) personality i32(...)* @__gxx_personality_v0 {
+entry:
+ invoke void @helper()
+ to label %invoke.cont unwind label %lpad
+
+; Don't jump threading; we can't split the critical edge from entry to lpad.
+; CHECK-LABEL: @pr27840
+; CHECK: invoke
+; CHECK-NEXT: to label %invoke.cont unwind label %lpad
+
+invoke.cont:
+ invoke void @helper()
+ to label %nowhere unwind label %lpad
+
+lpad:
+ %b = phi i1 [ true, %invoke.cont ], [ false, %entry ]
+ landingpad { i8*, i32 }
+ cleanup
+ %xor = xor i1 %b, %A
+ br i1 %xor, label %nowhere, label %invoke.cont
+
+nowhere:
+ unreachable
+}
diff --git a/test/Transforms/LoopVectorize/runtime-check-readonly.ll b/test/Transforms/LoopVectorize/runtime-check-readonly.ll
index a3b5a598d220..e91d5b84324d 100644
--- a/test/Transforms/LoopVectorize/runtime-check-readonly.ll
+++ b/test/Transforms/LoopVectorize/runtime-check-readonly.ll
@@ -8,10 +8,10 @@ target triple = "x86_64-apple-macosx10.8.0"
;CHECK: br
;CHECK: getelementptr
;CHECK-DAG: getelementptr
-;CHECK-DAG: icmp uge
-;CHECK-DAG: icmp uge
-;CHECK-DAG: icmp uge
-;CHECK-DAG: icmp uge
+;CHECK-DAG: icmp ugt
+;CHECK-DAG: icmp ugt
+;CHECK-DAG: icmp ugt
+;CHECK-DAG: icmp ugt
;CHECK-DAG: and
;CHECK-DAG: and
;CHECK: br
diff --git a/test/Transforms/LoopVectorize/tbaa-nodep.ll b/test/Transforms/LoopVectorize/tbaa-nodep.ll
index 06d000230027..3e79d47de08c 100644
--- a/test/Transforms/LoopVectorize/tbaa-nodep.ll
+++ b/test/Transforms/LoopVectorize/tbaa-nodep.ll
@@ -36,7 +36,7 @@ for.end: ; preds = %for.body
; CHECK: ret i32 0
; CHECK-NOTBAA-LABEL: @test1
-; CHECK-NOTBAA: icmp uge i32*
+; CHECK-NOTBAA: icmp ugt i32*
; CHECK-NOTBAA: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa
; CHECK-NOTBAA: store <4 x i32> %{{.*}}, <4 x i32>* %{{.*}}, align 4, !tbaa
@@ -70,8 +70,8 @@ for.end: ; preds = %for.body
; required. Without TBAA, however, two checks are required.
; CHECK-LABEL: @test2
-; CHECK: icmp uge float*
-; CHECK: icmp uge float*
+; CHECK: icmp ugt float*
+; CHECK: icmp ugt float*
; CHECK-NOT: icmp uge i32*
; CHECK: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa
@@ -80,10 +80,10 @@ for.end: ; preds = %for.body
; CHECK: ret i32 0
; CHECK-NOTBAA-LABEL: @test2
-; CHECK-NOTBAA: icmp uge float*
-; CHECK-NOTBAA: icmp uge float*
-; CHECK-NOTBAA-DAG: icmp uge float*
-; CHECK-NOTBAA-DAG: icmp uge i32*
+; CHECK-NOTBAA: icmp ugt float*
+; CHECK-NOTBAA: icmp ugt float*
+; CHECK-NOTBAA-DAG: icmp ugt float*
+; CHECK-NOTBAA-DAG: icmp ugt i32*
; CHECK-NOTBAA: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa
; CHECK-NOTBAA: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 4, !tbaa
diff --git a/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll b/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll
index 9eacbde7710a..022ea734cec2 100644
--- a/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll
+++ b/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll
@@ -8,15 +8,15 @@
; CHECK-NEXT: Loop Versioning found to be beneficial
;
; CHECK: for.body3:
-; CHECK-NEXT: %add86 = phi i32 [ %arrayidx7.promoted, %for.body3.ph ], [ %add8, %for.body3 ]
+; CHECK-NEXT: %[[induction:.*]] = phi i32 [ %arrayidx7.promoted, %for.body3.ph ], [ %add8, %for.body3 ]
; CHECK-NEXT: %j.113 = phi i32 [ %j.016, %for.body3.ph ], [ %inc, %for.body3 ]
; CHECK-NEXT: %idxprom = zext i32 %j.113 to i64
; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, i32* %var1, i64 %idxprom
; CHECK-NEXT: store i32 %add, i32* %arrayidx, align 4, !alias.scope !6, !noalias !6
-; CHECK-NEXT: %add8 = add nsw i32 %add86, %add
+; CHECK-NEXT: %add8 = add nsw i32 %[[induction]], %add
; CHECK-NEXT: %inc = add nuw i32 %j.113, 1
; CHECK-NEXT: %cmp2 = icmp ult i32 %inc, %itr
-; CHECK-NEXT: br i1 %cmp2, label %for.body3, label %for.inc11.loopexit.loopexit5, !llvm.loop !7
+; CHECK-NEXT: br i1 %cmp2, label %for.body3, label %for.inc11.loopexit.loopexit6, !llvm.loop !7
define i32 @foo(i32* nocapture %var1, i32* nocapture readnone %var2, i32* nocapture %var3, i32 %itr) #0 {
entry:
%cmp14 = icmp eq i32 %itr, 0