aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-08-18 08:26:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-08-18 08:26:46 +0000
commitd0a9cbdae159210824ddf2da138e2dcaecbe1cd4 (patch)
treec539e15a2dbf52df82eb2a72fb6581db604faab4
parentac3a3c134038429abacef8c5d8069674f98d6b34 (diff)
downloadsrc-d0a9cbdae159210824ddf2da138e2dcaecbe1cd4.tar.gz
src-d0a9cbdae159210824ddf2da138e2dcaecbe1cd4.zip
Vendor import of llvm release_70 branch r339999:vendor/llvm/llvm-release_70-r339999
Notes
Notes: svn path=/vendor/llvm/dist-release_70/; revision=338000 svn path=/vendor/llvm/llvm-release_70-r339999/; revision=338001; tag=vendor/llvm/llvm-release_70-r339999
-rw-r--r--cmake/modules/HandleLLVMOptions.cmake1
-rw-r--r--docs/ReleaseNotes.rst48
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp13
-rw-r--r--lib/Analysis/InstructionSimplify.cpp6
-rw-r--r--lib/Analysis/MemorySSA.cpp9
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp19
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp53
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp13
-rw-r--r--lib/Target/X86/X86FlagsCopyLowering.cpp17
-rw-r--r--lib/Transforms/Vectorize/SLPVectorizer.cpp8
-rw-r--r--test/Analysis/BasicAA/tail-byval.ll15
-rwxr-xr-xtest/BugPoint/compile-custom.ll2
-rw-r--r--test/BugPoint/unsymbolized.ll2
-rw-r--r--test/CodeGen/AMDGPU/extract-subvector-equal-length.ll30
-rw-r--r--test/CodeGen/ARM/inline-asm-operand-implicit-cast.ll122
-rw-r--r--test/CodeGen/ARM/inlineasm-operand-implicit-cast.ll307
-rw-r--r--test/CodeGen/PowerPC/pr38087.ll56
-rw-r--r--test/CodeGen/X86/flags-copy-lowering.mir6
-rw-r--r--test/CodeGen/X86/pr38533.ll65
-rw-r--r--test/CodeGen/X86/pr38539.ll314
-rw-r--r--test/Other/opt-bisect-legacy-pass-manager.ll2
-rw-r--r--test/TableGen/JSON.td2
-rw-r--r--test/ThinLTO/X86/cache.ll20
-rw-r--r--test/Transforms/DeadStoreElimination/tail-byval.ll23
-rw-r--r--test/Transforms/EarlyCSE/memoryssa.ll42
-rw-r--r--test/Transforms/SLPVectorizer/AArch64/PR38339.ll95
-rw-r--r--test/tools/gold/X86/common.ll10
-rw-r--r--test/tools/gold/X86/v1.16/wrap-1.ll4
-rw-r--r--test/tools/gold/X86/v1.16/wrap-2.ll4
-rw-r--r--test/tools/llvm-cov/showLineExecutionCounts.cpp2
-rw-r--r--test/tools/llvm-objcopy/auto-remove-shndx.test2
-rw-r--r--test/tools/llvm-objcopy/many-sections.test2
-rw-r--r--test/tools/llvm-objcopy/remove-shndx.test2
-rw-r--r--test/tools/llvm-objcopy/strict-no-add.test2
-rw-r--r--test/tools/llvm-symbolizer/pdb/pdb.test2
-rw-r--r--test/tools/llvm-symbolizer/ppc64.test2
-rw-r--r--unittests/Analysis/MemorySSA.cpp66
-rw-r--r--utils/lit/lit/Test.py11
-rw-r--r--utils/lit/lit/llvm/config.py3
-rw-r--r--utils/lit/tests/Inputs/shtest-env/lit.cfg2
-rw-r--r--utils/lit/tests/Inputs/shtest-format/external_shell/fail_with_bad_encoding.txt2
-rw-r--r--utils/lit/tests/Inputs/shtest-format/lit.cfg2
-rw-r--r--utils/lit/tests/Inputs/shtest-shell/dev-null.txt8
-rw-r--r--utils/lit/tests/Inputs/shtest-shell/lit.cfg2
-rw-r--r--utils/lit/tests/Inputs/shtest-shell/redirects.txt6
-rw-r--r--utils/lit/tests/Inputs/shtest-shell/valid-shell.txt28
-rw-r--r--utils/lit/tests/Inputs/shtest-timeout/lit.cfg2
-rw-r--r--utils/lit/tests/lit.cfg3
50 files changed, 1221 insertions, 244 deletions
diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake
index 5fd318f00917..05cf9026953a 100644
--- a/cmake/modules/HandleLLVMOptions.cmake
+++ b/cmake/modules/HandleLLVMOptions.cmake
@@ -149,6 +149,7 @@ endif()
# is unloaded.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,nodelete")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,nodelete")
endif()
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 2963a3df3a1c..7dce9e2d60dd 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -121,6 +121,16 @@ Non-comprehensive list of changes in this release
not to be compliant, and higher optimization levels will still emit some
information in v4 format.
+* Added support for the ``.rva`` assembler directive for COFF targets.
+
+* The :program:`llvm-rc` tool (Windows Resource Compiler) has been improved
+ a bit. There are still known missing features, but it is generally usable
+ in many cases. (The tool still doesn't preprocess input files automatically,
+ but it can now handle leftover C declarations in preprocessor output, if
+ given output from a preprocessor run externally.)
+
+* CodeView debug info can now be emitted MinGW configurations, if requested.
+
* Note..
.. NOTE
@@ -144,11 +154,35 @@ Changes to the LLVM IR
* invariant.group metadata can now refer only empty metadata nodes.
-Changes to the ARM Backend
---------------------------
+Changes to the AArch64 Target
+-----------------------------
- During this release ...
+* The ``.inst`` assembler directive is now usable on both COFF and Mach-O
+ targets, in addition to ELF.
+* Support for most remaining COFF relocations have been added.
+
+* Support for TLS on Windows has been added.
+
+Changes to the ARM Target
+-------------------------
+
+* The ``.inst`` assembler directive is now usable on both COFF and Mach-O
+ targets, in addition to ELF. For Thumb, it can now also automatically
+ deduce the instruction size, without having to specify it with
+ e.g. ``.inst.w`` as before.
+
+Changes to the Hexagon Target
+-----------------------------
+
+* Hexagon now supports auto-vectorization for HVX. It is disabled by default
+ and can be turned on with ``-fvectorize``. For auto-vectorization to take
+ effect, code generation for HVX needs to be enabled with ``-mhvx``.
+ The complete set of options should include ``-fvectorize``, ``-mhvx``,
+ and ``-mhvx-length={64b|128b}``.
+
+* The support for Hexagon ISA V4 is deprecated and will be removed in the
+ next release.
Changes to the MIPS Target
--------------------------
@@ -184,7 +218,13 @@ During this release the SystemZ target has:
Changes to the X86 Target
-------------------------
- During this release ...
+* The calling convention for the ``f80`` data type on MinGW targets has been
+ fixed. Normally, the calling convention for this type is handled within clang,
+ but if an intrinsic is used, which LLVM expands into a libcall, the
+ proper calling convention needs to be supported in LLVM as well. (Note,
+ on Windows, this data type is only used for long doubles in MinGW
+ environments - in MSVC environments, long doubles are the same size as
+ normal doubles.)
Changes to the AMDGPU Target
-----------------------------
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 1a24ae3dba15..f9ecbc043261 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -801,14 +801,15 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,
const Value *Object = GetUnderlyingObject(Loc.Ptr, DL);
- // If this is a tail call and Loc.Ptr points to a stack location, we know that
- // the tail call cannot access or modify the local stack.
- // We cannot exclude byval arguments here; these belong to the caller of
- // the current function not to the current function, and a tail callee
- // may reference them.
+ // Calls marked 'tail' cannot read or write allocas from the current frame
+ // because the current frame might be destroyed by the time they run. However,
+ // a tail call may use an alloca with byval. Calling with byval copies the
+ // contents of the alloca into argument registers or stack slots, so there is
+ // no lifetime issue.
if (isa<AllocaInst>(Object))
if (const CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
- if (CI->isTailCall())
+ if (CI->isTailCall() &&
+ !CI->getAttributes().hasAttrSomewhere(Attribute::ByVal))
return ModRefInfo::NoModRef;
// If the pointer is to a locally allocated object that does not escape,
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index f991291f565a..5e72798d459a 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -1338,7 +1338,7 @@ static Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const KnownBits YKnown = computeKnownBits(Y, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
const unsigned Width = Op0->getType()->getScalarSizeInBits();
const unsigned EffWidthY = Width - YKnown.countMinLeadingZeros();
- if (EffWidthY <= ShRAmt->getZExtValue())
+ if (ShRAmt->uge(EffWidthY))
return X;
}
@@ -1878,9 +1878,9 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
match(Op0, m_c_Or(m_CombineAnd(m_NUWShl(m_Value(X), m_APInt(ShAmt)),
m_Value(XShifted)),
m_Value(Y)))) {
- const unsigned ShftCnt = ShAmt->getZExtValue();
- const KnownBits YKnown = computeKnownBits(Y, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
const unsigned Width = Op0->getType()->getScalarSizeInBits();
+ const unsigned ShftCnt = ShAmt->getLimitedValue(Width);
+ const KnownBits YKnown = computeKnownBits(Y, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
const unsigned EffWidthY = Width - YKnown.countMinLeadingZeros();
if (EffWidthY <= ShftCnt) {
const KnownBits XKnown = computeKnownBits(X, Q.DL, 0, Q.AC, Q.CxtI,
diff --git a/lib/Analysis/MemorySSA.cpp b/lib/Analysis/MemorySSA.cpp
index f57d490ce96e..b38c0c4f1439 100644
--- a/lib/Analysis/MemorySSA.cpp
+++ b/lib/Analysis/MemorySSA.cpp
@@ -258,13 +258,18 @@ static ClobberAlias instructionClobbersQuery(MemoryDef *MD,
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(DefInst)) {
// These intrinsics will show up as affecting memory, but they are just
- // markers.
+ // markers, mostly.
+ //
+ // FIXME: We probably don't actually want MemorySSA to model these at all
+ // (including creating MemoryAccesses for them): we just end up inventing
+ // clobbers where they don't really exist at all. Please see D43269 for
+ // context.
switch (II->getIntrinsicID()) {
case Intrinsic::lifetime_start:
if (UseCS)
return {false, NoAlias};
AR = AA.alias(MemoryLocation(II->getArgOperand(1)), UseLoc);
- return {AR == MustAlias, AR};
+ return {AR != NoAlias, AR};
case Intrinsic::lifetime_end:
case Intrinsic::invariant_start:
case Intrinsic::invariant_end:
diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 9aa0ea15f3b7..2e6f6edbce55 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -1778,15 +1778,16 @@ SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo) {
SDValue Op = N->getOperand(0);
EVT OpVT = Op->getValueType(0);
- EVT IVT = EVT::getIntegerVT(*DAG.getContext(), OpVT.getSizeInBits());
- assert (IVT == N->getValueType(0) && "Bitcast to type of different size");
-
SDValue Promoted = GetPromotedFloat(N->getOperand(0));
EVT PromotedVT = Promoted->getValueType(0);
// Convert the promoted float value to the desired IVT.
- return DAG.getNode(GetPromotionOpcode(PromotedVT, OpVT), SDLoc(N), IVT,
- Promoted);
+ EVT IVT = EVT::getIntegerVT(*DAG.getContext(), OpVT.getSizeInBits());
+ SDValue Convert = DAG.getNode(GetPromotionOpcode(PromotedVT, OpVT), SDLoc(N),
+ IVT, Promoted);
+ // The final result type might not be an scalar so we need a bitcast. The
+ // bitcast will be further legalized if needed.
+ return DAG.getBitcast(N->getValueType(0), Convert);
}
// Promote Operand 1 of FCOPYSIGN. Operand 0 ought to be handled by
@@ -1941,8 +1942,12 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
SDValue DAGTypeLegalizer::PromoteFloatRes_BITCAST(SDNode *N) {
EVT VT = N->getValueType(0);
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
- return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT,
- N->getOperand(0));
+ // Input type isn't guaranteed to be a scalar int so bitcast if not. The
+ // bitcast will be legalized further if necessary.
+ EVT IVT = EVT::getIntegerVT(*DAG.getContext(),
+ N->getOperand(0).getValueType().getSizeInBits());
+ SDValue Cast = DAG.getBitcast(IVT, N->getOperand(0));
+ return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, Cast);
}
SDValue DAGTypeLegalizer::PromoteFloatRes_ConstantFP(SDNode *N) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 63a1ea13a5f5..133831fa76fb 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -269,8 +269,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) {
return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
case TargetLowering::TypePromoteFloat: {
// Convert the promoted float by hand.
- SDValue PromotedOp = GetPromotedFloat(InOp);
- return DAG.getNode(ISD::FP_TO_FP16, dl, NOutVT, PromotedOp);
+ if (!NOutVT.isVector())
+ return DAG.getNode(ISD::FP_TO_FP16, dl, NOutVT, GetPromotedFloat(InOp));
break;
}
case TargetLowering::TypeExpandInteger:
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 48e03c6da68f..9e38e675d13a 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2374,7 +2374,7 @@ void SelectionDAG::computeKnownBits(SDValue Op, KnownBits &Known,
if (SubIdx && SubIdx->getAPIntValue().ule(NumSrcElts - NumElts)) {
// Offset the demanded elts by the subvector index.
uint64_t Idx = SubIdx->getZExtValue();
- APInt DemandedSrc = DemandedElts.zext(NumSrcElts).shl(Idx);
+ APInt DemandedSrc = DemandedElts.zextOrSelf(NumSrcElts).shl(Idx);
computeKnownBits(Src, Known, DemandedSrc, Depth + 1);
} else {
computeKnownBits(Src, Known, Depth + 1);
@@ -3533,7 +3533,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
if (SubIdx && SubIdx->getAPIntValue().ule(NumSrcElts - NumElts)) {
// Offset the demanded elts by the subvector index.
uint64_t Idx = SubIdx->getZExtValue();
- APInt DemandedSrc = DemandedElts.zext(NumSrcElts).shl(Idx);
+ APInt DemandedSrc = DemandedElts.zextOrSelf(NumSrcElts).shl(Idx);
return ComputeNumSignBits(Src, DemandedSrc, Depth + 1);
}
return ComputeNumSignBits(Src, Depth + 1);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 5f6b6010cae2..c1c15514c09a 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7768,10 +7768,29 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
SDValue Val = RetValRegs.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(),
Chain, &Flag, CS.getInstruction());
- // FIXME: Why don't we do this for inline asms with MRVs?
- if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) {
- EVT ResultType = TLI.getValueType(DAG.getDataLayout(), CS.getType());
-
+ llvm::Type *CSResultType = CS.getType();
+ unsigned numRet;
+ ArrayRef<Type *> ResultTypes;
+ SmallVector<SDValue, 1> ResultValues(1);
+ if (CSResultType->isSingleValueType()) {
+ numRet = 1;
+ ResultValues[0] = Val;
+ ResultTypes = makeArrayRef(CSResultType);
+ } else {
+ numRet = CSResultType->getNumContainedTypes();
+ assert(Val->getNumOperands() == numRet &&
+ "Mismatch in number of output operands in asm result");
+ ResultTypes = CSResultType->subtypes();
+ ArrayRef<SDUse> ValueUses = Val->ops();
+ ResultValues.resize(numRet);
+ std::transform(ValueUses.begin(), ValueUses.end(), ResultValues.begin(),
+ [](const SDUse &u) -> SDValue { return u.get(); });
+ }
+ SmallVector<EVT, 1> ResultVTs(numRet);
+ for (unsigned i = 0; i < numRet; i++) {
+ EVT ResultVT = TLI.getValueType(DAG.getDataLayout(), ResultTypes[i]);
+ SDValue Val = ResultValues[i];
+ assert(ResultTypes[i]->isSized() && "Unexpected unsized type");
// If the type of the inline asm call site return value is different but
// has same size as the type of the asm output bitcast it. One example
// of this is for vectors with different width / number of elements.
@@ -7782,22 +7801,24 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
// This can also happen for a return value that disagrees with the
// register class it is put in, eg. a double in a general-purpose
// register on a 32-bit machine.
- if (ResultType != Val.getValueType() &&
- ResultType.getSizeInBits() == Val.getValueSizeInBits()) {
- Val = DAG.getNode(ISD::BITCAST, getCurSDLoc(),
- ResultType, Val);
-
- } else if (ResultType != Val.getValueType() &&
- ResultType.isInteger() && Val.getValueType().isInteger()) {
- // If a result value was tied to an input value, the computed result may
- // have a wider width than the expected result. Extract the relevant
- // portion.
- Val = DAG.getNode(ISD::TRUNCATE, getCurSDLoc(), ResultType, Val);
+ if (ResultVT != Val.getValueType() &&
+ ResultVT.getSizeInBits() == Val.getValueSizeInBits())
+ Val = DAG.getNode(ISD::BITCAST, getCurSDLoc(), ResultVT, Val);
+ else if (ResultVT != Val.getValueType() && ResultVT.isInteger() &&
+ Val.getValueType().isInteger()) {
+ // If a result value was tied to an input value, the computed result
+ // may have a wider width than the expected result. Extract the
+ // relevant portion.
+ Val = DAG.getNode(ISD::TRUNCATE, getCurSDLoc(), ResultVT, Val);
}
- assert(ResultType == Val.getValueType() && "Asm result value mismatch!");
+ assert(ResultVT == Val.getValueType() && "Asm result value mismatch!");
+ ResultVTs[i] = ResultVT;
+ ResultValues[i] = Val;
}
+ Val = DAG.getNode(ISD::MERGE_VALUES, getCurSDLoc(),
+ DAG.getVTList(ResultVTs), ResultValues);
setValue(CS.getInstruction(), Val);
// Don't need to use this as a chain in this case.
if (!IA->hasSideEffects() && !hasMemory && IndirectStoresToEmit.empty())
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index f6e13aee968a..331dbcbbe060 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -12007,10 +12007,15 @@ static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG) {
auto isSExtOfVecExtract = [&](SDValue Op) -> bool {
if (!Op)
return false;
- if (Op.getOpcode() != ISD::SIGN_EXTEND)
+ if (Op.getOpcode() != ISD::SIGN_EXTEND &&
+ Op.getOpcode() != ISD::SIGN_EXTEND_INREG)
return false;
+ // A SIGN_EXTEND_INREG might be fed by an ANY_EXTEND to produce a value
+ // of the right width.
SDValue Extract = Op.getOperand(0);
+ if (Extract.getOpcode() == ISD::ANY_EXTEND)
+ Extract = Extract.getOperand(0);
if (Extract.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
return false;
@@ -12098,8 +12103,10 @@ SDValue PPCTargetLowering::DAGCombineBuildVector(SDNode *N,
return Reduced;
// If we're building a vector out of extended elements from another vector
- // we have P9 vector integer extend instructions.
- if (Subtarget.hasP9Altivec()) {
+ // we have P9 vector integer extend instructions. The code assumes legal
+ // input types (i.e. it can't handle things like v4i16) so do not run before
+ // legalization.
+ if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
Reduced = combineBVOfVecSExt(N, DAG);
if (Reduced)
return Reduced;
diff --git a/lib/Target/X86/X86FlagsCopyLowering.cpp b/lib/Target/X86/X86FlagsCopyLowering.cpp
index c17c51a7aeac..d2f2f21542a9 100644
--- a/lib/Target/X86/X86FlagsCopyLowering.cpp
+++ b/lib/Target/X86/X86FlagsCopyLowering.cpp
@@ -97,6 +97,7 @@ public:
private:
MachineRegisterInfo *MRI;
+ const X86Subtarget *Subtarget;
const X86InstrInfo *TII;
const TargetRegisterInfo *TRI;
const TargetRegisterClass *PromoteRC;
@@ -346,10 +347,10 @@ bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
<< " **********\n");
- auto &Subtarget = MF.getSubtarget<X86Subtarget>();
+ Subtarget = &MF.getSubtarget<X86Subtarget>();
MRI = &MF.getRegInfo();
- TII = Subtarget.getInstrInfo();
- TRI = Subtarget.getRegisterInfo();
+ TII = Subtarget->getInstrInfo();
+ TRI = Subtarget->getRegisterInfo();
MDT = &getAnalysis<MachineDominatorTree>();
PromoteRC = &X86::GR8RegClass;
@@ -960,10 +961,14 @@ void X86FlagsCopyLoweringPass::rewriteSetCarryExtended(
.addReg(Reg)
.addImm(SubRegIdx[OrigRegSize]);
} else if (OrigRegSize > TargetRegSize) {
- BuildMI(MBB, SetPos, SetLoc, TII->get(TargetOpcode::EXTRACT_SUBREG),
+ if (TargetRegSize == 1 && !Subtarget->is64Bit()) {
+ // Need to constrain the register class.
+ MRI->constrainRegClass(Reg, &X86::GR32_ABCDRegClass);
+ }
+
+ BuildMI(MBB, SetPos, SetLoc, TII->get(TargetOpcode::COPY),
NewReg)
- .addReg(Reg)
- .addImm(SubRegIdx[TargetRegSize]);
+ .addReg(Reg, 0, SubRegIdx[TargetRegSize]);
} else {
BuildMI(MBB, SetPos, SetLoc, TII->get(TargetOpcode::COPY), NewReg)
.addReg(Reg);
diff --git a/lib/Transforms/Vectorize/SLPVectorizer.cpp b/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 5c2efe885e22..32df6d581577 100644
--- a/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -3109,14 +3109,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
}
if (NeedToShuffleReuses) {
// TODO: Merge this shuffle with the ReorderShuffleMask.
- if (!E->ReorderIndices.empty())
+ if (E->ReorderIndices.empty())
Builder.SetInsertPoint(VL0);
- else if (auto *I = dyn_cast<Instruction>(V))
- Builder.SetInsertPoint(I->getParent(),
- std::next(I->getIterator()));
- else
- Builder.SetInsertPoint(&F->getEntryBlock(),
- F->getEntryBlock().getFirstInsertionPt());
V = Builder.CreateShuffleVector(V, UndefValue::get(VecTy),
E->ReuseShuffleIndices, "shuffle");
}
diff --git a/test/Analysis/BasicAA/tail-byval.ll b/test/Analysis/BasicAA/tail-byval.ll
new file mode 100644
index 000000000000..0aa8dfdaedff
--- /dev/null
+++ b/test/Analysis/BasicAA/tail-byval.ll
@@ -0,0 +1,15 @@
+; RUN: opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
+
+declare void @takebyval(i32* byval %p)
+
+define i32 @tailbyval() {
+entry:
+ %p = alloca i32
+ store i32 42, i32* %p
+ tail call void @takebyval(i32* byval %p)
+ %rv = load i32, i32* %p
+ ret i32 %rv
+}
+; FIXME: This should be Just Ref.
+; CHECK-LABEL: Function: tailbyval: 1 pointers, 1 call sites
+; CHECK-NEXT: Both ModRef: Ptr: i32* %p <-> tail call void @takebyval(i32* byval %p)
diff --git a/test/BugPoint/compile-custom.ll b/test/BugPoint/compile-custom.ll
index 004470943746..cb82a01383e1 100755
--- a/test/BugPoint/compile-custom.ll
+++ b/test/BugPoint/compile-custom.ll
@@ -1,4 +1,4 @@
-; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext --compile-custom --compile-command="%python %/s.py arg1 arg2" --opt-command opt --output-prefix %t %s | FileCheck %s
+; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext --compile-custom --compile-command="%/s.py arg1 arg2" --opt-command opt --output-prefix %t %s | FileCheck %s
; REQUIRES: loadable_module
; Test that arguments are correctly passed in --compile-command. The output
diff --git a/test/BugPoint/unsymbolized.ll b/test/BugPoint/unsymbolized.ll
index ae47682195bb..da26b9dc4808 100644
--- a/test/BugPoint/unsymbolized.ll
+++ b/test/BugPoint/unsymbolized.ll
@@ -2,7 +2,7 @@
; RUN: echo "import sys" > %t.py
; RUN: echo "print('args = ' + str(sys.argv))" >> %t.py
; RUN: echo "exit(1)" >> %t.py
-; RUN: not bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -opt-command="%python" -opt-args %t.py | FileCheck %s
+; RUN: not bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -opt-command=%python -opt-args %t.py | FileCheck %s
; RUN: not --crash opt -load %llvmshlibdir/BugpointPasses%shlibext %s -bugpoint-crashcalls -disable-symbolication 2>&1 | FileCheck --check-prefix=CRASH %s
; RUN: not bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -opt-command=%t.non.existent.opt.binary -opt-args %t.py 2>&1 | FileCheck %s --check-prefix=BAD-OPT
diff --git a/test/CodeGen/AMDGPU/extract-subvector-equal-length.ll b/test/CodeGen/AMDGPU/extract-subvector-equal-length.ll
new file mode 100644
index 000000000000..6f7fb53f76ce
--- /dev/null
+++ b/test/CodeGen/AMDGPU/extract-subvector-equal-length.ll
@@ -0,0 +1,30 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -march=amdgcn -mtriple=amdgcn-- -verify-machineinstrs < %s | FileCheck %s
+
+; Test for ICE in SelectionDAG::computeKnownBits when visiting EXTRACT_SUBVECTOR
+; with DemandedElts already as wide as the source vector.
+
+define <3 x i32> @quux() #0 {
+; CHECK-LABEL: quux:
+; CHECK: ; %bb.0: ; %bb
+; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT: v_mov_b32_e32 v0, 0
+; CHECK-NEXT: v_mov_b32_e32 v1, 1
+; CHECK-NEXT: v_mov_b32_e32 v2, 1
+; CHECK-NEXT: s_setpc_b64 s[30:31]
+bb:
+ %tmp = shufflevector <4 x i8> <i8 1, i8 2, i8 3, i8 4>, <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
+ %tmp1 = extractelement <3 x i8> %tmp, i64 0
+ %tmp2 = zext i8 %tmp1 to i32
+ %tmp3 = insertelement <3 x i32> undef, i32 %tmp2, i32 0
+ %tmp4 = extractelement <3 x i8> %tmp, i64 1
+ %tmp5 = zext i8 %tmp4 to i32
+ %tmp6 = insertelement <3 x i32> %tmp3, i32 %tmp5, i32 1
+ %tmp7 = extractelement <3 x i8> %tmp, i64 2
+ %tmp8 = zext i8 %tmp7 to i32
+ %tmp9 = insertelement <3 x i32> %tmp6, i32 %tmp8, i32 2
+ %tmp10 = lshr <3 x i32> %tmp9, <i32 1, i32 1, i32 1>
+ ret <3 x i32> %tmp10
+}
+
+attributes #0 = { noinline optnone }
diff --git a/test/CodeGen/ARM/inline-asm-operand-implicit-cast.ll b/test/CodeGen/ARM/inline-asm-operand-implicit-cast.ll
deleted file mode 100644
index 45bdb124e032..000000000000
--- a/test/CodeGen/ARM/inline-asm-operand-implicit-cast.ll
+++ /dev/null
@@ -1,122 +0,0 @@
-; RUN: llc -mtriple armv7-arm-linux-gnueabihf -O2 -mcpu=cortex-a7 < %s | FileCheck %s
-
-; Check support for returning a float in GPR with soft float ABI
-define arm_aapcscc float @zerobits_float_soft() #0 {
-; CHECK-LABEL: zerobits_float_soft
-; CHECK: mov r0, #0
- %1 = tail call float asm "mov ${0}, #0", "=&r"()
- ret float %1
-}
-
-; Check support for returning a double in GPR with soft float ABI
-define arm_aapcscc double @zerobits_double_soft() #0 {
-; CHECK-LABEL: zerobits_double_soft
-; CHECK: mov r0, #0
-; CHECK-NEXT: mov r1, #0
- %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"()
- ret double %1
-}
-
-; Check support for returning a float in GPR with matching float input with
-; soft float ABI
-define arm_aapcscc float @flt_gpr_matching_in_op_soft(float %f) #0 {
-; CHECK-LABEL: flt_gpr_matching_in_op_soft
-; CHECK: mov r0, r0
- %1 = call float asm "mov $0, $1", "=&r,0"(float %f)
- ret float %1
-}
-
-; Check support for returning a double in GPR with matching double input with
-; soft float ABI
-define arm_aapcscc double @dbl_gpr_matching_in_op_soft(double %d) #0 {
-; CHECK-LABEL: dbl_gpr_matching_in_op_soft
-; CHECK: mov r1, r0
- %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d)
- ret double %1
-}
-
-; Check support for returning a float in specific GPR with matching float input
-; with soft float ABI
-define arm_aapcscc float @flt_gpr_matching_spec_reg_in_op_soft(float %f) #0 {
-; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_soft
-; CHECK: mov r3, r3
- %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f)
- ret float %1
-}
-
-; Check support for returning a double in specific GPR with matching double
-; input with soft float ABI
-define arm_aapcscc double @dbl_gpr_matching_spec_reg_in_op_soft(double %d) #0 {
-; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_soft
-; CHECK: mov r3, r2
- %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d)
- ret double %1
-}
-
-attributes #0 = { nounwind "target-features"="+d16,+vfp2,+vfp3,-fp-only-sp" "use-soft-float"="true" }
-
-
-; Check support for returning a float in GPR with hard float ABI
-define float @zerobits_float_hard() #1 {
-; CHECK-LABEL: zerobits_float_hard
-; CHECK: mov r0, #0
-; CHECK: vmov s0, r0
- %1 = tail call float asm "mov ${0}, #0", "=&r"()
- ret float %1
-}
-
-; Check support for returning a double in GPR with hard float ABI
-define double @zerobits_double_hard() #1 {
-; CHECK-LABEL: zerobits_double_hard
-; CHECK: mov r0, #0
-; CHECK-NEXT: mov r1, #0
-; CHECK: vmov d0, r0, r1
- %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"()
- ret double %1
-}
-
-; Check support for returning a float in GPR with matching float input with
-; hard float ABI
-define float @flt_gpr_matching_in_op_hard(float %f) #1 {
-; CHECK-LABEL: flt_gpr_matching_in_op_hard
-; CHECK: vmov r0, s0
-; CHECK: mov r0, r0
-; CHECK: vmov s0, r0
- %1 = call float asm "mov $0, $1", "=&r,0"(float %f)
- ret float %1
-}
-
-; Check support for returning a double in GPR with matching double input with
-; hard float ABI
-define double @dbl_gpr_matching_in_op_hard(double %d) #1 {
-; CHECK-LABEL: dbl_gpr_matching_in_op_hard
-; CHECK: vmov r0, r1, d0
-; CHECK: mov r1, r0
-; CHECK: vmov d0, r0, r1
- %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d)
- ret double %1
-}
-
-; Check support for returning a float in specific GPR with matching float
-; input with hard float ABI
-define float @flt_gpr_matching_spec_reg_in_op_hard(float %f) #1 {
-; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_hard
-; CHECK: vmov r3, s0
-; CHECK: mov r3, r3
-; CHECK: vmov s0, r3
- %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f)
- ret float %1
-}
-
-; Check support for returning a double in specific GPR with matching double
-; input with hard float ABI
-define double @dbl_gpr_matching_spec_reg_in_op_hard(double %d) #1 {
-; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_hard
-; CHECK: vmov r2, r3, d0
-; CHECK: mov r3, r2
-; CHECK: vmov d0, r2, r3
- %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d)
- ret double %1
-}
-
-attributes #1 = { nounwind "target-features"="+d16,+vfp2,+vfp3,-fp-only-sp" "use-soft-float"="false" }
diff --git a/test/CodeGen/ARM/inlineasm-operand-implicit-cast.ll b/test/CodeGen/ARM/inlineasm-operand-implicit-cast.ll
new file mode 100644
index 000000000000..7b98f0f0de31
--- /dev/null
+++ b/test/CodeGen/ARM/inlineasm-operand-implicit-cast.ll
@@ -0,0 +1,307 @@
+; RUN: llc -mtriple armv7-arm-linux-gnueabihf -O2 -mcpu=cortex-a7 < %s | FileCheck %s
+
+%struct.twofloat = type { float, float }
+%struct.twodouble = type { double, double }
+
+; Check support for returning a float in GPR with soft float ABI
+define arm_aapcscc float @zerobits_float_soft() #0 {
+; CHECK-LABEL: zerobits_float_soft
+; CHECK: mov r0, #0
+ %1 = tail call float asm "mov ${0}, #0", "=&r"()
+ ret float %1
+}
+
+; Check support for returning a double in GPR with soft float ABI
+define arm_aapcscc double @zerobits_double_soft() #0 {
+; CHECK-LABEL: zerobits_double_soft
+; CHECK: mov r0, #0
+; CHECK-NEXT: mov r1, #0
+ %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"()
+ ret double %1
+}
+
+; Check support for returning a float in GPR with matching float input with
+; soft float ABI
+define arm_aapcscc float @flt_gpr_matching_in_op_soft(float %f) #0 {
+; CHECK-LABEL: flt_gpr_matching_in_op_soft
+; CHECK: mov r0, r0
+ %1 = call float asm "mov $0, $1", "=&r,0"(float %f)
+ ret float %1
+}
+
+; Check support for returning a double in GPR with matching double input with
+; soft float ABI
+define arm_aapcscc double @dbl_gpr_matching_in_op_soft(double %d) #0 {
+; CHECK-LABEL: dbl_gpr_matching_in_op_soft
+; CHECK: mov r1, r0
+ %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d)
+ ret double %1
+}
+
+; Check support for returning a float in specific GPR with matching float input
+; with soft float ABI
+define arm_aapcscc float @flt_gpr_matching_spec_reg_in_op_soft(float %f) #0 {
+; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_soft
+; CHECK: mov r3, r3
+ %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f)
+ ret float %1
+}
+
+; Check support for returning a double in specific GPR with matching double
+; input with soft float ABI
+define arm_aapcscc double @dbl_gpr_matching_spec_reg_in_op_soft(double %d) #0 {
+; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_soft
+; CHECK: mov r3, r2
+ %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d)
+ ret double %1
+}
+
+; Check support for returning several float in GPR
+define arm_aapcscc float @zerobits_float_convoluted_soft() #0 {
+; CHECK-LABEL: zerobits_float_convoluted_soft
+; CHECK: mov r0, #0
+; CHECK-NEXT: mov r1, #0
+ %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"()
+ %asmresult = extractvalue { float, float } %1, 0
+ %asmresult1 = extractvalue { float, float } %1, 1
+ %add = fadd float %asmresult, %asmresult1
+ ret float %add
+}
+
+; Check support for returning several double in GPR
+define double @zerobits_double_convoluted_soft() #0 {
+; CHECK-LABEL: zerobits_double_convoluted_soft
+; CHECK: mov r0, #0
+; CHECK-NEXT: mov r1, #0
+; CHECK-NEXT: mov r2, #0
+; CHECK-NEXT: mov r3, #0
+ %1 = call { double, double } asm "mov ${0:Q}, #0; mov ${0:R}, #0; mov ${1:Q}, #0; mov ${1:R}, #0", "=r,=r"()
+ %asmresult = extractvalue { double, double } %1, 0
+ %asmresult1 = extractvalue { double, double } %1, 1
+ %add = fadd double %asmresult, %asmresult1
+ ret double %add
+}
+
+; Check support for returning several floats in GPRs with matching float inputs
+; with soft float ABI
+define arm_aapcscc float @flt_gprs_matching_in_op_soft(float %f1, float %f2) #0 {
+; CHECK-LABEL: flt_gprs_matching_in_op_soft
+; CHECK: mov r0, r0
+; CHECK-NEXT: mov r1, r1
+ %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&r,=&r,0,1"(float %f1, float %f2)
+ %asmresult1 = extractvalue { float, float } %1, 0
+ %asmresult2 = extractvalue { float, float } %1, 1
+ %add = fadd float %asmresult1, %asmresult2
+ ret float %add
+}
+
+; Check support for returning several double in GPRs with matching double input
+; with soft float ABI
+define arm_aapcscc double @dbl_gprs_matching_in_op_soft(double %d1, double %d2) #0 {
+; CHECK-LABEL: dbl_gprs_matching_in_op_soft
+; CHECK: mov r1, r0
+; CHECK-NEXT: mov r3, r2
+ %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&r,=&r,0,1"(double %d1, double %d2)
+ %asmresult1 = extractvalue { double, double } %1, 0
+ %asmresult2 = extractvalue { double, double } %1, 1
+ %add = fadd double %asmresult1, %asmresult2
+ ret double %add
+}
+
+; Check support for returning several float in specific GPRs with matching
+; float input with soft float ABI
+define arm_aapcscc float @flt_gprs_matching_spec_reg_in_op_soft(float %f1, float %f2) #0 {
+; CHECK-LABEL: flt_gprs_matching_spec_reg_in_op_soft
+; CHECK: mov r3, r3
+; CHECK-NEXT: mov r4, r4
+ %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&{r3},=&{r4},0,1"(float %f1, float %f2)
+ %asmresult1 = extractvalue { float, float } %1, 0
+ %asmresult2 = extractvalue { float, float } %1, 1
+ %add = fadd float %asmresult1, %asmresult2
+ ret float %add
+}
+
+; Check support for returning several double in specific GPRs with matching
+; double input with soft float ABI
+define arm_aapcscc double @dbl_gprs_matching_spec_reg_in_op_soft(double %d1, double %d2) #0 {
+; CHECK-LABEL: dbl_gprs_matching_spec_reg_in_op_soft
+; CHECK: mov r3, r2
+; CHECK-NEXT: mov r5, r4
+ %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&{r2},=&{r4},0,1"(double %d1, double %d2)
+ %asmresult1 = extractvalue { double, double } %1, 0
+ %asmresult2 = extractvalue { double, double } %1, 1
+ %add = fadd double %asmresult1, %asmresult2
+ ret double %add
+}
+
+attributes #0 = { nounwind "target-features"="+d16,+vfp2,+vfp3,-fp-only-sp" "use-soft-float"="true" }
+
+
+; Check support for returning a float in GPR with hard float ABI
+define float @zerobits_float_hard() #1 {
+; CHECK-LABEL: zerobits_float_hard
+; CHECK: mov r0, #0
+; CHECK: vmov s0, r0
+ %1 = tail call float asm "mov ${0}, #0", "=&r"()
+ ret float %1
+}
+
+; Check support for returning a double in GPR with hard float ABI
+define double @zerobits_double_hard() #1 {
+; CHECK-LABEL: zerobits_double_hard
+; CHECK: mov r0, #0
+; CHECK-NEXT: mov r1, #0
+; CHECK: vmov d0, r0, r1
+ %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"()
+ ret double %1
+}
+
+; Check support for returning a float in GPR with matching float input with
+; hard float ABI
+define float @flt_gpr_matching_in_op_hard(float %f) #1 {
+; CHECK-LABEL: flt_gpr_matching_in_op_hard
+; CHECK: vmov r0, s0
+; CHECK: mov r0, r0
+; CHECK: vmov s0, r0
+ %1 = call float asm "mov $0, $1", "=&r,0"(float %f)
+ ret float %1
+}
+
+; Check support for returning a double in GPR with matching double input with
+; hard float ABI
+define double @dbl_gpr_matching_in_op_hard(double %d) #1 {
+; CHECK-LABEL: dbl_gpr_matching_in_op_hard
+; CHECK: vmov r0, r1, d0
+; CHECK: mov r1, r0
+; CHECK: vmov d0, r0, r1
+ %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d)
+ ret double %1
+}
+
+; Check support for returning a float in specific GPR with matching float
+; input with hard float ABI
+define float @flt_gpr_matching_spec_reg_in_op_hard(float %f) #1 {
+; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_hard
+; CHECK: vmov r3, s0
+; CHECK: mov r3, r3
+; CHECK: vmov s0, r3
+ %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f)
+ ret float %1
+}
+
+; Check support for returning a double in specific GPR with matching double
+; input with hard float ABI
+define double @dbl_gpr_matching_spec_reg_in_op_hard(double %d) #1 {
+; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_hard
+; CHECK: vmov r2, r3, d0
+; CHECK: mov r3, r2
+; CHECK: vmov d0, r2, r3
+ %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d)
+ ret double %1
+}
+
+; Check support for returning several float in GPR
+define %struct.twofloat @zerobits_float_convoluted_hard() #1 {
+; CHECK-LABEL: zerobits_float_convoluted_hard
+; CHECK: mov r0, #0
+; CHECK-NEXT: mov r1, #0
+; CHECK: vmov s0, r0
+; CHECK-NEXT: vmov s1, r1
+ %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"()
+ %asmresult1 = extractvalue { float, float } %1, 0
+ %asmresult2 = extractvalue { float, float } %1, 1
+ %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0
+ %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1
+ ret %struct.twofloat %res
+}
+
+; Check support for returning several double in GPR
+define %struct.twodouble @zerobits_double_convoluted_hard() #1 {
+; CHECK-LABEL: zerobits_double_convoluted_hard
+; CHECK: mov r0, #0
+; CHECK-NEXT: mov r1, #0
+; CHECK-NEXT: mov r2, #0
+; CHECK-NEXT: mov r3, #0
+; CHECK: vmov d0, r0, r1
+; CHECK-NEXT: vmov d1, r2, r3
+ %1 = call { double, double } asm "mov ${0:Q}, #0; mov ${0:R}, #0; mov ${1:Q}, #0; mov ${1:R}, #0", "=r,=r"()
+ %asmresult1 = extractvalue { double, double } %1, 0
+ %asmresult2 = extractvalue { double, double } %1, 1
+ %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0
+ %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1
+ ret %struct.twodouble %res
+}
+
+; Check support for returning several floats in GPRs with matching float inputs
+; with hard float ABI
+define %struct.twofloat @flt_gprs_matching_in_op_hard(float %f1, float %f2) #1 {
+; CHECK-LABEL: flt_gprs_matching_in_op_hard
+; CHECK: vmov r0, s0
+; CHECK-NEXT: vmov r1, s1
+; CHECK: mov r0, r0
+; CHECK-NEXT: mov r1, r1
+; CHECK: vmov s0, r0
+; CHECK-NEXT: vmov s1, r1
+ %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&r,=&r,0,1"(float %f1, float %f2)
+ %asmresult1 = extractvalue { float, float } %1, 0
+ %asmresult2 = extractvalue { float, float } %1, 1
+ %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0
+ %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1
+ ret %struct.twofloat %res
+}
+
+; Check support for returning several double in GPRs with matching double input
+; with hard float ABI
+define %struct.twodouble @dbl_gprs_matching_in_op_hard(double %d1, double %d2) #1 {
+; CHECK-LABEL: dbl_gprs_matching_in_op_hard
+; CHECK: vmov r0, r1, d0
+; CHECK-NEXT: vmov r2, r3, d1
+; CHECK: mov r1, r0
+; CHECK-NEXT: mov r3, r2
+; CHECK: vmov d0, r0, r1
+; CHECK-NEXT: vmov d1, r2, r3
+ %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&r,=&r,0,1"(double %d1, double %d2)
+ %asmresult1 = extractvalue { double, double } %1, 0
+ %asmresult2 = extractvalue { double, double } %1, 1
+ %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0
+ %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1
+ ret %struct.twodouble %res
+}
+
+; Check support for returning several float in specific GPRs with matching
+; float input with hard float ABI
+define %struct.twofloat @flt_gprs_matching_spec_reg_in_op_hard(float %f1, float %f2) #1 {
+; CHECK-LABEL: flt_gprs_matching_spec_reg_in_op_hard
+; CHECK: vmov r3, s0
+; CHECK-NEXT: vmov r4, s1
+; CHECK: mov r3, r3
+; CHECK-NEXT: mov r4, r4
+; CHECK: vmov s0, r3
+; CHECK-NEXT: vmov s1, r4
+ %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&{r3},=&{r4},0,1"(float %f1, float %f2)
+ %asmresult1 = extractvalue { float, float } %1, 0
+ %asmresult2 = extractvalue { float, float } %1, 1
+ %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0
+ %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1
+ ret %struct.twofloat %res
+}
+
+; Check support for returning several double in specific GPRs with matching
+; double input with hard float ABI
+define %struct.twodouble @dbl_gprs_matching_spec_reg_in_op_hard(double %d1, double %d2) #1 {
+; CHECK-LABEL: dbl_gprs_matching_spec_reg_in_op_hard
+; CHECK: vmov r2, r3, d0
+; CHECK-NEXT: vmov r4, r5, d1
+; CHECK: mov r3, r2
+; CHECK-NEXT: mov r5, r4
+; CHECK: vmov d0, r2, r3
+; CHECK-NEXT: vmov d1, r4, r5
+ %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&{r2},=&{r4},0,1"(double %d1, double %d2)
+ %asmresult1 = extractvalue { double, double } %1, 0
+ %asmresult2 = extractvalue { double, double } %1, 1
+ %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0
+ %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1
+ ret %struct.twodouble %res
+}
+
+attributes #1 = { nounwind "target-features"="+d16,+vfp2,+vfp3,-fp-only-sp" "use-soft-float"="false" }
diff --git a/test/CodeGen/PowerPC/pr38087.ll b/test/CodeGen/PowerPC/pr38087.ll
new file mode 100644
index 000000000000..af8704f7d708
--- /dev/null
+++ b/test/CodeGen/PowerPC/pr38087.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -ppc-vsr-nums-as-vr \
+; RUN: -mtriple=powerpc64le-unknown-unknown -ppc-asm-full-reg-names < %s | \
+; RUN: FileCheck %s
+; Function Attrs: nounwind readnone speculatable
+declare <4 x float> @llvm.fmuladd.v4f32(<4 x float>, <4 x float>, <4 x float>) #0
+
+; Function Attrs: nounwind readnone speculatable
+declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #0
+
+define void @draw_llvm_vs_variant0() {
+; CHECK-LABEL: draw_llvm_vs_variant0:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: ldx r3, 0, r3
+; CHECK-NEXT: mtvsrd f0, r3
+; CHECK-NEXT: xxswapd v2, vs0
+; CHECK-NEXT: vmrglh v2, v2, v2
+; CHECK-NEXT: vextsh2w v2, v2
+; CHECK-NEXT: xvcvsxwsp vs0, v2
+; CHECK-NEXT: xxspltw vs0, vs0, 2
+; CHECK-NEXT: xvmaddasp vs0, vs0, vs0
+; CHECK-NEXT: stxvx vs0, 0, r3
+; CHECK-NEXT: blr
+entry:
+ %.size = load i32, i32* undef
+ %0 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %.size, i32 7)
+ %1 = extractvalue { i32, i1 } %0, 0
+ %2 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %1, i32 0)
+ %3 = extractvalue { i32, i1 } %2, 0
+ %4 = select i1 false, i32 0, i32 %3
+ %5 = xor i1 false, true
+ %6 = sext i1 %5 to i32
+ %7 = load <4 x i16>, <4 x i16>* undef, align 2
+ %8 = extractelement <4 x i16> %7, i32 0
+ %9 = sext i16 %8 to i32
+ %10 = insertelement <4 x i32> undef, i32 %9, i32 0
+ %11 = extractelement <4 x i16> %7, i32 1
+ %12 = sext i16 %11 to i32
+ %13 = insertelement <4 x i32> %10, i32 %12, i32 1
+ %14 = extractelement <4 x i16> %7, i32 2
+ %15 = sext i16 %14 to i32
+ %16 = insertelement <4 x i32> %13, i32 %15, i32 2
+ %17 = extractelement <4 x i16> %7, i32 3
+ %18 = sext i16 %17 to i32
+ %19 = insertelement <4 x i32> %16, i32 %18, i32 3
+ %20 = sitofp <4 x i32> %19 to <4 x float>
+ %21 = insertelement <4 x i32> undef, i32 %6, i32 0
+ %22 = shufflevector <4 x i32> %21, <4 x i32> undef, <4 x i32> zeroinitializer
+ %23 = bitcast <4 x float> %20 to <4 x i32>
+ %24 = and <4 x i32> %23, %22
+ %25 = bitcast <4 x i32> %24 to <4 x float>
+ %26 = shufflevector <4 x float> %25, <4 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ %27 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> undef, <4 x float> undef, <4 x float> %26)
+ store <4 x float> %27, <4 x float>* undef
+ ret void
+}
diff --git a/test/CodeGen/X86/flags-copy-lowering.mir b/test/CodeGen/X86/flags-copy-lowering.mir
index d5991754d40b..98d6f21dc486 100644
--- a/test/CodeGen/X86/flags-copy-lowering.mir
+++ b/test/CodeGen/X86/flags-copy-lowering.mir
@@ -545,7 +545,7 @@ body: |
MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4
; CHECK-NOT: $eflags =
; CHECK: %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
- ; CHECK-NEXT: %[[ZERO_SUBREG:[^:]*]]:gr8 = EXTRACT_SUBREG %[[ZERO]], %subreg.sub_8bit
+ ; CHECK-NEXT: %[[ZERO_SUBREG:[^:]*]]:gr8 = COPY %[[ZERO]].sub_8bit
; CHECK-NEXT: %[[REPLACEMENT:[^:]*]]:gr8 = SUB8rr %[[ZERO_SUBREG]], %[[CF_REG]]
; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
@@ -554,9 +554,9 @@ body: |
MOV16mr $rsp, 1, $noreg, -16, $noreg, killed %5
; CHECK-NOT: $eflags =
; CHECK: %[[CF_EXT:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
- ; CHECK-NEXT: %[[CF_TRUNC:[^:]*]]:gr16 = EXTRACT_SUBREG %[[CF_EXT]], %subreg.sub_16bit
+ ; CHECK-NEXT: %[[CF_TRUNC:[^:]*]]:gr16 = COPY %[[CF_EXT]].sub_16bit
; CHECK-NEXT: %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
- ; CHECK-NEXT: %[[ZERO_SUBREG:[^:]*]]:gr16 = EXTRACT_SUBREG %[[ZERO]], %subreg.sub_16bit
+ ; CHECK-NEXT: %[[ZERO_SUBREG:[^:]*]]:gr16 = COPY %[[ZERO]].sub_16bit
; CHECK-NEXT: %[[REPLACEMENT:[^:]*]]:gr16 = SUB16rr %[[ZERO_SUBREG]], %[[CF_TRUNC]]
; CHECK-NEXT: MOV16mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
diff --git a/test/CodeGen/X86/pr38533.ll b/test/CodeGen/X86/pr38533.ll
new file mode 100644
index 000000000000..96d003ba1a84
--- /dev/null
+++ b/test/CodeGen/X86/pr38533.ll
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefixes=CHECK,SSE
+; RUN: llc < %s -mtriple=x86_64-unknown -mattr=avx512f | FileCheck %s --check-prefixes=CHECK,AVX512
+
+; This test makes sure that a vector that needs to be promoted that is bitcasted to fp16 is legalized correctly without causing a width mismatch.
+define void @constant_fold_vector_to_half() {
+; CHECK-LABEL: constant_fold_vector_to_half:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movw $16384, (%rax) # imm = 0x4000
+; CHECK-NEXT: retq
+ store volatile half bitcast (<4 x i4> <i4 0, i4 0, i4 0, i4 4> to half), half* undef
+ ret void
+}
+
+; Similarly this makes sure that the opposite bitcast of the above is also legalized without crashing.
+define void @pr38533_2(half %x) {
+; SSE-LABEL: pr38533_2:
+; SSE: # %bb.0:
+; SSE-NEXT: pushq %rax
+; SSE-NEXT: .cfi_def_cfa_offset 16
+; SSE-NEXT: callq __gnu_f2h_ieee
+; SSE-NEXT: movw %ax, {{[0-9]+}}(%rsp)
+; SSE-NEXT: movzwl {{[0-9]+}}(%rsp), %eax
+; SSE-NEXT: movw %ax, (%rax)
+; SSE-NEXT: popq %rax
+; SSE-NEXT: .cfi_def_cfa_offset 8
+; SSE-NEXT: retq
+;
+; AVX512-LABEL: pr38533_2:
+; AVX512: # %bb.0:
+; AVX512-NEXT: vcvtps2ph $4, %xmm0, %xmm0
+; AVX512-NEXT: vmovd %xmm0, %eax
+; AVX512-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
+; AVX512-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
+; AVX512-NEXT: movw %ax, (%rax)
+; AVX512-NEXT: retq
+ %a = bitcast half %x to <4 x i4>
+ store volatile <4 x i4> %a, <4 x i4>* undef
+ ret void
+}
+
+; This case is a bitcast from fp16 to a 16-bit wide legal vector type. In this case the result type is legal when the bitcast gets type legalized.
+define void @pr38533_3(half %x) {
+; SSE-LABEL: pr38533_3:
+; SSE: # %bb.0:
+; SSE-NEXT: pushq %rax
+; SSE-NEXT: .cfi_def_cfa_offset 16
+; SSE-NEXT: callq __gnu_f2h_ieee
+; SSE-NEXT: movw %ax, (%rsp)
+; SSE-NEXT: movzwl (%rsp), %eax
+; SSE-NEXT: movw %ax, (%rax)
+; SSE-NEXT: popq %rax
+; SSE-NEXT: .cfi_def_cfa_offset 8
+; SSE-NEXT: retq
+;
+; AVX512-LABEL: pr38533_3:
+; AVX512: # %bb.0:
+; AVX512-NEXT: vcvtps2ph $4, %xmm0, %xmm0
+; AVX512-NEXT: vmovd %xmm0, %eax
+; AVX512-NEXT: movw %ax, (%rax)
+; AVX512-NEXT: retq
+ %a = bitcast half %x to <16 x i1>
+ store volatile <16 x i1> %a, <16 x i1>* undef
+ ret void
+}
diff --git a/test/CodeGen/X86/pr38539.ll b/test/CodeGen/X86/pr38539.ll
new file mode 100644
index 000000000000..7a871a9f1177
--- /dev/null
+++ b/test/CodeGen/X86/pr38539.ll
@@ -0,0 +1,314 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=X86
+
+; This test is targeted at 64-bit mode. It used to crash due to the creation of an EXTRACT_SUBREG after the peephole pass had ran.
+define void @f() {
+; X64-LABEL: f:
+; X64: # %bb.0: # %BB
+; X64-NEXT: pushq %rbp
+; X64-NEXT: .cfi_def_cfa_offset 16
+; X64-NEXT: pushq %r14
+; X64-NEXT: .cfi_def_cfa_offset 24
+; X64-NEXT: pushq %rbx
+; X64-NEXT: .cfi_def_cfa_offset 32
+; X64-NEXT: subq $16, %rsp
+; X64-NEXT: .cfi_def_cfa_offset 48
+; X64-NEXT: .cfi_offset %rbx, -32
+; X64-NEXT: .cfi_offset %r14, -24
+; X64-NEXT: .cfi_offset %rbp, -16
+; X64-NEXT: movzbl {{[0-9]+}}(%rsp), %ebx
+; X64-NEXT: movq %rbx, %rcx
+; X64-NEXT: shlq $62, %rcx
+; X64-NEXT: sarq $62, %rcx
+; X64-NEXT: movq (%rsp), %r14
+; X64-NEXT: movb (%rax), %bpl
+; X64-NEXT: xorl %edi, %edi
+; X64-NEXT: xorl %esi, %esi
+; X64-NEXT: movq %r14, %rdx
+; X64-NEXT: callq __modti3
+; X64-NEXT: andl $3, %edx
+; X64-NEXT: cmpq %rax, %r14
+; X64-NEXT: sbbq %rdx, %rbx
+; X64-NEXT: setb %sil
+; X64-NEXT: setae %bl
+; X64-NEXT: testb %al, %al
+; X64-NEXT: setne %dl
+; X64-NEXT: setne (%rax)
+; X64-NEXT: movzbl %bpl, %eax
+; X64-NEXT: xorl %ecx, %ecx
+; X64-NEXT: subb %sil, %cl
+; X64-NEXT: # kill: def $eax killed $eax def $ax
+; X64-NEXT: divb %al
+; X64-NEXT: negb %bl
+; X64-NEXT: cmpb %al, %al
+; X64-NEXT: setle %al
+; X64-NEXT: negb %al
+; X64-NEXT: cbtw
+; X64-NEXT: idivb %bl
+; X64-NEXT: movsbl %ah, %eax
+; X64-NEXT: movzbl %al, %eax
+; X64-NEXT: andl $1, %eax
+; X64-NEXT: shlq $4, %rax
+; X64-NEXT: negq %rax
+; X64-NEXT: negb %dl
+; X64-NEXT: leaq -16(%rsp,%rax), %rax
+; X64-NEXT: movq %rax, (%rax)
+; X64-NEXT: movl %ecx, %eax
+; X64-NEXT: cbtw
+; X64-NEXT: idivb %dl
+; X64-NEXT: movsbl %ah, %eax
+; X64-NEXT: andb $1, %al
+; X64-NEXT: movb %al, (%rax)
+; X64-NEXT: addq $16, %rsp
+; X64-NEXT: .cfi_def_cfa_offset 32
+; X64-NEXT: popq %rbx
+; X64-NEXT: .cfi_def_cfa_offset 24
+; X64-NEXT: popq %r14
+; X64-NEXT: .cfi_def_cfa_offset 16
+; X64-NEXT: popq %rbp
+; X64-NEXT: .cfi_def_cfa_offset 8
+; X64-NEXT: retq
+;
+; X86-LABEL: f:
+; X86: # %bb.0: # %BB
+; X86-NEXT: pushl %ebp
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %ebp, -8
+; X86-NEXT: movl %esp, %ebp
+; X86-NEXT: .cfi_def_cfa_register %ebp
+; X86-NEXT: pushl %ebx
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl %esi
+; X86-NEXT: andl $-8, %esp
+; X86-NEXT: subl $48, %esp
+; X86-NEXT: .cfi_offset %esi, -20
+; X86-NEXT: .cfi_offset %edi, -16
+; X86-NEXT: .cfi_offset %ebx, -12
+; X86-NEXT: movzbl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: shll $30, %eax
+; X86-NEXT: movl %eax, %ecx
+; X86-NEXT: sarl $30, %ecx
+; X86-NEXT: sarl $31, %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
+; X86-NEXT: movb (%eax), %dl
+; X86-NEXT: movb %dl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
+; X86-NEXT: leal {{[0-9]+}}(%esp), %edx
+; X86-NEXT: pushl %eax
+; X86-NEXT: pushl %ecx
+; X86-NEXT: pushl %ebx
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl $0
+; X86-NEXT: pushl $0
+; X86-NEXT: pushl $0
+; X86-NEXT: pushl $0
+; X86-NEXT: pushl %edx
+; X86-NEXT: calll __modti3
+; X86-NEXT: addl $32, %esp
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: andl $3, %eax
+; X86-NEXT: xorl %ecx, %ecx
+; X86-NEXT: cmpl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ebx
+; X86-NEXT: sbbl %eax, %esi
+; X86-NEXT: sbbl $0, %ecx
+; X86-NEXT: setae %dl
+; X86-NEXT: sbbb %cl, %cl
+; X86-NEXT: testb %al, %al
+; X86-NEXT: setne %ch
+; X86-NEXT: setne (%eax)
+; X86-NEXT: movb {{[-0-9]+}}(%e{{[sb]}}p), %dh # 1-byte Reload
+; X86-NEXT: movzbl %dh, %eax
+; X86-NEXT: # kill: def $eax killed $eax def $ax
+; X86-NEXT: divb %dh
+; X86-NEXT: negb %ch
+; X86-NEXT: negb %dl
+; X86-NEXT: cmpb %al, %al
+; X86-NEXT: setle %al
+; X86-NEXT: negb %al
+; X86-NEXT: cbtw
+; X86-NEXT: idivb %dl
+; X86-NEXT: movsbl %ah, %eax
+; X86-NEXT: movzbl %al, %eax
+; X86-NEXT: andl $1, %eax
+; X86-NEXT: negl %eax
+; X86-NEXT: leal (%eax,%eax,2), %eax
+; X86-NEXT: leal -4(%esp,%eax,4), %eax
+; X86-NEXT: movl %eax, (%eax)
+; X86-NEXT: movl %ecx, %eax
+; X86-NEXT: cbtw
+; X86-NEXT: idivb %ch
+; X86-NEXT: movsbl %ah, %eax
+; X86-NEXT: andb $1, %al
+; X86-NEXT: movb %al, (%eax)
+; X86-NEXT: leal -12(%ebp), %esp
+; X86-NEXT: popl %esi
+; X86-NEXT: popl %edi
+; X86-NEXT: popl %ebx
+; X86-NEXT: popl %ebp
+; X86-NEXT: .cfi_def_cfa %esp, 4
+; X86-NEXT: retl
+BB:
+ %A30 = alloca i66
+ %L17 = load i66, i66* %A30
+ %B20 = and i66 %L17, -1
+ %G2 = getelementptr i66, i66* %A30, i1 true
+ %L10 = load i8, i8* undef
+ %B6 = udiv i8 %L10, %L10
+ %C15 = icmp eq i8 undef, 0
+ %B8 = srem i66 0, %B20
+ %C2 = icmp ule i66 %B8, %B20
+ %B5 = or i8 0, %B6
+ %C19 = icmp uge i1 false, %C2
+ %C1 = icmp sle i8 undef, %B5
+ %B37 = srem i1 %C1, %C2
+ %C7 = icmp uge i1 false, %C15
+ store i1 %C7, i1* undef
+ %G6 = getelementptr i66, i66* %G2, i1 %B37
+ store i66* %G6, i66** undef
+ %B30 = srem i1 %C19, %C7
+ store i1 %B30, i1* undef
+ ret void
+}
+
+; Similar to above, but bitwidth adjusted to target 32-bit mode. This also shows that we didn't constrain the register class when extracting a subreg.
+define void @g() {
+; X64-LABEL: g:
+; X64: # %bb.0: # %BB
+; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax
+; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %esi
+; X64-NEXT: shlq $32, %rsi
+; X64-NEXT: orq %rax, %rsi
+; X64-NEXT: movq %rsi, %rdi
+; X64-NEXT: shlq $30, %rdi
+; X64-NEXT: sarq $30, %rdi
+; X64-NEXT: movb (%rax), %al
+; X64-NEXT: movzbl %al, %eax
+; X64-NEXT: # kill: def $eax killed $eax def $ax
+; X64-NEXT: divb %al
+; X64-NEXT: movl %eax, %r8d
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: xorl %edx, %edx
+; X64-NEXT: idivq %rdi
+; X64-NEXT: movabsq $17179869183, %rax # imm = 0x3FFFFFFFF
+; X64-NEXT: andq %rdx, %rax
+; X64-NEXT: testb %al, %al
+; X64-NEXT: setne %dil
+; X64-NEXT: setne (%rax)
+; X64-NEXT: cmpq %rsi, %rax
+; X64-NEXT: seta %dl
+; X64-NEXT: setbe %cl
+; X64-NEXT: negb %cl
+; X64-NEXT: cmpb %r8b, %al
+; X64-NEXT: setle %al
+; X64-NEXT: negb %al
+; X64-NEXT: cbtw
+; X64-NEXT: idivb %cl
+; X64-NEXT: movsbl %ah, %eax
+; X64-NEXT: movzbl %al, %eax
+; X64-NEXT: andl $1, %eax
+; X64-NEXT: shlq $3, %rax
+; X64-NEXT: negq %rax
+; X64-NEXT: negb %dil
+; X64-NEXT: negb %dl
+; X64-NEXT: leaq -16(%rsp,%rax), %rax
+; X64-NEXT: movq %rax, (%rax)
+; X64-NEXT: movl %edx, %eax
+; X64-NEXT: cbtw
+; X64-NEXT: idivb %dil
+; X64-NEXT: movsbl %ah, %eax
+; X64-NEXT: andb $1, %al
+; X64-NEXT: movb %al, (%rax)
+; X64-NEXT: retq
+;
+; X86-LABEL: g:
+; X86: # %bb.0: # %BB
+; X86-NEXT: pushl %ebp
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %ebp, -8
+; X86-NEXT: movl %esp, %ebp
+; X86-NEXT: .cfi_def_cfa_register %ebp
+; X86-NEXT: pushl %ebx
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl %esi
+; X86-NEXT: andl $-8, %esp
+; X86-NEXT: subl $16, %esp
+; X86-NEXT: .cfi_offset %esi, -20
+; X86-NEXT: .cfi_offset %edi, -16
+; X86-NEXT: .cfi_offset %ebx, -12
+; X86-NEXT: movzbl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: shll $30, %eax
+; X86-NEXT: sarl $30, %eax
+; X86-NEXT: movl (%esp), %edi
+; X86-NEXT: movb (%eax), %bl
+; X86-NEXT: pushl %eax
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl $0
+; X86-NEXT: pushl $0
+; X86-NEXT: calll __moddi3
+; X86-NEXT: addl $16, %esp
+; X86-NEXT: andl $3, %edx
+; X86-NEXT: cmpl %eax, %edi
+; X86-NEXT: sbbl %edx, %esi
+; X86-NEXT: setb %dl
+; X86-NEXT: setae %dh
+; X86-NEXT: testb %al, %al
+; X86-NEXT: setne %bh
+; X86-NEXT: setne (%eax)
+; X86-NEXT: movzbl %bl, %eax
+; X86-NEXT: xorl %ecx, %ecx
+; X86-NEXT: subb %dl, %cl
+; X86-NEXT: # kill: def $eax killed $eax def $ax
+; X86-NEXT: divb %bl
+; X86-NEXT: negb %dh
+; X86-NEXT: cmpb %al, %al
+; X86-NEXT: setle %al
+; X86-NEXT: negb %al
+; X86-NEXT: cbtw
+; X86-NEXT: idivb %dh
+; X86-NEXT: movsbl %ah, %eax
+; X86-NEXT: movzbl %al, %eax
+; X86-NEXT: andl $1, %eax
+; X86-NEXT: shll $3, %eax
+; X86-NEXT: negl %eax
+; X86-NEXT: negb %bh
+; X86-NEXT: leal -8(%esp,%eax), %eax
+; X86-NEXT: movl %eax, (%eax)
+; X86-NEXT: movl %ecx, %eax
+; X86-NEXT: cbtw
+; X86-NEXT: idivb %bh
+; X86-NEXT: movsbl %ah, %eax
+; X86-NEXT: andb $1, %al
+; X86-NEXT: movb %al, (%eax)
+; X86-NEXT: leal -12(%ebp), %esp
+; X86-NEXT: popl %esi
+; X86-NEXT: popl %edi
+; X86-NEXT: popl %ebx
+; X86-NEXT: popl %ebp
+; X86-NEXT: .cfi_def_cfa %esp, 4
+; X86-NEXT: retl
+BB:
+ %A30 = alloca i34
+ %L17 = load i34, i34* %A30
+ %B20 = and i34 %L17, -1
+ %G2 = getelementptr i34, i34* %A30, i1 true
+ %L10 = load i8, i8* undef
+ %B6 = udiv i8 %L10, %L10
+ %C15 = icmp eq i8 undef, 0
+ %B8 = srem i34 0, %B20
+ %C2 = icmp ule i34 %B8, %B20
+ %B5 = or i8 0, %B6
+ %C19 = icmp uge i1 false, %C2
+ %C1 = icmp sle i8 undef, %B5
+ %B37 = srem i1 %C1, %C2
+ %C7 = icmp uge i1 false, %C15
+ store i1 %C7, i1* undef
+ %G6 = getelementptr i34, i34* %G2, i1 %B37
+ store i34* %G6, i34** undef
+ %B30 = srem i1 %C19, %C7
+ store i1 %B30, i1* undef
+ ret void
+}
diff --git a/test/Other/opt-bisect-legacy-pass-manager.ll b/test/Other/opt-bisect-legacy-pass-manager.ll
index 560675e893c5..bf89e80d4960 100644
--- a/test/Other/opt-bisect-legacy-pass-manager.ll
+++ b/test/Other/opt-bisect-legacy-pass-manager.ll
@@ -38,7 +38,7 @@
; utils/bisect) to locate the optimization that inlines the call to
; f2() in f3().
-; RUN: '%python' %S/opt-bisect-helper.py --start=0 --end=256 --optcmd=opt \
+; RUN: %python %S/opt-bisect-helper.py --start=0 --end=256 --optcmd=opt \
; RUN: --filecheckcmd=FileCheck --test=%s \
; RUN: --prefix=CHECK-BISECT-INLINE-HELPER \
; RUN: | FileCheck %s --check-prefix=CHECK-BISECT-INLINE-RESULT
diff --git a/test/TableGen/JSON.td b/test/TableGen/JSON.td
index a53215579f2a..968c2577fa99 100644
--- a/test/TableGen/JSON.td
+++ b/test/TableGen/JSON.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen -dump-json %s | '%python' %S/JSON-check.py %s
+// RUN: llvm-tblgen -dump-json %s | %python %S/JSON-check.py %s
// CHECK: data['!tablegen_json_version'] == 1
diff --git a/test/ThinLTO/X86/cache.ll b/test/ThinLTO/X86/cache.ll
index bcd4f09e3ae6..cce584ec8b5d 100644
--- a/test/ThinLTO/X86/cache.ll
+++ b/test/ThinLTO/X86/cache.ll
@@ -106,11 +106,11 @@
; RUN: rm -Rf %t.cache && mkdir %t.cache
; Create cache files with different sizes.
; Only 8B, 16B and 76B files should stay after pruning.
-; RUN: "%python" -c "with open(r'%t.cache/llvmcache-foo-1024', 'w') as file: file.truncate(1024)"
-; RUN: "%python" -c "with open(r'%t.cache/llvmcache-foo-16', 'w') as file: file.truncate(16)"
-; RUN: "%python" -c "with open(r'%t.cache/llvmcache-foo-8', 'w') as file: file.truncate(8)"
-; RUN: "%python" -c "with open(r'%t.cache/llvmcache-foo-76', 'w') as file: file.truncate(76)"
-; RUN: "%python" -c "with open(r'%t.cache/llvmcache-foo-77', 'w') as file: file.truncate(77)"
+; RUN: %python -c "with open(r'%t.cache/llvmcache-foo-1024', 'w') as file: file.truncate(1024)"
+; RUN: %python -c "with open(r'%t.cache/llvmcache-foo-16', 'w') as file: file.truncate(16)"
+; RUN: %python -c "with open(r'%t.cache/llvmcache-foo-8', 'w') as file: file.truncate(8)"
+; RUN: %python -c "with open(r'%t.cache/llvmcache-foo-76', 'w') as file: file.truncate(76)"
+; RUN: %python -c "with open(r'%t.cache/llvmcache-foo-77', 'w') as file: file.truncate(77)"
; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache --thinlto-cache-max-size-bytes 100
; RUN: ls %t.cache/llvmcache-foo-16
; RUN: ls %t.cache/llvmcache-foo-8
@@ -123,11 +123,11 @@
; RUN: rm -Rf %t.cache && mkdir %t.cache
; Create cache files with different sizes.
; Only 8B and 16B files should stay after pruning.
-; RUN: "%python" -c "print(' ' * 1023)" > %t.cache/llvmcache-foo-1024
-; RUN: "%python" -c "print(' ' * 15)" > %t.cache/llvmcache-foo-16
-; RUN: "%python" -c "print(' ' * 7)" > %t.cache/llvmcache-foo-8
-; RUN: "%python" -c "print(' ' * 75)" > %t.cache/llvmcache-foo-76
-; RUN: "%python" -c "print(' ' * 76)" > %t.cache/llvmcache-foo-77
+; RUN: %python -c "print(' ' * 1023)" > %t.cache/llvmcache-foo-1024
+; RUN: %python -c "print(' ' * 15)" > %t.cache/llvmcache-foo-16
+; RUN: %python -c "print(' ' * 7)" > %t.cache/llvmcache-foo-8
+; RUN: %python -c "print(' ' * 75)" > %t.cache/llvmcache-foo-76
+; RUN: %python -c "print(' ' * 76)" > %t.cache/llvmcache-foo-77
; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache --thinlto-cache-max-size-files 2
; RUN: ls %t.cache/llvmcache-foo-16
; RUN: ls %t.cache/llvmcache-foo-8
diff --git a/test/Transforms/DeadStoreElimination/tail-byval.ll b/test/Transforms/DeadStoreElimination/tail-byval.ll
new file mode 100644
index 000000000000..ed2fbd434a75
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/tail-byval.ll
@@ -0,0 +1,23 @@
+; RUN: opt -dse -S < %s | FileCheck %s
+
+; Don't eliminate stores to allocas before tail calls to functions that use
+; byval. It's correct to mark calls like these as 'tail'. To implement this tail
+; call, the backend should copy the bytes from the alloca into the argument area
+; before clearing the stack.
+
+target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-unknown-linux-gnu"
+
+declare void @g(i32* byval %p)
+
+define void @f(i32* byval %x) {
+entry:
+ %p = alloca i32
+ %v = load i32, i32* %x
+ store i32 %v, i32* %p
+ tail call void @g(i32* byval %p)
+ ret void
+}
+; CHECK-LABEL: define void @f(i32* byval %x)
+; CHECK: store i32 %v, i32* %p
+; CHECK: tail call void @g(i32* byval %p)
diff --git a/test/Transforms/EarlyCSE/memoryssa.ll b/test/Transforms/EarlyCSE/memoryssa.ll
index 1c10efe22937..41e8d488ab4d 100644
--- a/test/Transforms/EarlyCSE/memoryssa.ll
+++ b/test/Transforms/EarlyCSE/memoryssa.ll
@@ -106,3 +106,45 @@ end:
store i32 %v2, i32* @G3
ret void
}
+
+;; Check that we respect lifetime.start/lifetime.end intrinsics when deleting
+;; stores that, without the lifetime calls, would be writebacks.
+; CHECK-LABEL: @test_writeback_lifetimes(
+; CHECK-NOMEMSSA-LABEL: @test_writeback_lifetimes(
+define void @test_writeback_lifetimes(i32* %p) {
+entry:
+ %q = getelementptr i32, i32* %p, i64 1
+ %pv = load i32, i32* %p
+ %qv = load i32, i32* %q
+ call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
+ call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
+ ; CHECK: store i32 %pv
+ ; CHECK-NOMEMSSA-LABEL: store i32 %pv
+ store i32 %pv, i32* %p
+ ; CHECK: store i32 %qv, i32* %q
+ ; CHECK-NOMEMSSA-LABEL: store i32 %qv, i32* %q
+ store i32 %qv, i32* %q
+ ret void
+}
+
+;; Check that we respect lifetime.start/lifetime.end intrinsics when deleting
+;; stores that, without the lifetime calls, would be writebacks.
+; CHECK-LABEL: @test_writeback_lifetimes_multi_arg(
+; CHECK-NOMEMSSA-LABEL: @test_writeback_lifetimes_multi_arg(
+define void @test_writeback_lifetimes_multi_arg(i32* %p, i32* %q) {
+entry:
+ %pv = load i32, i32* %p
+ %qv = load i32, i32* %q
+ call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
+ call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
+ ; CHECK: store i32 %pv
+ ; CHECK-NOMEMSSA-LABEL: store i32 %pv
+ store i32 %pv, i32* %p
+ ; CHECK: store i32 %qv, i32* %q
+ ; CHECK-NOMEMSSA-LABEL: store i32 %qv, i32* %q
+ store i32 %qv, i32* %q
+ ret void
+}
+
+declare void @llvm.lifetime.end.p0i8(i64, i32*)
+declare void @llvm.lifetime.start.p0i8(i64, i32*)
diff --git a/test/Transforms/SLPVectorizer/AArch64/PR38339.ll b/test/Transforms/SLPVectorizer/AArch64/PR38339.ll
index 1ab4a13260ed..1a981a32804b 100644
--- a/test/Transforms/SLPVectorizer/AArch64/PR38339.ll
+++ b/test/Transforms/SLPVectorizer/AArch64/PR38339.ll
@@ -27,3 +27,98 @@ define void @f1(<2 x i16> %x, i16* %a) {
store i16 %t2, i16* %ptr3
ret void
}
+
+define void @f2(<2 x i16> %x, i16* %a) {
+; CHECK-LABEL: @f2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[CONT:%.*]]
+; CHECK: cont:
+; CHECK-NEXT: [[XX:%.*]] = phi <2 x i16> [ [[X:%.*]], [[ENTRY:%.*]] ], [ undef, [[CONT]] ]
+; CHECK-NEXT: [[AA:%.*]] = phi i16* [ [[A:%.*]], [[ENTRY]] ], [ undef, [[CONT]] ]
+; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x i16> [[XX]], <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 0>
+; CHECK-NEXT: [[PTR0:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 0
+; CHECK-NEXT: [[PTR1:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 1
+; CHECK-NEXT: [[PTR2:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 2
+; CHECK-NEXT: [[PTR3:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 3
+; CHECK-NEXT: [[TMP0:%.*]] = extractelement <4 x i16> [[SHUFFLE]], i32 0
+; CHECK-NEXT: store i16 [[TMP0]], i16* [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast i16* [[PTR0]] to <4 x i16>*
+; CHECK-NEXT: store <4 x i16> [[SHUFFLE]], <4 x i16>* [[TMP1]], align 2
+; CHECK-NEXT: [[A_VAL:%.*]] = load i16, i16* [[A]], align 2
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[A_VAL]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[CONT]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %cont
+
+cont: ; preds = %entry, %cont
+ %xx = phi <2 x i16> [ %x, %entry ], [ undef, %cont ]
+ %aa = phi i16* [ %a, %entry ], [ undef, %cont ]
+ %t2 = extractelement <2 x i16> %xx, i32 0
+ %t3 = extractelement <2 x i16> %xx, i32 1
+ %ptr0 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 0
+ %ptr1 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 1
+ %ptr2 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 2
+ %ptr3 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 3
+ store i16 %t2, i16* %a
+ store i16 %t2, i16* %ptr0
+ store i16 %t3, i16* %ptr1
+ store i16 %t3, i16* %ptr2
+ store i16 %t2, i16* %ptr3
+ %a_val = load i16, i16* %a, align 2
+ %cmp = icmp eq i16 %a_val, 0
+ br i1 %cmp, label %cont, label %exit
+
+exit: ; preds = %cont
+ ret void
+}
+
+define void @f3(<2 x i16> %x, i16* %a) {
+; CHECK-LABEL: @f3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[CONT:%.*]]
+; CHECK: cont:
+; CHECK-NEXT: [[XX:%.*]] = phi <2 x i16> [ [[X:%.*]], [[ENTRY:%.*]] ], [ undef, [[CONT]] ]
+; CHECK-NEXT: [[AA:%.*]] = phi i16* [ [[A:%.*]], [[ENTRY]] ], [ undef, [[CONT]] ]
+; CHECK-NEXT: [[REORDER_SHUFFLE:%.*]] = shufflevector <2 x i16> [[XX]], <2 x i16> undef, <2 x i32> <i32 1, i32 0>
+; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x i16> [[REORDER_SHUFFLE]], <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 0>
+; CHECK-NEXT: [[PTR0:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 0
+; CHECK-NEXT: [[PTR1:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 1
+; CHECK-NEXT: [[PTR2:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 2
+; CHECK-NEXT: [[PTR3:%.*]] = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 3
+; CHECK-NEXT: [[TMP0:%.*]] = extractelement <4 x i16> [[SHUFFLE]], i32 0
+; CHECK-NEXT: store i16 [[TMP0]], i16* [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast i16* [[PTR0]] to <4 x i16>*
+; CHECK-NEXT: store <4 x i16> [[SHUFFLE]], <4 x i16>* [[TMP1]], align 2
+; CHECK-NEXT: [[A_VAL:%.*]] = load i16, i16* [[A]], align 2
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[A_VAL]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[CONT]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %cont
+
+cont: ; preds = %entry, %cont
+ %xx = phi <2 x i16> [ %x, %entry ], [ undef, %cont ]
+ %aa = phi i16* [ %a, %entry ], [ undef, %cont ]
+ %t2 = extractelement <2 x i16> %xx, i32 0
+ %t3 = extractelement <2 x i16> %xx, i32 1
+ %ptr0 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 0
+ %ptr1 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 1
+ %ptr2 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 2
+ %ptr3 = getelementptr inbounds [4 x i16], [4 x i16]* undef, i16 0, i16 3
+ store i16 %t3, i16* %a
+ store i16 %t3, i16* %ptr0
+ store i16 %t2, i16* %ptr1
+ store i16 %t2, i16* %ptr2
+ store i16 %t3, i16* %ptr3
+ %a_val = load i16, i16* %a, align 2
+ %cmp = icmp eq i16 %a_val, 0
+ br i1 %cmp, label %cont, label %exit
+
+exit: ; preds = %cont
+ ret void
+}
diff --git a/test/tools/gold/X86/common.ll b/test/tools/gold/X86/common.ll
index 1debe7875474..d8b4e031f9db 100644
--- a/test/tools/gold/X86/common.ll
+++ b/test/tools/gold/X86/common.ll
@@ -8,7 +8,7 @@ target triple = "x86_64-unknown-linux-gnu"
@a = common global i16 0, align 8
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
; RUN: --plugin-opt=emit-llvm \
; RUN: -shared %t1.o %t2.o -o %t3.o
; RUN: llvm-dis %t3.o -o - | FileCheck %s --check-prefix=A
@@ -16,7 +16,7 @@ target triple = "x86_64-unknown-linux-gnu"
; Shared library case, we merge @a as common and keep it for the symbol table.
; A: @a = common global [4 x i8] zeroinitializer, align 8
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
; RUN: --plugin-opt=emit-llvm \
; RUN: -shared %t1.o %t2b.o -o %t3.o
; RUN: llvm-dis %t3.o -o - | FileCheck %s --check-prefix=B
@@ -24,7 +24,7 @@ target triple = "x86_64-unknown-linux-gnu"
; (i16 align 8) + (i8 align 16) = i16 align 16
; B: @a = common global i16 0, align 16
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
; RUN: --plugin-opt=emit-llvm \
; RUN: -shared %t1.o %t2c.o -o %t3.o
; RUN: llvm-dis %t3.o -o - | FileCheck %s --check-prefix=C
@@ -32,7 +32,7 @@ target triple = "x86_64-unknown-linux-gnu"
; (i16 align 8) + (i8 align 1) = i16 align 8.
; C: @a = common global i16 0, align 8
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
; RUN: --plugin-opt=emit-llvm \
; RUN: %t1.o %t2.o -o %t3.o
; RUN: llvm-dis %t3.o -o - | FileCheck --check-prefix=EXEC %s
@@ -41,7 +41,7 @@ target triple = "x86_64-unknown-linux-gnu"
; EXEC: @a = internal global [4 x i8] zeroinitializer, align 8
; RUN: llc %p/Inputs/common.ll -o %t2native.o -filetype=obj
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \
; RUN: --plugin-opt=emit-llvm \
; RUN: %t1.o %t2native.o -o %t3.o
; RUN: llvm-dis %t3.o -o - | FileCheck --check-prefix=MIXED %s
diff --git a/test/tools/gold/X86/v1.16/wrap-1.ll b/test/tools/gold/X86/v1.16/wrap-1.ll
index 5ea83b007dfe..806442e49976 100644
--- a/test/tools/gold/X86/v1.16/wrap-1.ll
+++ b/test/tools/gold/X86/v1.16/wrap-1.ll
@@ -1,12 +1,12 @@
; LTO
; RUN: llvm-as %s -o %t.o
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext %t.o -o %t.out -wrap=bar -plugin-opt=save-temps
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext %t.o -o %t.out -wrap=bar -plugin-opt=save-temps
; RUN: llvm-readobj -t %t.out | FileCheck %s
; RUN: cat %t.out.resolution.txt | FileCheck -check-prefix=RESOLS %s
; ThinLTO
; RUN: opt -module-summary %s -o %t.o
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext %t.o -o %t.out -wrap=bar -plugin-opt=save-temps
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext %t.o -o %t.out -wrap=bar -plugin-opt=save-temps
; RUN: llvm-readobj -t %t.out | FileCheck %s
; RUN: cat %t.out.resolution.txt | FileCheck -check-prefix=RESOLS %s
diff --git a/test/tools/gold/X86/v1.16/wrap-2.ll b/test/tools/gold/X86/v1.16/wrap-2.ll
index 7c1d95d5be32..f36456c17ad0 100644
--- a/test/tools/gold/X86/v1.16/wrap-2.ll
+++ b/test/tools/gold/X86/v1.16/wrap-2.ll
@@ -7,14 +7,14 @@
; LTO defsym handling, gold will need a fix (not the gold plugin).
; RUN-TODO: llvm-as %s -o %t.o
; RUN-TODO: llvm-as %S/Inputs/wrap-bar.ll -o %t1.o
-; RUN-TODO: %gold -plugin %llvmshlibdir/LLVMgold%shlibext %t.o %t1.o -shared -o %t.so -wrap=bar
+; RUN-TODO: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext %t.o %t1.o -shared -o %t.so -wrap=bar
; RUN-TODO: llvm-objdump -d %t.so | FileCheck %s
; RUN-TODO: llvm-readobj -t %t.so | FileCheck -check-prefix=BIND %s
; ThinLTO
; RUN: opt -module-summary %s -o %t.o
; RUN: opt -module-summary %S/Inputs/wrap-bar.ll -o %t1.o
-; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext %t.o %t1.o -shared -o %t.so -wrap=bar
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext %t.o %t1.o -shared -o %t.so -wrap=bar
; RUN: llvm-objdump -d %t.so | FileCheck %s -check-prefix=THIN
; RUN: llvm-readobj -t %t.so | FileCheck -check-prefix=BIND %s
diff --git a/test/tools/llvm-cov/showLineExecutionCounts.cpp b/test/tools/llvm-cov/showLineExecutionCounts.cpp
index c7e373eb8756..7fc36a7a911e 100644
--- a/test/tools/llvm-cov/showLineExecutionCounts.cpp
+++ b/test/tools/llvm-cov/showLineExecutionCounts.cpp
@@ -37,7 +37,7 @@ int main() { // TEXT: [[@LINE]]| 161|int main(
//
// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -name=main 2>/dev/null > %t.export.json
// RUN: FileCheck -input-file %t.export.json %S/Inputs/lineExecutionCounts.json
-// RUN: cat %t.export.json | "%python" -c "import json, sys; json.loads(sys.stdin.read())"
+// RUN: cat %t.export.json | %python -c "import json, sys; json.loads(sys.stdin.read())"
//
// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json
// RUN: not grep '"name":"main"' %t.export-summary.json
diff --git a/test/tools/llvm-objcopy/auto-remove-shndx.test b/test/tools/llvm-objcopy/auto-remove-shndx.test
index 349d35a6dc90..5452f34d96de 100644
--- a/test/tools/llvm-objcopy/auto-remove-shndx.test
+++ b/test/tools/llvm-objcopy/auto-remove-shndx.test
@@ -1,4 +1,4 @@
-# RUN: '%python' %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+# RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
# RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2
# RUN: llvm-readobj -sections %t2 | FileCheck --check-prefix=SECS %s
diff --git a/test/tools/llvm-objcopy/many-sections.test b/test/tools/llvm-objcopy/many-sections.test
index b514fbe6bf40..7aaa3a7fe7f2 100644
--- a/test/tools/llvm-objcopy/many-sections.test
+++ b/test/tools/llvm-objcopy/many-sections.test
@@ -1,4 +1,4 @@
-RUN: '%python' %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
RUN: llvm-objcopy %t %t2
RUN: llvm-readobj -file-headers %t2 | FileCheck --check-prefix=EHDR %s
RUN: llvm-readobj -sections %t2 | FileCheck --check-prefix=SECS %s
diff --git a/test/tools/llvm-objcopy/remove-shndx.test b/test/tools/llvm-objcopy/remove-shndx.test
index 77f4622cd5a0..b8ea94cbc1da 100644
--- a/test/tools/llvm-objcopy/remove-shndx.test
+++ b/test/tools/llvm-objcopy/remove-shndx.test
@@ -1,6 +1,6 @@
# This test checks to see that a .symtab_shndx section is added to any binary
# that needs it, even if the original was removed.
-RUN: '%python' %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
RUN: llvm-objcopy -R .symtab_shndx %t %t2
RUN: llvm-readobj -sections %t2 | FileCheck %s
diff --git a/test/tools/llvm-objcopy/strict-no-add.test b/test/tools/llvm-objcopy/strict-no-add.test
index 00d5dc112200..15f5251db343 100644
--- a/test/tools/llvm-objcopy/strict-no-add.test
+++ b/test/tools/llvm-objcopy/strict-no-add.test
@@ -1,7 +1,7 @@
# This test makes sure that sections added at the end that don't have symbols
# defined in them don't trigger the creation of a large index table.
-RUN: '%python' %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
+RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
RUN: cat %p/Inputs/alloc-symtab.o > %t
RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2
RUN: llvm-objcopy -add-section=.s0=%t -add-section=.s1=%t -add-section=.s2=%t %t2 %t2
diff --git a/test/tools/llvm-symbolizer/pdb/pdb.test b/test/tools/llvm-symbolizer/pdb/pdb.test
index 29be9f132399..a97b35eab9c4 100644
--- a/test/tools/llvm-symbolizer/pdb/pdb.test
+++ b/test/tools/llvm-symbolizer/pdb/pdb.test
@@ -9,7 +9,7 @@ Subtract ImageBase from all the offsets and run the test again with
--relative-address.
RUN: grep '^ADDR:' %s | sed -s 's/ADDR: //' \
-RUN: | "%python" -c 'import sys;print("\n".join([hex(int(x, 16) - 0x400000) for x in sys.stdin]))' \
+RUN: | %python -c 'import sys;print("\n".join([hex(int(x, 16) - 0x400000) for x in sys.stdin]))' \
RUN: | llvm-symbolizer -obj="%p/Inputs/test.exe" -demangle=false --relative-address \
RUN: | FileCheck %s --check-prefix=CHECK-NO-DEMANGLE
diff --git a/test/tools/llvm-symbolizer/ppc64.test b/test/tools/llvm-symbolizer/ppc64.test
index 34ebad88b585..fc8e4ffc7e2e 100644
--- a/test/tools/llvm-symbolizer/ppc64.test
+++ b/test/tools/llvm-symbolizer/ppc64.test
@@ -4,7 +4,7 @@ int foo() { return 0; }
int bar() { return foo(); }
int _start() { return bar(); }
-RUN: "%python" -c "print('0x1000014c\n0x1000018c\n0x100001cc')" | llvm-symbolizer -obj=%p/Inputs/ppc64 | FileCheck %s
+RUN: %python -c "print('0x1000014c\n0x1000018c\n0x100001cc')" | llvm-symbolizer -obj=%p/Inputs/ppc64 | FileCheck %s
CHECK: foo
CHECK: bar
diff --git a/unittests/Analysis/MemorySSA.cpp b/unittests/Analysis/MemorySSA.cpp
index 1a1675faca16..0eb543b5477e 100644
--- a/unittests/Analysis/MemorySSA.cpp
+++ b/unittests/Analysis/MemorySSA.cpp
@@ -1199,3 +1199,69 @@ TEST_F(MemorySSATest, TestStoreMayAlias) {
++I;
}
}
+
+TEST_F(MemorySSATest, LifetimeMarkersAreClobbers) {
+ // Example code:
+ // define void @a(i8* %foo) {
+ // %bar = getelementptr i8, i8* %foo, i64 1
+ // store i8 0, i8* %foo
+ // store i8 0, i8* %bar
+ // call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
+ // call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
+ // store i8 0, i8* %foo
+ // store i8 0, i8* %bar
+ // ret void
+ // }
+ //
+ // Patterns like this are possible after inlining; the stores to %foo and %bar
+ // should both be clobbered by the lifetime.start call if they're dominated by
+ // it.
+
+ IRBuilder<> B(C);
+ F = Function::Create(
+ FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+
+ // Make blocks
+ BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
+
+ B.SetInsertPoint(Entry);
+ Value *Foo = &*F->arg_begin();
+
+ Value *Bar = B.CreateGEP(Foo, B.getInt64(1), "bar");
+
+ B.CreateStore(B.getInt8(0), Foo);
+ B.CreateStore(B.getInt8(0), Bar);
+
+ auto GetLifetimeIntrinsic = [&](Intrinsic::ID ID) {
+ return Intrinsic::getDeclaration(&M, ID, {Foo->getType()});
+ };
+
+ B.CreateCall(GetLifetimeIntrinsic(Intrinsic::lifetime_end),
+ {B.getInt64(2), Foo});
+ Instruction *LifetimeStart = B.CreateCall(
+ GetLifetimeIntrinsic(Intrinsic::lifetime_start), {B.getInt64(2), Foo});
+
+ Instruction *FooStore = B.CreateStore(B.getInt8(0), Foo);
+ Instruction *BarStore = B.CreateStore(B.getInt8(0), Bar);
+
+ setupAnalyses();
+ MemorySSA &MSSA = *Analyses->MSSA;
+
+ MemoryAccess *LifetimeStartAccess = MSSA.getMemoryAccess(LifetimeStart);
+ ASSERT_NE(LifetimeStartAccess, nullptr);
+
+ MemoryAccess *FooAccess = MSSA.getMemoryAccess(FooStore);
+ ASSERT_NE(FooAccess, nullptr);
+
+ MemoryAccess *BarAccess = MSSA.getMemoryAccess(BarStore);
+ ASSERT_NE(BarAccess, nullptr);
+
+ MemoryAccess *FooClobber =
+ MSSA.getWalker()->getClobberingMemoryAccess(FooAccess);
+ EXPECT_EQ(FooClobber, LifetimeStartAccess);
+
+ MemoryAccess *BarClobber =
+ MSSA.getWalker()->getClobberingMemoryAccess(BarAccess);
+ EXPECT_EQ(BarClobber, LifetimeStartAccess);
+}
diff --git a/utils/lit/lit/Test.py b/utils/lit/lit/Test.py
index 9fa9064dc689..a10419f33fa1 100644
--- a/utils/lit/lit/Test.py
+++ b/utils/lit/lit/Test.py
@@ -378,10 +378,15 @@ class Test:
fil.write(testcase_xml)
if self.result.code.isFailure:
fil.write(">\n\t<failure ><![CDATA[")
- if type(self.result.output) == unicode:
- encoded_output = self.result.output.encode("utf-8", 'ignore')
- else:
+ # In Python2, 'str' and 'unicode' are distinct types, but in Python3, the type 'unicode' does not exist
+ # and instead 'bytes' is distinct
+ # in Python3, there's no unicode
+ if isinstance(self.result.output, str):
encoded_output = self.result.output
+ elif isinstance(self.result.output, bytes):
+ encoded_output = self.result.output.decode("utf-8", 'ignore')
+ else:
+ encoded_output = self.result.output.encode("utf-8", 'ignore')
# In the unlikely case that the output contains the CDATA terminator
# we wrap it by creating a new CDATA block
fil.write(encoded_output.replace("]]>", "]]]]><![CDATA[>"))
diff --git a/utils/lit/lit/llvm/config.py b/utils/lit/lit/llvm/config.py
index 2257fb6db679..74c5f27c2790 100644
--- a/utils/lit/lit/llvm/config.py
+++ b/utils/lit/lit/llvm/config.py
@@ -299,7 +299,8 @@ class LLVMConfig(object):
'count'), verbatim=True, unresolved='fatal'),
ToolSubst(r'\| \bnot\b', command=FindTool('not'), verbatim=True, unresolved='fatal')]
- self.config.substitutions.append(('%python', sys.executable))
+ self.config.substitutions.append(('%python', '"%s"' % (sys.executable)))
+
self.add_tool_substitutions(
tool_patterns, [self.config.llvm_tools_dir])
diff --git a/utils/lit/tests/Inputs/shtest-env/lit.cfg b/utils/lit/tests/Inputs/shtest-env/lit.cfg
index 23ef60a4b21e..1e2d050754a7 100644
--- a/utils/lit/tests/Inputs/shtest-env/lit.cfg
+++ b/utils/lit/tests/Inputs/shtest-env/lit.cfg
@@ -6,4 +6,4 @@ config.test_source_root = None
config.test_exec_root = None
config.environment['FOO'] = '1'
config.environment['BAR'] = '2'
-config.substitutions.append(('%{python}', sys.executable))
+config.substitutions.append(('%{python}', '"%s"' % (sys.executable)))
diff --git a/utils/lit/tests/Inputs/shtest-format/external_shell/fail_with_bad_encoding.txt b/utils/lit/tests/Inputs/shtest-format/external_shell/fail_with_bad_encoding.txt
index ce38831e32ed..7fbc7087a1a0 100644
--- a/utils/lit/tests/Inputs/shtest-format/external_shell/fail_with_bad_encoding.txt
+++ b/utils/lit/tests/Inputs/shtest-format/external_shell/fail_with_bad_encoding.txt
@@ -1,5 +1,5 @@
# Run a command that fails with error on stdout.
#
-# RUN: "%{python}" %S/write-bad-encoding.py
+# RUN: %{python} %S/write-bad-encoding.py
# RUN: false
diff --git a/utils/lit/tests/Inputs/shtest-format/lit.cfg b/utils/lit/tests/Inputs/shtest-format/lit.cfg
index 0d6488848b4f..607538e901a2 100644
--- a/utils/lit/tests/Inputs/shtest-format/lit.cfg
+++ b/utils/lit/tests/Inputs/shtest-format/lit.cfg
@@ -6,4 +6,4 @@ config.test_source_root = None
config.test_exec_root = None
config.target_triple = 'x86_64-unknown-unknown'
config.available_features.add('a-present-feature')
-config.substitutions.append(('%{python}', sys.executable))
+config.substitutions.append(('%{python}', "'%s'" % (sys.executable)))
diff --git a/utils/lit/tests/Inputs/shtest-shell/dev-null.txt b/utils/lit/tests/Inputs/shtest-shell/dev-null.txt
index 5b742489cc80..1561657085d4 100644
--- a/utils/lit/tests/Inputs/shtest-shell/dev-null.txt
+++ b/utils/lit/tests/Inputs/shtest-shell/dev-null.txt
@@ -1,14 +1,14 @@
# Check handling of /dev/null in command line options
# On windows, it should be redirected to a temp file.
#
-# RUN: "%{python}" %S/check_args.py --my_arg /dev/null | FileCheck %s --check-prefix=CHECK1
+# RUN: %{python} %S/check_args.py --my_arg /dev/null | FileCheck %s --check-prefix=CHECK1
# CHECK1: OK
-# RUN: "%{python}" %S/check_args.py --my_arg=/dev/null | FileCheck %s --check-prefix=CHECK2
+# RUN: %{python} %S/check_args.py --my_arg=/dev/null | FileCheck %s --check-prefix=CHECK2
# CHECK2: OK
-# RUN: "%{python}" %S/check_args.py -a /dev/null | FileCheck %s --check-prefix=CHECK3
+# RUN: %{python} %S/check_args.py -a /dev/null | FileCheck %s --check-prefix=CHECK3
# CHECK3: OK
-# RUN: "%{python}" %S/check_args.py -a=/dev/null | FileCheck %s --check-prefix=CHECK4
+# RUN: %{python} %S/check_args.py -a=/dev/null | FileCheck %s --check-prefix=CHECK4
# CHECK4: OK
diff --git a/utils/lit/tests/Inputs/shtest-shell/lit.cfg b/utils/lit/tests/Inputs/shtest-shell/lit.cfg
index 761dc6748855..3231dedc7146 100644
--- a/utils/lit/tests/Inputs/shtest-shell/lit.cfg
+++ b/utils/lit/tests/Inputs/shtest-shell/lit.cfg
@@ -4,4 +4,4 @@ config.suffixes = ['.txt']
config.test_format = lit.formats.ShTest()
config.test_source_root = None
config.test_exec_root = None
-config.substitutions.append(('%{python}', sys.executable))
+config.substitutions.append(('%{python}', '"%s"' % (sys.executable)))
diff --git a/utils/lit/tests/Inputs/shtest-shell/redirects.txt b/utils/lit/tests/Inputs/shtest-shell/redirects.txt
index f90c2b7868b7..992ac9eb30aa 100644
--- a/utils/lit/tests/Inputs/shtest-shell/redirects.txt
+++ b/utils/lit/tests/Inputs/shtest-shell/redirects.txt
@@ -17,13 +17,13 @@
# Check stderr redirect (2> and 2>>).
#
# RUN: echo "not-present" > %t.stderr-write
-# RUN: "%{python}" %S/write-to-stderr.py 2> %t.stderr-write
+# RUN: %{python} %S/write-to-stderr.py 2> %t.stderr-write
# RUN: FileCheck --check-prefix=STDERR-WRITE < %t.stderr-write %s
#
# STDERR-WRITE-NOT: not-present
# STDERR-WRITE: a line on stderr
#
-# RUN: "%{python}" %S/write-to-stderr.py 2>> %t.stderr-write
+# RUN: %{python} %S/write-to-stderr.py 2>> %t.stderr-write
# RUN: FileCheck --check-prefix=STDERR-APPEND < %t.stderr-write %s
#
# STDERR-APPEND: a line on stderr
@@ -33,7 +33,7 @@
# Check combined redirect (&>).
#
# RUN: echo "not-present" > %t.combined
-# RUN: "%{python}" %S/write-to-stdout-and-stderr.py &> %t.combined
+# RUN: %{python} %S/write-to-stdout-and-stderr.py &> %t.combined
# RUN: FileCheck --check-prefix=COMBINED-WRITE < %t.combined %s
#
# COMBINED-WRITE-NOT: not-present
diff --git a/utils/lit/tests/Inputs/shtest-shell/valid-shell.txt b/utils/lit/tests/Inputs/shtest-shell/valid-shell.txt
index 6cc83e839cfb..7267b9b9ef5a 100644
--- a/utils/lit/tests/Inputs/shtest-shell/valid-shell.txt
+++ b/utils/lit/tests/Inputs/shtest-shell/valid-shell.txt
@@ -2,13 +2,13 @@
# Check force remove commands success whether the file does or doesn't exist.
#
# RUN: rm -f %t.write
-# RUN: "%{python}" %S/check_path.py file %t.write > %t.out
+# RUN: %{python} %S/check_path.py file %t.write > %t.out
# RUN: FileCheck --check-prefix=REMOVE-FILE < %t.out %s
# RUN: echo "create a temp file" > %t.write
-# RUN: "%{python}" %S/check_path.py file %t.write > %t.out
+# RUN: %{python} %S/check_path.py file %t.write > %t.out
# RUN: FileCheck --check-prefix=FILE-EXIST < %t.out %s
# RUN: rm -f %t.write
-# RUN: "%{python}" %S/check_path.py file %t.write > %t.out
+# RUN: %{python} %S/check_path.py file %t.write > %t.out
# RUN: FileCheck --check-prefix=REMOVE-FILE < %t.out %s
#
# REMOVE-FILE: False
@@ -19,14 +19,14 @@
#
# Check the mkdir command with -p option.
# RUN: rm -f -r %T/test
-# RUN: "%{python}" %S/check_path.py dir %T/test > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test > %t.out
# RUN: FileCheck --check-prefix=REMOVE-PARENT-DIR < %t.out %s
# RUN: mkdir -p %T/test
-# RUN: "%{python}" %S/check_path.py dir %T/test > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test > %t.out
# RUN: FileCheck --check-prefix=MAKE-PARENT-DIR < %t.out %s
# RUN: rm -f %T/test || true
# RUN: rm -f -r %T/test
-# RUN: "%{python}" %S/check_path.py dir %T/test > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test > %t.out
# RUN: FileCheck --check-prefix=REMOVE-PARENT-DIR < %t.out %s
#
# MAKE-PARENT-DIR: True
@@ -36,13 +36,13 @@
#
# RUN: rm -rf %T/test1
# RUN: mkdir %T/test1
-# RUN: "%{python}" %S/check_path.py dir %T/test1 > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test1 > %t.out
# RUN: FileCheck --check-prefix=MAKE-DIR < %t.out %s
# RUN: cd %T/test1 && mkdir foo
-# RUN: "%{python}" %S/check_path.py dir %T/test1 > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test1 > %t.out
# RUN: FileCheck --check-prefix=MAKE-DIR < %t.out %s
# RUN: cd %T && rm -rf %T/test1
-# RUN: "%{python}" %S/check_path.py dir %T/test1 > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test1 > %t.out
# RUN: FileCheck --check-prefix=REMOVE-DIR < %t.out %s
#
# MAKE-DIR: True
@@ -52,16 +52,16 @@
#
# RUN: rm -rf %T/test
# RUN: mkdir -p %T/test/test1 %T/test/test2
-# RUN: "%{python}" %S/check_path.py dir %T/test %T/test/test1 %T/test/test2 > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test %T/test/test1 %T/test/test2 > %t.out
# RUN: FileCheck --check-prefix=DIRS-EXIST < %t.out %s
# RUN: mkdir %T/test || true
# RUN: echo "create a temp file" > %T/test/temp.write
# RUN: echo "create a temp1 file" > %T/test/test1/temp1.write
# RUN: echo "create a temp2 file" > %T/test/test2/temp2.write
-# RUN: "%{python}" %S/check_path.py file %T/test/temp.write %T/test/test1/temp1.write %T/test/test2/temp2.write> %t.out
+# RUN: %{python} %S/check_path.py file %T/test/temp.write %T/test/test1/temp1.write %T/test/test2/temp2.write> %t.out
# RUN: FileCheck --check-prefix=FILES-EXIST < %t.out %s
# RUN: rm -r -f %T/*
-# RUN: "%{python}" %S/check_path.py dir %T/test > %t.out
+# RUN: %{python} %S/check_path.py dir %T/test > %t.out
# RUN: FileCheck --check-prefix=REMOVE-ALL < %t.out %s
#
# DIRS-EXIST: True
@@ -92,7 +92,7 @@
# RUN: mkdir -p %T/testCat
# RUN: echo "abcdefgh" > %T/testCat/temp.write
# RUN: cat %T/testCat/temp.write > %T/testCat/tempcat.write
-# RUN: "%{python}" %S/check_path.py file %T/testCat/tempcat.write > %T/testCat/path.out
+# RUN: %{python} %S/check_path.py file %T/testCat/tempcat.write > %T/testCat/path.out
# RUN: FileCheck --check-prefix=FILE-EXISTS < %T/testCat/path.out %s
# RUN: FileCheck --check-prefix=CAT-OUTPUT < %T/testCat/tempcat.write %s
# FILE-EXISTS: True
@@ -106,7 +106,7 @@
# RUN: echo "efghijkl" > %T/testCat/temp2.write
# RUN: echo "mnopqrst" > %T/testCat/temp3.write
# RUN: cat %T/testCat/temp1.write %T/testCat/temp2.write %T/testCat/temp3.write > %T/testCat/tempmulticat.write
-# RUN: "%{python}" %S/check_path.py file %T/testCat/tempmulticat.write > %T/testCat/path.out
+# RUN: %{python} %S/check_path.py file %T/testCat/tempmulticat.write > %T/testCat/path.out
# RUN: FileCheck --check-prefix=MULTI-FILE-EXISTS < %T/testCat/path.out %s
# RUN: FileCheck --check-prefix=MULTI-CAT-OUTPUT < %T/testCat/tempmulticat.write %s
# MULTI-FILE-EXISTS: True
diff --git a/utils/lit/tests/Inputs/shtest-timeout/lit.cfg b/utils/lit/tests/Inputs/shtest-timeout/lit.cfg
index c3a1c3b96ada..96bf18170a8f 100644
--- a/utils/lit/tests/Inputs/shtest-timeout/lit.cfg
+++ b/utils/lit/tests/Inputs/shtest-timeout/lit.cfg
@@ -29,4 +29,4 @@ config.test_exec_root = config.test_source_root
config.target_triple = '(unused)'
src_root = os.path.join(config.test_source_root, '..')
config.environment['PYTHONPATH'] = src_root
-config.substitutions.append(('%{python}', sys.executable))
+config.substitutions.append(('%{python}', '"%s"' % (sys.executable)))
diff --git a/utils/lit/tests/lit.cfg b/utils/lit/tests/lit.cfg
index 75d1b5eac857..01a3431b4359 100644
--- a/utils/lit/tests/lit.cfg
+++ b/utils/lit/tests/lit.cfg
@@ -40,7 +40,8 @@ config.substitutions.append(('%{inputs}', os.path.join(
src_root, 'tests', 'Inputs')))
config.substitutions.append(('%{lit}', "%%{python} %s" % (
os.path.join(lit_path, 'lit.py'),)))
-config.substitutions.append(('%{python}', sys.executable))
+config.substitutions.append(('%{python}', '"%s"' % (sys.executable)))
+
# Enable coverage.py reporting, assuming the coverage module has been installed
# and sitecustomize.py in the virtualenv has been modified appropriately.