diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-18 08:26:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-18 08:26:46 +0000 |
commit | d0a9cbdae159210824ddf2da138e2dcaecbe1cd4 (patch) | |
tree | c539e15a2dbf52df82eb2a72fb6581db604faab4 | |
parent | ac3a3c134038429abacef8c5d8069674f98d6b34 (diff) |
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
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. |