From dadf0cbf3b46f99d4097219237ab52d73eadd6c8 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 19 Jan 2019 18:44:58 +0000 Subject: [PATCH 1/7] Vendor import of libc++ release_80 branch r351543: https://llvm.org/svn/llvm-project/libcxx/branches/release_80@351543 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a57e36fddcde..3a6c3c9df4d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) project(libcxx CXX C) set(PACKAGE_NAME libcxx) - set(PACKAGE_VERSION 8.0.0svn) + set(PACKAGE_VERSION 8.0.0) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") From e79719ce607b6130e41e23dbdc90cc6b4e0401e6 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 5 Feb 2019 18:38:58 +0000 Subject: [PATCH 2/7] Vendor import of llvm release_80 branch r353167: https://llvm.org/svn/llvm-project/llvm/branches/release_80@353167 --- cmake/modules/AddLLVM.cmake | 1 - docs/ReleaseNotes.rst | 46 +- include/llvm/Support/JSON.h | 1 + .../Transforms/Utils/FunctionImportUtils.h | 5 + lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 5 +- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 +- lib/CodeGen/MachineInstr.cpp | 5 +- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 +- lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 3 +- lib/IR/AutoUpgrade.cpp | 9 +- lib/Support/JSON.cpp | 6 + .../AArch64/AArch64SpeculationHardening.cpp | 179 ++++--- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 5 +- lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 7 + lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h | 5 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 5 +- lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 14 +- lib/Target/Mips/MicroMips32r6InstrInfo.td | 1 + lib/Target/Mips/MicroMipsInstrInfo.td | 1 + lib/Target/Mips/Mips32r6InstrInfo.td | 2 +- lib/Target/Mips/MipsAsmPrinter.cpp | 41 ++ lib/Target/Mips/MipsFastISel.cpp | 13 + lib/Target/Mips/MipsISelLowering.cpp | 53 ++- lib/Target/Mips/MipsISelLowering.h | 3 + lib/Target/Mips/MipsInstrInfo.cpp | 13 +- lib/Target/Mips/MipsInstrInfo.td | 12 +- lib/Target/Mips/MipsMCInstLower.cpp | 2 + lib/Target/X86/X86DiscriminateMemOps.cpp | 11 + lib/Target/X86/X86InsertPrefetch.cpp | 3 +- lib/Transforms/Utils/FunctionImportUtils.cpp | 18 + lib/Transforms/Utils/LoopUtils.cpp | 19 +- test/CodeGen/AArch64/build-vector-extract.ll | 441 ++++++++++++++++++ test/CodeGen/AArch64/eh_recoverfp.ll | 11 + .../AArch64/speculation-hardening-loads.ll | 42 +- test/CodeGen/AArch64/speculation-hardening.ll | 60 +-- .../CodeGen/AArch64/speculation-hardening.mir | 85 ++++ test/CodeGen/Mips/cconv/vector.ll | 8 +- test/CodeGen/Mips/gprestore.ll | 12 +- test/CodeGen/Mips/llvm-ir/sdiv.ll | 36 +- test/CodeGen/Mips/llvm-ir/srem.ll | 36 +- test/CodeGen/Mips/llvm-ir/udiv.ll | 36 +- test/CodeGen/Mips/llvm-ir/urem.ll | 36 +- test/CodeGen/Mips/long-call-attr.ll | 8 +- test/CodeGen/Mips/long-call-mcount.ll | 4 +- test/CodeGen/Mips/msa/f16-llvm-ir.ll | 12 +- test/CodeGen/Mips/o32_cc_byval.ll | 3 +- test/CodeGen/Mips/reloc-jalr.ll | 154 ++++++ test/CodeGen/Mips/shrink-wrapping.ll | 8 +- test/CodeGen/X86/debug-loclists.ll | 6 +- test/CodeGen/X86/discriminate-mem-ops.ll | 2 +- test/CodeGen/X86/insert-prefetch-inline.ll | 2 +- .../X86/insert-prefetch-invalid-instr.ll | 2 +- test/CodeGen/X86/insert-prefetch.ll | 4 +- test/DebugInfo/COFF/types-empty-member-fn.ll | 72 +++ test/DebugInfo/Mips/dwarfdump-tls.ll | 26 +- .../X86/dwarfdump-debug-loclists.test | 8 +- .../FunctionImport/Inputs/comdat.ll | 10 + test/Transforms/FunctionImport/comdat.ll | 32 ++ .../enable_and_isvectorized.ll | 33 ++ .../no_switch_disable_vectorization.ll | 95 ++++ .../X86/debug_loclists_startx_length.s | 4 +- 61 files changed, 1535 insertions(+), 263 deletions(-) create mode 100644 test/CodeGen/AArch64/build-vector-extract.ll create mode 100644 test/CodeGen/AArch64/eh_recoverfp.ll create mode 100644 test/CodeGen/Mips/reloc-jalr.ll create mode 100644 test/DebugInfo/COFF/types-empty-member-fn.ll create mode 100644 test/Transforms/FunctionImport/Inputs/comdat.ll create mode 100644 test/Transforms/FunctionImport/comdat.ll create mode 100644 test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll create mode 100644 test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake index 4dbc0ddaf4f0..0df6845aaa71 100755 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake @@ -1280,7 +1280,6 @@ function(get_llvm_lit_path base_dir file_name) cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN}) if (ARG_ALLOW_EXTERNAL) - set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_EXTERNAL_LIT}") set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit") if ("${LLVM_EXTERNAL_LIT}" STREQUAL "") set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}") diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index db9cf5194952..2bd435ca9d29 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -48,6 +48,12 @@ Non-comprehensive list of changes in this release functionality. See `Writing an LLVM Pass `_. +* For MinGW, references to data variables that might need to be imported + from a dll are accessed via a stub, to allow the linker to convert it to + a dllimport if needed. + +* Added support for labels as offsets in ``.reloc`` directive. + .. NOTE If you would like to document a larger change, then you can add a subsection about it right here. You can copy the following boilerplate @@ -62,17 +68,44 @@ Changes to the LLVM IR ---------------------- +Changes to the AArch64 Target +----------------------------- + +* Added support for the ``.arch_extension`` assembler directive, just like + on ARM. + + Changes to the ARM Backend -------------------------- During this release ... +Changes to the Hexagon Target +-------------------------- + +* Added support for Hexagon/HVX V66 ISA. + Changes to the MIPS Target -------------------------- - During this release ... +* Improved support of GlobalISel instruction selection framework. +* Implemented emission of ``R_MIPS_JALR`` and ``R_MICROMIPS_JALR`` + relocations. These relocations provide hints to a linker for optimization + of jumps to protected symbols. + +* ORC JIT has been supported for MIPS and MIPS64 architectures. + +* Assembler now suggests alternative MIPS instruction mnemonics when + an invalid one is specified. + +* Improved support for MIPS N32 ABI. + +* Added new instructions (``pll.ps``, ``plu.ps``, ``cvt.s.pu``, + ``cvt.s.pl``, ``cvt.ps``, ``sigrie``). + +* Numerous bug fixes and code cleanups. Changes to the PowerPC Target ----------------------------- @@ -123,7 +156,16 @@ Changes to the DAG infrastructure External Open Source Projects Using LLVM 8 ========================================== -* A project... +Zig Programming Language +------------------------ + +`Zig `_ is a system programming language intended to be +an alternative to C. It provides high level features such as generics, compile +time function execution, and partial evaluation, while exposing low level LLVM +IR features such as aliases and intrinsics. Zig uses Clang to provide automatic +import of .h symbols, including inline functions and simple macros. Zig uses +LLD combined with lazily building compiler-rt to provide out-of-the-box +cross-compiling for all supported targets. Additional Information diff --git a/include/llvm/Support/JSON.h b/include/llvm/Support/JSON.h index 7a04fd52bc50..2b95a174e018 100644 --- a/include/llvm/Support/JSON.h +++ b/include/llvm/Support/JSON.h @@ -481,6 +481,7 @@ class Value { mutable llvm::AlignedCharArrayUnion Union; + friend bool operator==(const Value &, const Value &); }; bool operator==(const Value &, const Value &); diff --git a/include/llvm/Transforms/Utils/FunctionImportUtils.h b/include/llvm/Transforms/Utils/FunctionImportUtils.h index e24398b90012..fe1355976818 100644 --- a/include/llvm/Transforms/Utils/FunctionImportUtils.h +++ b/include/llvm/Transforms/Utils/FunctionImportUtils.h @@ -44,6 +44,11 @@ class FunctionImportGlobalProcessing { /// to promote any non-renamable values. SmallPtrSet Used; + /// Keep track of any COMDATs that require renaming (because COMDAT + /// leader was promoted and renamed). Maps from original COMDAT to one + /// with new name. + DenseMap RenamedComdats; + /// Check if we should promote the given local value to global scope. bool shouldPromoteLocalToGlobal(const GlobalValue *SGV); diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 8cabad4ad312..154f81f2622d 100644 --- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1836,7 +1836,10 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, unsigned Index = 0; SmallVector ArgTypeIndices; - TypeIndex ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]); + TypeIndex ReturnTypeIndex = TypeIndex::Void(); + if (ReturnAndArgs.size() > Index) { + ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]); + } // If the first argument is a pointer type and this isn't a static method, // treat it as the special 'this' parameter, which is encoded separately from diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 1de2ffb6cfa1..18c5fe27b1a8 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1956,8 +1956,10 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry) { // Emit the size. Asm->OutStreamer->AddComment("Loc expr size"); - Asm->emitInt16(DebugLocs.getBytes(Entry).size()); - + if (getDwarfVersion() >= 5) + Asm->EmitULEB128(DebugLocs.getBytes(Entry).size()); + else + Asm->emitInt16(DebugLocs.getBytes(Entry).size()); // Emit the entry. APByteStreamer Streamer(*Asm); emitDebugLocEntry(Streamer, Entry); diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 764a84c7e132..dc1ad953e71d 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -225,12 +225,13 @@ void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { } #ifndef NDEBUG - bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; + bool isDebugOp = Op.getType() == MachineOperand::MO_Metadata || + Op.getType() == MachineOperand::MO_MCSymbol; // OpNo now points as the desired insertion point. Unless this is a variadic // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). // RegMask operands go between the explicit and implicit operands. assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || - OpNo < MCID->getNumOperands() || isMetaDataOp) && + OpNo < MCID->getNumOperands() || isDebugOp) && "Trying to add an operand to a machine instr that is already done!"); #endif diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index ff5505c97721..6af01423ca10 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -16214,23 +16214,29 @@ static SDValue reduceBuildVecToShuffleWithZero(SDNode *BV, SelectionDAG &DAG) { // The build vector contains some number of undef elements and exactly // one other element. That other element must be a zero-extended scalar // extracted from a vector at a constant index to turn this into a shuffle. + // Also, require that the build vector does not implicitly truncate/extend + // its elements. // TODO: This could be enhanced to allow ANY_EXTEND as well as ZERO_EXTEND. + EVT VT = BV->getValueType(0); SDValue Zext = BV->getOperand(ZextElt); if (Zext.getOpcode() != ISD::ZERO_EXTEND || !Zext.hasOneUse() || Zext.getOperand(0).getOpcode() != ISD::EXTRACT_VECTOR_ELT || - !isa(Zext.getOperand(0).getOperand(1))) + !isa(Zext.getOperand(0).getOperand(1)) || + Zext.getValueSizeInBits() != VT.getScalarSizeInBits()) return SDValue(); - // The zero-extend must be a multiple of the source size. + // The zero-extend must be a multiple of the source size, and we must be + // building a vector of the same size as the source of the extract element. SDValue Extract = Zext.getOperand(0); unsigned DestSize = Zext.getValueSizeInBits(); unsigned SrcSize = Extract.getValueSizeInBits(); - if (DestSize % SrcSize != 0) + if (DestSize % SrcSize != 0 || + Extract.getOperand(0).getValueSizeInBits() != VT.getSizeInBits()) return SDValue(); // Create a shuffle mask that will combine the extracted element with zeros // and undefs. - int ZextRatio = DestSize / SrcSize; + int ZextRatio = DestSize / SrcSize; int NumMaskElts = NumBVOps * ZextRatio; SmallVector ShufMask(NumMaskElts, -1); for (int i = 0; i != NumMaskElts; ++i) { @@ -16260,7 +16266,7 @@ static SDValue reduceBuildVecToShuffleWithZero(SDNode *BV, SelectionDAG &DAG) { SDValue ZeroVec = DAG.getConstant(0, DL, VecVT); SDValue Shuf = DAG.getVectorShuffle(VecVT, DL, Extract.getOperand(0), ZeroVec, ShufMask); - return DAG.getBitcast(BV->getValueType(0), Shuf); + return DAG.getBitcast(VT, Shuf); } // Check to see if this is a BUILD_VECTOR of a bunch of EXTRACT_VECTOR_ELT diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index f8b5ff6ec8fb..94df6946f3ae 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -184,7 +184,8 @@ DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset, } if (Kind != dwarf::DW_LLE_base_address) { - unsigned Bytes = Data.getU16(Offset); + unsigned Bytes = + Version >= 5 ? Data.getULEB128(Offset) : Data.getU16(Offset); // A single location description describing the location of the object... StringRef str = Data.getData().substr(*Offset, Bytes); *Offset += Bytes; diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index b2eb8b09982e..27064154221f 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -469,6 +469,11 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name, } } + if (Name == "seh.recoverfp") { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_recoverfp); + return true; + } + return false; } @@ -544,10 +549,6 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer); return true; } - if (Name == "x86.seh.recoverfp") { - NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_recoverfp); - return true; - } break; } diff --git a/lib/Support/JSON.cpp b/lib/Support/JSON.cpp index d468013fb94a..07a556814915 100644 --- a/lib/Support/JSON.cpp +++ b/lib/Support/JSON.cpp @@ -182,6 +182,12 @@ bool operator==(const Value &L, const Value &R) { case Value::Boolean: return *L.getAsBoolean() == *R.getAsBoolean(); case Value::Number: + // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + // The same integer must convert to the same double, per the standard. + // However we see 64-vs-80-bit precision comparisons with gcc-7 -O3 -m32. + // So we avoid floating point promotion for exact comparisons. + if (L.Type == Value::T_Integer || R.Type == Value::T_Integer) + return L.getAsInteger() == R.getAsInteger(); return *L.getAsNumber() == *R.getAsNumber(); case Value::String: return *L.getAsString() == *R.getAsString(); diff --git a/lib/Target/AArch64/AArch64SpeculationHardening.cpp b/lib/Target/AArch64/AArch64SpeculationHardening.cpp index e9699b0367d3..50300305abe3 100644 --- a/lib/Target/AArch64/AArch64SpeculationHardening.cpp +++ b/lib/Target/AArch64/AArch64SpeculationHardening.cpp @@ -103,6 +103,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/IR/DebugLoc.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" @@ -146,25 +147,31 @@ class AArch64SpeculationHardening : public MachineFunctionPass { BitVector RegsAlreadyMasked; bool functionUsesHardeningRegister(MachineFunction &MF) const; - bool instrumentControlFlow(MachineBasicBlock &MBB); + bool instrumentControlFlow(MachineBasicBlock &MBB, + bool &UsesFullSpeculationBarrier); bool endsWithCondControlFlow(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, AArch64CC::CondCode &CondCode) const; void insertTrackingCode(MachineBasicBlock &SplitEdgeBB, AArch64CC::CondCode &CondCode, DebugLoc DL) const; - void insertSPToRegTaintPropagation(MachineBasicBlock *MBB, + void insertSPToRegTaintPropagation(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const; - void insertRegToSPTaintPropagation(MachineBasicBlock *MBB, + void insertRegToSPTaintPropagation(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned TmpReg) const; + void insertFullSpeculationBarrier(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + DebugLoc DL) const; bool slhLoads(MachineBasicBlock &MBB); bool makeGPRSpeculationSafe(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineInstr &MI, unsigned Reg); - bool lowerSpeculationSafeValuePseudos(MachineBasicBlock &MBB); + bool lowerSpeculationSafeValuePseudos(MachineBasicBlock &MBB, + bool UsesFullSpeculationBarrier); bool expandSpeculationSafeValue(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI); + MachineBasicBlock::iterator MBBI, + bool UsesFullSpeculationBarrier); bool insertCSDB(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL); }; @@ -207,15 +214,19 @@ bool AArch64SpeculationHardening::endsWithCondControlFlow( return true; } +void AArch64SpeculationHardening::insertFullSpeculationBarrier( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + DebugLoc DL) const { + // A full control flow speculation barrier consists of (DSB SYS + ISB) + BuildMI(MBB, MBBI, DL, TII->get(AArch64::DSB)).addImm(0xf); + BuildMI(MBB, MBBI, DL, TII->get(AArch64::ISB)).addImm(0xf); +} + void AArch64SpeculationHardening::insertTrackingCode( MachineBasicBlock &SplitEdgeBB, AArch64CC::CondCode &CondCode, DebugLoc DL) const { if (UseControlFlowSpeculationBarrier) { - // insert full control flow speculation barrier (DSB SYS + ISB) - BuildMI(SplitEdgeBB, SplitEdgeBB.begin(), DL, TII->get(AArch64::ISB)) - .addImm(0xf); - BuildMI(SplitEdgeBB, SplitEdgeBB.begin(), DL, TII->get(AArch64::DSB)) - .addImm(0xf); + insertFullSpeculationBarrier(SplitEdgeBB, SplitEdgeBB.begin(), DL); } else { BuildMI(SplitEdgeBB, SplitEdgeBB.begin(), DL, TII->get(AArch64::CSELXr)) .addDef(MisspeculatingTaintReg) @@ -227,7 +238,7 @@ void AArch64SpeculationHardening::insertTrackingCode( } bool AArch64SpeculationHardening::instrumentControlFlow( - MachineBasicBlock &MBB) { + MachineBasicBlock &MBB, bool &UsesFullSpeculationBarrier) { LLVM_DEBUG(dbgs() << "Instrument control flow tracking on MBB: " << MBB); bool Modified = false; @@ -263,55 +274,105 @@ bool AArch64SpeculationHardening::instrumentControlFlow( } // Perform correct code generation around function calls and before returns. - { - SmallVector ReturnInstructions; - SmallVector CallInstructions; + // The below variables record the return/terminator instructions and the call + // instructions respectively; including which register is available as a + // temporary register just before the recorded instructions. + SmallVector, 4> ReturnInstructions; + SmallVector, 4> CallInstructions; + // if a temporary register is not available for at least one of the + // instructions for which we need to transfer taint to the stack pointer, we + // need to insert a full speculation barrier. + // TmpRegisterNotAvailableEverywhere tracks that condition. + bool TmpRegisterNotAvailableEverywhere = false; - for (MachineInstr &MI : MBB) { - if (MI.isReturn()) - ReturnInstructions.push_back(&MI); - else if (MI.isCall()) - CallInstructions.push_back(&MI); - } + RegScavenger RS; + RS.enterBasicBlock(MBB); - Modified |= - (ReturnInstructions.size() > 0) || (CallInstructions.size() > 0); + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); I++) { + MachineInstr &MI = *I; + if (!MI.isReturn() && !MI.isCall()) + continue; - for (MachineInstr *Return : ReturnInstructions) - insertRegToSPTaintPropagation(Return->getParent(), Return, AArch64::X17); - for (MachineInstr *Call : CallInstructions) { - // Just after the call: - MachineBasicBlock::iterator i = Call; - i++; - insertSPToRegTaintPropagation(Call->getParent(), i); - // Just before the call: - insertRegToSPTaintPropagation(Call->getParent(), Call, AArch64::X17); - } + // The RegScavenger represents registers available *after* the MI + // instruction pointed to by RS.getCurrentPosition(). + // We need to have a register that is available *before* the MI is executed. + if (I != MBB.begin()) + RS.forward(std::prev(I)); + // FIXME: The below just finds *a* unused register. Maybe code could be + // optimized more if this looks for the register that isn't used for the + // longest time around this place, to enable more scheduling freedom. Not + // sure if that would actually result in a big performance difference + // though. Maybe RegisterScavenger::findSurvivorBackwards has some logic + // already to do this - but it's unclear if that could easily be used here. + unsigned TmpReg = RS.FindUnusedReg(&AArch64::GPR64commonRegClass); + LLVM_DEBUG(dbgs() << "RS finds " + << ((TmpReg == 0) ? "no register " : "register "); + if (TmpReg != 0) dbgs() << printReg(TmpReg, TRI) << " "; + dbgs() << "to be available at MI " << MI); + if (TmpReg == 0) + TmpRegisterNotAvailableEverywhere = true; + if (MI.isReturn()) + ReturnInstructions.push_back({&MI, TmpReg}); + else if (MI.isCall()) + CallInstructions.push_back({&MI, TmpReg}); } + if (TmpRegisterNotAvailableEverywhere) { + // When a temporary register is not available everywhere in this basic + // basic block where a propagate-taint-to-sp operation is needed, just + // emit a full speculation barrier at the start of this basic block, which + // renders the taint/speculation tracking in this basic block unnecessary. + insertFullSpeculationBarrier(MBB, MBB.begin(), + (MBB.begin())->getDebugLoc()); + UsesFullSpeculationBarrier = true; + Modified = true; + } else { + for (auto MI_Reg : ReturnInstructions) { + assert(MI_Reg.second != 0); + LLVM_DEBUG( + dbgs() + << " About to insert Reg to SP taint propagation with temp register " + << printReg(MI_Reg.second, TRI) + << " on instruction: " << *MI_Reg.first); + insertRegToSPTaintPropagation(MBB, MI_Reg.first, MI_Reg.second); + Modified = true; + } + + for (auto MI_Reg : CallInstructions) { + assert(MI_Reg.second != 0); + LLVM_DEBUG(dbgs() << " About to insert Reg to SP and back taint " + "propagation with temp register " + << printReg(MI_Reg.second, TRI) + << " around instruction: " << *MI_Reg.first); + // Just after the call: + insertSPToRegTaintPropagation( + MBB, std::next((MachineBasicBlock::iterator)MI_Reg.first)); + // Just before the call: + insertRegToSPTaintPropagation(MBB, MI_Reg.first, MI_Reg.second); + Modified = true; + } + } return Modified; } void AArch64SpeculationHardening::insertSPToRegTaintPropagation( - MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI) const { + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const { // If full control flow speculation barriers are used, emit a control flow // barrier to block potential miss-speculation in flight coming in to this // function. if (UseControlFlowSpeculationBarrier) { - // insert full control flow speculation barrier (DSB SYS + ISB) - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::DSB)).addImm(0xf); - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ISB)).addImm(0xf); + insertFullSpeculationBarrier(MBB, MBBI, DebugLoc()); return; } // CMP SP, #0 === SUBS xzr, SP, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::SUBSXri)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::SUBSXri)) .addDef(AArch64::XZR) .addUse(AArch64::SP) .addImm(0) .addImm(0); // no shift // CSETM x16, NE === CSINV x16, xzr, xzr, EQ - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::CSINVXr)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::CSINVXr)) .addDef(MisspeculatingTaintReg) .addUse(AArch64::XZR) .addUse(AArch64::XZR) @@ -319,7 +380,7 @@ void AArch64SpeculationHardening::insertSPToRegTaintPropagation( } void AArch64SpeculationHardening::insertRegToSPTaintPropagation( - MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned TmpReg) const { // If full control flow speculation barriers are used, there will not be // miss-speculation when returning from this function, and therefore, also @@ -328,19 +389,19 @@ void AArch64SpeculationHardening::insertRegToSPTaintPropagation( return; // mov Xtmp, SP === ADD Xtmp, SP, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) .addDef(TmpReg) .addUse(AArch64::SP) .addImm(0) .addImm(0); // no shift // and Xtmp, Xtmp, TaintReg === AND Xtmp, Xtmp, TaintReg, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ANDXrs)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ANDXrs)) .addDef(TmpReg, RegState::Renamable) .addUse(TmpReg, RegState::Kill | RegState::Renamable) .addUse(MisspeculatingTaintReg, RegState::Kill) .addImm(0); // mov SP, Xtmp === ADD SP, Xtmp, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) .addDef(AArch64::SP) .addUse(TmpReg, RegState::Kill) .addImm(0) @@ -484,7 +545,8 @@ bool AArch64SpeculationHardening::slhLoads(MachineBasicBlock &MBB) { /// \brief If MBBI references a pseudo instruction that should be expanded /// here, do the expansion and return true. Otherwise return false. bool AArch64SpeculationHardening::expandSpeculationSafeValue( - MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) { + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + bool UsesFullSpeculationBarrier) { MachineInstr &MI = *MBBI; unsigned Opcode = MI.getOpcode(); bool Is64Bit = true; @@ -499,7 +561,7 @@ bool AArch64SpeculationHardening::expandSpeculationSafeValue( // Just remove the SpeculationSafe pseudo's if control flow // miss-speculation isn't happening because we're already inserting barriers // to guarantee that. - if (!UseControlFlowSpeculationBarrier) { + if (!UseControlFlowSpeculationBarrier && !UsesFullSpeculationBarrier) { unsigned DstReg = MI.getOperand(0).getReg(); unsigned SrcReg = MI.getOperand(1).getReg(); // Mark this register and all its aliasing registers as needing to be @@ -537,7 +599,7 @@ bool AArch64SpeculationHardening::insertCSDB(MachineBasicBlock &MBB, } bool AArch64SpeculationHardening::lowerSpeculationSafeValuePseudos( - MachineBasicBlock &MBB) { + MachineBasicBlock &MBB, bool UsesFullSpeculationBarrier) { bool Modified = false; RegsNeedingCSDBBeforeUse.reset(); @@ -572,15 +634,16 @@ bool AArch64SpeculationHardening::lowerSpeculationSafeValuePseudos( break; } - if (NeedToEmitBarrier) + if (NeedToEmitBarrier && !UsesFullSpeculationBarrier) Modified |= insertCSDB(MBB, MBBI, DL); - Modified |= expandSpeculationSafeValue(MBB, MBBI); + Modified |= + expandSpeculationSafeValue(MBB, MBBI, UsesFullSpeculationBarrier); MBBI = NMBBI; } - if (RegsNeedingCSDBBeforeUse.any()) + if (RegsNeedingCSDBBeforeUse.any() && !UsesFullSpeculationBarrier) Modified |= insertCSDB(MBB, MBBI, DL); return Modified; @@ -609,7 +672,7 @@ bool AArch64SpeculationHardening::runOnMachineFunction(MachineFunction &MF) { Modified |= slhLoads(MBB); } - // 2.a Add instrumentation code to function entry and exits. + // 2. Add instrumentation code to function entry and exits. LLVM_DEBUG( dbgs() << "***** AArch64SpeculationHardening - track control flow *****\n"); @@ -620,17 +683,15 @@ bool AArch64SpeculationHardening::runOnMachineFunction(MachineFunction &MF) { EntryBlocks.push_back(LPI.LandingPadBlock); for (auto Entry : EntryBlocks) insertSPToRegTaintPropagation( - Entry, Entry->SkipPHIsLabelsAndDebug(Entry->begin())); + *Entry, Entry->SkipPHIsLabelsAndDebug(Entry->begin())); - // 2.b Add instrumentation code to every basic block. - for (auto &MBB : MF) - Modified |= instrumentControlFlow(MBB); - - LLVM_DEBUG(dbgs() << "***** AArch64SpeculationHardening - Lowering " - "SpeculationSafeValue Pseudos *****\n"); - // Step 3: Lower SpeculationSafeValue pseudo instructions. - for (auto &MBB : MF) - Modified |= lowerSpeculationSafeValuePseudos(MBB); + // 3. Add instrumentation code to every basic block. + for (auto &MBB : MF) { + bool UsesFullSpeculationBarrier = false; + Modified |= instrumentControlFlow(MBB, UsesFullSpeculationBarrier); + Modified |= + lowerSpeculationSafeValuePseudos(MBB, UsesFullSpeculationBarrier); + } return Modified; } diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d2fed6861477..f10d100bfe11 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -65,10 +65,7 @@ class MCInstrInfo; } // end namespace llvm -static cl::opt -EmitJalrReloc("mips-jalr-reloc", cl::Hidden, - cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), - cl::init(true)); +extern cl::opt EmitJalrReloc; namespace { diff --git a/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 18d7dd99be34..2f2dd4e03c40 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -15,6 +15,13 @@ using namespace llvm; +// Note: this option is defined here to be visible from libLLVMMipsAsmParser +// and libLLVMMipsCodeGen +cl::opt +EmitJalrReloc("mips-jalr-reloc", cl::Hidden, + cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), + cl::init(true)); + namespace { static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; diff --git a/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h index a90db2384c46..ab8a6753eadc 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ b/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -89,7 +89,10 @@ namespace MipsII { MO_GOT_HI16, MO_GOT_LO16, MO_CALL_HI16, - MO_CALL_LO16 + MO_CALL_LO16, + + /// Helper operand used to generate R_MIPS_JALR + MO_JALR }; enum { diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index f43a4d980f92..e3dcbaccfd08 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -614,8 +614,9 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, llvm_unreachable("Unhandled fixup kind!"); break; case MipsMCExpr::MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); - break; + // MEK_DTPREL is used for marking TLS DIEExpr only + // and contains a regular sub-expression. + return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI); case MipsMCExpr::MEK_CALL_HI16: FixupKind = Mips::fixup_Mips_CALL_HI16; break; diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp index 99857e083c6c..2d7312725205 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -44,8 +44,10 @@ void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { llvm_unreachable("MEK_None and MEK_Special are invalid"); break; case MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); - break; + // MEK_DTPREL is used for marking TLS DIEExpr only + // and contains a regular sub-expression. + getSubExpr()->print(OS, MAI, true); + return; case MEK_CALL_HI16: OS << "%call_hi"; break; @@ -161,7 +163,9 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); case MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); + // MEK_DTPREL is used for marking TLS DIEExpr only + // and contains a regular sub-expression. + return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup); case MEK_DTPREL_HI: case MEK_DTPREL_LO: case MEK_GOT: @@ -249,9 +253,6 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); break; - case MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); - break; case MEK_CALL_HI16: case MEK_CALL_LO16: case MEK_GOT: @@ -274,6 +275,7 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { if (const MipsMCExpr *E = dyn_cast(getSubExpr())) E->fixELFSymbolsInTLSFixups(Asm); break; + case MEK_DTPREL: case MEK_DTPREL_HI: case MEK_DTPREL_LO: case MEK_TLSLDM: diff --git a/lib/Target/Mips/MicroMips32r6InstrInfo.td b/lib/Target/Mips/MicroMips32r6InstrInfo.td index 814918d25e70..c441aa76ad40 100644 --- a/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -460,6 +460,7 @@ class JALRC16_MMR6_DESC_BASE let isCall = 1; let hasDelaySlot = 0; let Defs = [RA]; + let hasPostISelHook = 1; } class JALRC16_MMR6_DESC : JALRC16_MMR6_DESC_BASE<"jalr", GPR32Opnd>; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index af380a0ec71e..ccc4f04bb92d 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -426,6 +426,7 @@ class JumpLinkRegMM16 : let isCall = 1; let hasDelaySlot = 1; let Defs = [RA]; + let hasPostISelHook = 1; } // 16-bit Jump Reg diff --git a/lib/Target/Mips/Mips32r6InstrInfo.td b/lib/Target/Mips/Mips32r6InstrInfo.td index 2bd0cf2d59a6..fb239f572ef2 100644 --- a/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/lib/Target/Mips/Mips32r6InstrInfo.td @@ -1105,7 +1105,7 @@ def : MipsPat<(select i32:$cond, immz, i32:$f), // Pseudo instructions let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, - hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in { + hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT], hasPostISelHook = 1 in { class TailCallRegR6 : PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, PseudoInstExpansion<(JumpInst RT:$rt, RO:$rs)>; diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 362431fd42a6..a7a748b0840e 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -68,6 +68,8 @@ using namespace llvm; #define DEBUG_TYPE "mips-asm-printer" +extern cl::opt EmitJalrReloc; + MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const { return static_cast(*OutStreamer->getTargetStreamer()); } @@ -148,6 +150,40 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, EmitToStreamer(OutStreamer, TmpInst0); } +// If there is an MO_JALR operand, insert: +// +// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol +// tmplabel: +// +// This is an optimization hint for the linker which may then replace +// an indirect call with a direct branch. +static void emitDirectiveRelocJalr(const MachineInstr &MI, + MCContext &OutContext, + TargetMachine &TM, + MCStreamer &OutStreamer, + const MipsSubtarget &Subtarget) { + for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands(); + I < E; ++I) { + MachineOperand MO = MI.getOperand(I); + if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) { + MCSymbol *Callee = MO.getMCSymbol(); + if (Callee && !Callee->getName().empty()) { + MCSymbol *OffsetLabel = OutContext.createTempSymbol(); + const MCExpr *OffsetExpr = + MCSymbolRefExpr::create(OffsetLabel, OutContext); + const MCExpr *CaleeExpr = + MCSymbolRefExpr::create(Callee, OutContext); + OutStreamer.EmitRelocDirective + (*OffsetExpr, + Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", + CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo()); + OutStreamer.EmitLabel(OffsetLabel); + return; + } + } + } +} + void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { MipsTargetStreamer &TS = getTargetStreamer(); unsigned Opc = MI->getOpcode(); @@ -207,6 +243,11 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { return; } + if (EmitJalrReloc && + (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) { + emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget); + } + MachineBasicBlock::const_instr_iterator I = MI->getIterator(); MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); diff --git a/lib/Target/Mips/MipsFastISel.cpp b/lib/Target/Mips/MipsFastISel.cpp index 22ade31a72cd..a18416b9e861 100644 --- a/lib/Target/Mips/MipsFastISel.cpp +++ b/lib/Target/Mips/MipsFastISel.cpp @@ -56,6 +56,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSymbol.h" @@ -75,6 +76,8 @@ using namespace llvm; +extern cl::opt EmitJalrReloc; + namespace { class MipsFastISel final : public FastISel { @@ -1551,6 +1554,16 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { CLI.Call = MIB; + if (EmitJalrReloc && !Subtarget->inMips16Mode()) { + // Attach callee address to the instruction, let asm printer emit + // .reloc R_MIPS_JALR. + if (Symbol) + MIB.addSym(Symbol, MipsII::MO_JALR); + else + MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol( + Addr.getGlobalValue()->getName()), MipsII::MO_JALR); + } + // Finish off the call including any return values. return finishCall(CLI, RetVT, NumBytes); } diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 8c2a364cdfa9..0f9c075ba0cc 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -57,6 +57,7 @@ #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CodeGen.h" @@ -91,6 +92,8 @@ NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false)); +extern cl::opt EmitJalrReloc; + static const MCPhysReg Mips64DPRegs[8] = { Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64, Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64 @@ -2879,6 +2882,54 @@ getOpndList(SmallVectorImpl &Ops, Ops.push_back(InFlag); } +void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const { + switch (MI.getOpcode()) { + default: + return; + case Mips::JALR: + case Mips::JALRPseudo: + case Mips::JALR64: + case Mips::JALR64Pseudo: + case Mips::JALR16_MM: + case Mips::JALRC16_MMR6: + case Mips::TAILCALLREG: + case Mips::TAILCALLREG64: + case Mips::TAILCALLR6REG: + case Mips::TAILCALL64R6REG: + case Mips::TAILCALLREG_MM: + case Mips::TAILCALLREG_MMR6: { + if (!EmitJalrReloc || + Subtarget.inMips16Mode() || + !isPositionIndependent() || + Node->getNumOperands() < 1 || + Node->getOperand(0).getNumOperands() < 2) { + return; + } + // We are after the callee address, set by LowerCall(). + // If added to MI, asm printer will emit .reloc R_MIPS_JALR for the + // symbol. + const SDValue TargetAddr = Node->getOperand(0).getOperand(1); + StringRef Sym; + if (const GlobalAddressSDNode *G = + dyn_cast_or_null(TargetAddr)) { + Sym = G->getGlobal()->getName(); + } + else if (const ExternalSymbolSDNode *ES = + dyn_cast_or_null(TargetAddr)) { + Sym = ES->getSymbol(); + } + + if (Sym.empty()) + return; + + MachineFunction *MF = MI.getParent()->getParent(); + MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym); + MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR)); + } + } +} + /// LowerCall - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. SDValue @@ -2930,7 +2981,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // the maximum out going argument area (including the reserved area), and // preallocates the stack space on entrance to the caller. // - // FIXME: We should do the same for efficency and space. + // FIXME: We should do the same for efficiency and space. // Note: The check on the calling convention below must match // MipsABIInfo::GetCalleeAllocdArgSizeInBytes(). diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index e043f133a09f..c88633be02b7 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -341,6 +341,9 @@ class TargetRegisterClass; EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override; + void AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const override; + void HandleByVal(CCState *, unsigned &, unsigned) const override; unsigned getRegisterByName(const char* RegName, EVT VT, diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index bfb4c775205d..e38bef4663a7 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -653,6 +653,16 @@ MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc, MIB.addImm(0); + // If I has an MCSymbol operand (used by asm printer, to emit R_MIPS_JALR), + // add it to the new instruction. + for (unsigned J = I->getDesc().getNumOperands(), E = I->getNumOperands(); + J < E; ++J) { + const MachineOperand &MO = I->getOperand(J); + if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) + MIB.addSym(MO.getMCSymbol(), MipsII::MO_JALR); + } + + } else { for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { if (BranchWithZeroOperand && (unsigned)ZeroOperandPosition == J) @@ -825,7 +835,8 @@ MipsInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { {MO_GOT_HI16, "mips-got-hi16"}, {MO_GOT_LO16, "mips-got-lo16"}, {MO_CALL_HI16, "mips-call-hi16"}, - {MO_CALL_LO16, "mips-call-lo16"} + {MO_CALL_LO16, "mips-call-lo16"}, + {MO_JALR, "mips-jalr"} }; return makeArrayRef(Flags); } diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index d9398b7d6024..46721e6cb9e5 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1623,11 +1623,15 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in { class JumpLinkRegPseudo: PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>, - PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; + PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> { + let hasPostISelHook = 1; + } class JumpLinkReg: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [], II_JALR, FrmR, opstr>; + [], II_JALR, FrmR, opstr> { + let hasPostISelHook = 1; + } class BGEZAL_FT : @@ -1646,7 +1650,9 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, class TailCallReg : PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, - PseudoInstExpansion<(JumpInst RO:$rs)>; + PseudoInstExpansion<(JumpInst RO:$rs)> { + let hasPostISelHook = 1; + } } class BAL_BR_Pseudo : diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index 46b37ceae391..4a7c0ce2be19 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -117,6 +117,8 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, case MipsII::MO_CALL_LO16: TargetKind = MipsMCExpr::MEK_CALL_LO16; break; + case MipsII::MO_JALR: + return MCOperand(); } switch (MOTy) { diff --git a/lib/Target/X86/X86DiscriminateMemOps.cpp b/lib/Target/X86/X86DiscriminateMemOps.cpp index 3654bf04f4e9..6bee20b617dd 100644 --- a/lib/Target/X86/X86DiscriminateMemOps.cpp +++ b/lib/Target/X86/X86DiscriminateMemOps.cpp @@ -27,6 +27,14 @@ using namespace llvm; #define DEBUG_TYPE "x86-discriminate-memops" +static cl::opt EnableDiscriminateMemops( + DEBUG_TYPE, cl::init(false), + cl::desc("Generate unique debug info for each instruction with a memory " + "operand. Should be enabled for profile-drived cache prefetching, " + "both in the build of the binary being profiled, as well as in " + "the build of the binary consuming the profile."), + cl::Hidden); + namespace { using Location = std::pair; @@ -67,6 +75,9 @@ char X86DiscriminateMemOps::ID = 0; X86DiscriminateMemOps::X86DiscriminateMemOps() : MachineFunctionPass(ID) {} bool X86DiscriminateMemOps::runOnMachineFunction(MachineFunction &MF) { + if (!EnableDiscriminateMemops) + return false; + DISubprogram *FDI = MF.getFunction().getSubprogram(); if (!FDI || !FDI->getUnit()->getDebugInfoForProfiling()) return false; diff --git a/lib/Target/X86/X86InsertPrefetch.cpp b/lib/Target/X86/X86InsertPrefetch.cpp index 30b46a09ef0f..8bd57aa2278b 100644 --- a/lib/Target/X86/X86InsertPrefetch.cpp +++ b/lib/Target/X86/X86InsertPrefetch.cpp @@ -34,7 +34,8 @@ using namespace sampleprof; static cl::opt PrefetchHintsFile("prefetch-hints-file", - cl::desc("Path to the prefetch hints profile."), + cl::desc("Path to the prefetch hints profile. See also " + "-x86-discriminate-memops"), cl::Hidden); namespace { diff --git a/lib/Transforms/Utils/FunctionImportUtils.cpp b/lib/Transforms/Utils/FunctionImportUtils.cpp index a9772e31da50..81d63ee80394 100644 --- a/lib/Transforms/Utils/FunctionImportUtils.cpp +++ b/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -249,6 +249,8 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { + // Save the original name string before we rename GV below. + auto Name = GV.getName().str(); // Once we change the name or linkage it is difficult to determine // again whether we should promote since shouldPromoteLocalToGlobal needs // to locate the summary (based on GUID from name and linkage). Therefore, @@ -257,6 +259,12 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { GV.setLinkage(getLinkage(&GV, DoPromote)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); + + // If we are renaming a COMDAT leader, ensure that we record the COMDAT + // for later renaming as well. This is required for COFF. + if (const auto *C = GV.getComdat()) + if (C->getName() == Name) + RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName())); } else GV.setLinkage(getLinkage(&GV, /* DoPromote */ false)); @@ -281,6 +289,16 @@ void FunctionImportGlobalProcessing::processGlobalsForThinLTO() { processGlobalForThinLTO(SF); for (GlobalAlias &GA : M.aliases()) processGlobalForThinLTO(GA); + + // Replace any COMDATS that required renaming (because the COMDAT leader was + // promoted and renamed). + if (!RenamedComdats.empty()) + for (auto &GO : M.global_objects()) + if (auto *C = GO.getComdat()) { + auto Replacement = RenamedComdats.find(C); + if (Replacement != RenamedComdats.end()) + GO.setComdat(Replacement->second); + } } bool FunctionImportGlobalProcessing::run() { diff --git a/lib/Transforms/Utils/LoopUtils.cpp b/lib/Transforms/Utils/LoopUtils.cpp index a93d1aeb62ef..112e80d27e34 100644 --- a/lib/Transforms/Utils/LoopUtils.cpp +++ b/lib/Transforms/Utils/LoopUtils.cpp @@ -217,7 +217,10 @@ static Optional getOptionalBoolLoopAttribute(const Loop *TheLoop, // When the value is absent it is interpreted as 'attribute set'. return true; case 2: - return mdconst::extract_or_null(MD->getOperand(1).get()); + if (ConstantInt *IntMD = + mdconst::extract_or_null(MD->getOperand(1).get())) + return IntMD->getZExtValue(); + return true; } llvm_unreachable("unexpected number of options"); } @@ -376,17 +379,17 @@ TransformationMode llvm::hasVectorizeTransformation(Loop *L) { Optional InterleaveCount = getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count"); - if (Enable == true) { - // 'Forcing' vector width and interleave count to one effectively disables - // this tranformation. - if (VectorizeWidth == 1 && InterleaveCount == 1) - return TM_SuppressedByUser; - return TM_ForcedByUser; - } + // 'Forcing' vector width and interleave count to one effectively disables + // this tranformation. + if (Enable == true && VectorizeWidth == 1 && InterleaveCount == 1) + return TM_SuppressedByUser; if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized")) return TM_Disable; + if (Enable == true) + return TM_ForcedByUser; + if (VectorizeWidth == 1 && InterleaveCount == 1) return TM_Disable; diff --git a/test/CodeGen/AArch64/build-vector-extract.ll b/test/CodeGen/AArch64/build-vector-extract.ll new file mode 100644 index 000000000000..a785533e8db9 --- /dev/null +++ b/test/CodeGen/AArch64/build-vector-extract.ll @@ -0,0 +1,441 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s + +define <2 x i64> @extract0_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: zip1 v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov w8, s0 +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: zip1 v0.4s, v0.4s, v0.4s +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #12 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[1] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 v0.4s, v0.4s, v0.4s +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #12 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[2] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #12 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[3] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: zip1 v1.4s, v0.4s, v1.4s +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov w8, s0 +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8 +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #4 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[1] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: mov v0.s[3], wzr +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[2] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #4 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[3] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +; This would crash because we did not expect to create +; a shuffle for a vector where the source operand is +; not the same size as the result. +; TODO: Should we handle this pattern? Ie, is moving to/from +; registers the optimal code? + +define <4 x i32> @larger_bv_than_source(<4 x i16> %t0) { +; CHECK-LABEL: larger_bv_than_source: +; CHECK: // %bb.0: +; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: ret + %t1 = extractelement <4 x i16> %t0, i32 2 + %vgetq_lane = zext i16 %t1 to i32 + %t2 = insertelement <4 x i32> undef, i32 %vgetq_lane, i64 0 + ret <4 x i32> %t2 +} + diff --git a/test/CodeGen/AArch64/eh_recoverfp.ll b/test/CodeGen/AArch64/eh_recoverfp.ll new file mode 100644 index 000000000000..777bcee54382 --- /dev/null +++ b/test/CodeGen/AArch64/eh_recoverfp.ll @@ -0,0 +1,11 @@ +; RUN: llc -mtriple arm64-windows %s -o - 2>&1 | FileCheck %s + +define i8* @foo(i8* %a) { +; CHECK-LABEL: foo +; CHECK-NOT: llvm.x86.seh.recoverfp + %1 = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @f to i8*), i8* %a) + ret i8* %1 +} + +declare i8* @llvm.x86.seh.recoverfp(i8*, i8*) +declare i32 @f() diff --git a/test/CodeGen/AArch64/speculation-hardening-loads.ll b/test/CodeGen/AArch64/speculation-hardening-loads.ll index 0b8f8d31b316..e90fb19a522a 100644 --- a/test/CodeGen/AArch64/speculation-hardening-loads.ll +++ b/test/CodeGen/AArch64/speculation-hardening-loads.ll @@ -11,10 +11,10 @@ entry: ; CHECK-NEXT: and x8, x8, x16 ; CHECK-NEXT: and x1, x1, x16 ; CHECK-NEXT: csdb -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 ; CHECK-NEXT: mov x0, x8 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -29,9 +29,9 @@ entry: ; CHECK-NEXT: and x0, x0, x16 ; CHECK-NEXT: csdb ; CHECK-NEXT: ldr d0, [x0] -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -51,12 +51,12 @@ entry: ; CHECK-NEXT: and x8, x8, x16 ; csdb instruction must occur before the add instruction with w8 as operand. ; CHECK-NEXT: csdb -; CHECK-NEXT: mov x17, sp ; CHECK-NEXT: add w9, w1, w8 ; CHECK-NEXT: cmp x8, #0 -; CHECK-NEXT: and x17, x17, x16 ; CHECK-NEXT: csel w0, w1, w9, eq -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -76,12 +76,12 @@ entry: ; CHECK-NEXT: and w8, w8, w16 ; csdb instruction must occur before the add instruction with x8 as operand. ; CHECK-NEXT: csdb -; CHECK-NEXT: mov x17, sp ; CHECK-NEXT: add x9, x1, x8 ; CHECK-NEXT: cmp w8, #0 -; CHECK-NEXT: and x17, x17, x16 ; CHECK-NEXT: csel x0, x1, x9, eq -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -112,11 +112,11 @@ entry: ; CHECK-NEXT: and x1, x1, x16 ; CHECK-NEXT: csdb ; CHECK-NEXT: ldr d0, [x1] -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 ; CHECK-NEXT: mov v0.d[1], v0.d[0] ; CHECK-NEXT: str q0, [x0] -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -129,9 +129,9 @@ entry: ; CHECK-NEXT: and x1, x1, x16 ; CHECK-NEXT: csdb ; CHECK-NEXT: ld1 { v0.d }[0], [x1] -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret %0 = load double, double* %b, align 16 %vld1_lane = insertelement <2 x double> , double %0, i32 0 @@ -147,9 +147,9 @@ entry: ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: ldr w8, [sp, #12] ; CHECK-NEXT: add sp, sp, #16 -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret %a = alloca i32, align 4 %val = load volatile i32, i32* %a, align 4 diff --git a/test/CodeGen/AArch64/speculation-hardening.ll b/test/CodeGen/AArch64/speculation-hardening.ll index 3535b63c32cc..51156f68dec8 100644 --- a/test/CodeGen/AArch64/speculation-hardening.ll +++ b/test/CodeGen/AArch64/speculation-hardening.ll @@ -1,9 +1,9 @@ -; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,SLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,NOSLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,SLH --dump-input-on-failure -; RUN sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,NOSLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,SLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,NOSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,SLH,NOGISELSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,NOSLH,NOGISELNOSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,SLH,GISELSLH --dump-input-on-failure +; RUN sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,NOSLH,GISELNOSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,SLH,NOGISELSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,NOSLH,NOGISELNOSLH --dump-input-on-failure define i32 @f(i8* nocapture readonly %p, i32 %i, i32 %N) local_unnamed_addr SLHATTR { ; CHECK-LABEL: f @@ -13,12 +13,12 @@ entry: ; NOSLH-NOT: cmp sp, #0 ; NOSLH-NOT: csetm x16, ne -; SLH: mov x17, sp -; SLH: and x17, x17, x16 -; SLH: mov sp, x17 -; NOSLH-NOT: mov x17, sp -; NOSLH-NOT: and x17, x17, x16 -; NOSLH-NOT: mov sp, x17 +; SLH: mov [[TMPREG:x[0-9]+]], sp +; SLH: and [[TMPREG]], [[TMPREG]], x16 +; SLH: mov sp, [[TMPREG]] +; NOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; NOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; NOSLH-NOT: mov sp, [[TMPREG]] %call = tail call i32 @tail_callee(i32 %i) ; SLH: cmp sp, #0 ; SLH: csetm x16, ne @@ -43,29 +43,37 @@ if.then: ; preds = %entry ; NOSLH-NOT: csel x16, x16, xzr, [[COND]] return: ; preds = %entry, %if.then %retval.0 = phi i32 [ %conv, %if.then ], [ 0, %entry ] -; SLH: mov x17, sp -; SLH: and x17, x17, x16 -; SLH: mov sp, x17 -; NOSLH-NOT: mov x17, sp -; NOSLH-NOT: and x17, x17, x16 -; NOSLH-NOT: mov sp, x17 +; SLH: mov [[TMPREG:x[0-9]+]], sp +; SLH: and [[TMPREG]], [[TMPREG]], x16 +; SLH: mov sp, [[TMPREG]] +; NOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; NOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; NOSLH-NOT: mov sp, [[TMPREG]] ret i32 %retval.0 } ; Make sure that for a tail call, taint doesn't get put into SP twice. define i32 @tail_caller(i32 %a) local_unnamed_addr SLHATTR { ; CHECK-LABEL: tail_caller: -; SLH: mov x17, sp -; SLH: and x17, x17, x16 -; SLH: mov sp, x17 -; NOSLH-NOT: mov x17, sp -; NOSLH-NOT: and x17, x17, x16 -; NOSLH-NOT: mov sp, x17 +; NOGISELSLH: mov [[TMPREG:x[0-9]+]], sp +; NOGISELSLH: and [[TMPREG]], [[TMPREG]], x16 +; NOGISELSLH: mov sp, [[TMPREG]] +; NOGISELNOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; NOGISELNOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; NOGISELNOSLH-NOT: mov sp, [[TMPREG]] +; GISELSLH: mov [[TMPREG:x[0-9]+]], sp +; GISELSLH: and [[TMPREG]], [[TMPREG]], x16 +; GISELSLH: mov sp, [[TMPREG]] +; GISELNOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; GISELNOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; GISELNOSLH-NOT: mov sp, [[TMPREG]] ; GlobalISel doesn't optimize tail calls (yet?), so only check that ; cross-call taint register setup code is missing if a tail call was ; actually produced. -; SLH: {{(bl tail_callee[[:space:]] cmp sp, #0)|(b tail_callee)}} -; SLH-NOT: cmp sp, #0 +; NOGISELSLH: b tail_callee +; GISELSLH: bl tail_callee +; GISELSLH: cmp sp, #0 +; SLH-NOT: cmp sp, #0 %call = tail call i32 @tail_callee(i32 %a) ret i32 %call } diff --git a/test/CodeGen/AArch64/speculation-hardening.mir b/test/CodeGen/AArch64/speculation-hardening.mir index cf8357d9558b..5991c4df0407 100644 --- a/test/CodeGen/AArch64/speculation-hardening.mir +++ b/test/CodeGen/AArch64/speculation-hardening.mir @@ -25,6 +25,22 @@ define void @indirectbranch(i32 %a, i32 %b) speculative_load_hardening { ret void } + ; Also check that a non-default temporary register gets picked correctly to + ; transfer the SP to to and it with the taint register when the default + ; temporary isn't available. + define void @indirect_call_x17(i32 %a, i32 %b) speculative_load_hardening { + ret void + } + @g = common dso_local local_unnamed_addr global i64 (...)* null, align 8 + define void @indirect_tailcall_x17(i32 %a, i32 %b) speculative_load_hardening { + ret void + } + define void @indirect_call_lr(i32 %a, i32 %b) speculative_load_hardening { + ret void + } + define void @RS_cannot_find_available_regs() speculative_load_hardening { + ret void + } ... --- name: nobranch_fallthrough @@ -115,3 +131,72 @@ body: | ; CHECK-NOT: csel RET undef $lr, implicit $x0 ... +--- +name: indirect_call_x17 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x17 + ; CHECK-LABEL: indirect_call_x17 + ; CHECK: mov x0, sp + ; CHECK: and x0, x0, x16 + ; CHECK: mov sp, x0 + ; CHECK: blr x17 + BLR killed renamable $x17, implicit-def dead $lr, implicit $sp + RET undef $lr, implicit undef $w0 +... +--- +name: indirect_tailcall_x17 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: indirect_tailcall_x17 + ; CHECK: mov x1, sp + ; CHECK: and x1, x1, x16 + ; CHECK: mov sp, x1 + ; CHECK: br x17 + $x8 = ADRP target-flags(aarch64-page) @g + $x17 = LDRXui killed $x8, target-flags(aarch64-pageoff, aarch64-nc) @g + TCRETURNri killed $x17, 0, implicit $sp, implicit $x0 +... +--- +name: indirect_call_lr +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: indirect_call_lr + ; CHECK: mov x1, sp + ; CHECK-NEXT: and x1, x1, x16 + ; CHECK-NEXT: mov sp, x1 + ; CHECK-NEXT: blr x30 + liveins: $x0, $lr + BLR killed renamable $lr, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 + $w0 = nsw ADDWri killed $w0, 1, 0 + RET undef $lr, implicit $w0 +... +--- +name: RS_cannot_find_available_regs +tracksRegLiveness: true +body: | + bb.0: + ; In the rare case when no free temporary register is available for the + ; propagate taint-to-sp operation, just put in a full speculation barrier + ; (isb+dsb sy) at the start of the basic block. And don't put masks on + ; instructions for the rest of the basic block, since speculation in that + ; basic block was already done, so no need to do masking. + ; CHECK-LABEL: RS_cannot_find_available_regs + ; CHECK: dsb sy + ; CHECK-NEXT: isb + ; CHECK-NEXT: ldr x0, [x0] + ; The following 2 instructions come from propagating the taint encoded in + ; sp at function entry to x16. It turns out the taint info in x16 is not + ; used in this function, so those instructions could be optimized away. An + ; optimization for later if it turns out this situation occurs often enough. + ; CHECK-NEXT: cmp sp, #0 + ; CHECK-NEXT: csetm x16, ne + ; CHECK-NEXT: ret + liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp, $lr + $x0 = LDRXui killed $x0, 0 + RET undef $lr, implicit $x0 +... diff --git a/test/CodeGen/Mips/cconv/vector.ll b/test/CodeGen/Mips/cconv/vector.ll index 6a07c4f34564..5c7c3f424c38 100644 --- a/test/CodeGen/Mips/cconv/vector.ll +++ b/test/CodeGen/Mips/cconv/vector.ll @@ -1,12 +1,12 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips-unknown-linux-gnu -mcpu=mips32 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32,MIPS32EB -; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EB +; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EB ; RUN: llc < %s -mtriple=mips-unknown-linux-gnu -mcpu=mips32r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32R5,MIPS32R5EB -; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EB +; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EB ; RUN: llc < %s -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32,MIPS32EL -; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EL +; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EL ; RUN: llc < %s -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32R5,MIPS32R5EL -; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EL +; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EL ; Test that vector types are passed through the integer register set whether or ; not MSA is enabled. This is a ABI requirement for MIPS. For GCC compatibility diff --git a/test/CodeGen/Mips/gprestore.ll b/test/CodeGen/Mips/gprestore.ll index 88ac047b6609..a1e696b0ac08 100644 --- a/test/CodeGen/Mips/gprestore.ll +++ b/test/CodeGen/Mips/gprestore.ll @@ -1,10 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic | FileCheck %s --check-prefix=O32 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic | FileCheck %s --check-prefix=N64 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 | FileCheck %s --check-prefix=N32 -; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -O3 | FileCheck %s --check-prefix=O3O32 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -O3 | FileCheck %s --check-prefix=O3N64 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -O3 | FileCheck %s --check-prefix=O3N32 +; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -mips-jalr-reloc=false | FileCheck %s --check-prefix=O32 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -mips-jalr-reloc=false | FileCheck %s --check-prefix=N64 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -mips-jalr-reloc=false | FileCheck %s --check-prefix=N32 +; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3O32 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3N64 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3N32 ; Test that PIC calls use the $25 register. This is an ABI requirement. diff --git a/test/CodeGen/Mips/llvm-ir/sdiv.ll b/test/CodeGen/Mips/llvm-ir/sdiv.ll index e54eaa63222a..af3d4f50f3fe 100644 --- a/test/CodeGen/Mips/llvm-ir/sdiv.ll +++ b/test/CodeGen/Mips/llvm-ir/sdiv.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define signext i1 @sdiv_i1(i1 signext %a, i1 signext %b) { ; GP32-LABEL: sdiv_i1: diff --git a/test/CodeGen/Mips/llvm-ir/srem.ll b/test/CodeGen/Mips/llvm-ir/srem.ll index ef0502c85d59..487a5b9b6cbc 100644 --- a/test/CodeGen/Mips/llvm-ir/srem.ll +++ b/test/CodeGen/Mips/llvm-ir/srem.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define signext i1 @srem_i1(i1 signext %a, i1 signext %b) { ; GP32-LABEL: srem_i1: diff --git a/test/CodeGen/Mips/llvm-ir/udiv.ll b/test/CodeGen/Mips/llvm-ir/udiv.ll index 8694a9f92b65..3b7243712024 100644 --- a/test/CodeGen/Mips/llvm-ir/udiv.ll +++ b/test/CodeGen/Mips/llvm-ir/udiv.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R1 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R1 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R2 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define zeroext i1 @udiv_i1(i1 zeroext %a, i1 zeroext %b) { ; GP32-LABEL: udiv_i1: diff --git a/test/CodeGen/Mips/llvm-ir/urem.ll b/test/CodeGen/Mips/llvm-ir/urem.ll index b744f706cbf9..4105d67da6f1 100644 --- a/test/CodeGen/Mips/llvm-ir/urem.ll +++ b/test/CodeGen/Mips/llvm-ir/urem.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define signext i1 @urem_i1(i1 signext %a, i1 signext %b) { ; GP32-LABEL: urem_i1: diff --git a/test/CodeGen/Mips/long-call-attr.ll b/test/CodeGen/Mips/long-call-attr.ll index 5b6ba94aaa35..beda290a9725 100644 --- a/test/CodeGen/Mips/long-call-attr.ll +++ b/test/CodeGen/Mips/long-call-attr.ll @@ -1,11 +1,11 @@ ; RUN: llc -march=mips -target-abi o32 --mattr=+long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=O32 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=O32 %s ; RUN: llc -march=mips -target-abi o32 --mattr=-long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=O32 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=O32 %s ; RUN: llc -march=mips64 -target-abi n64 --mattr=+long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=N64 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=N64 %s ; RUN: llc -march=mips64 -target-abi n64 --mattr=-long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=N64 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=N64 %s declare void @far() #0 diff --git a/test/CodeGen/Mips/long-call-mcount.ll b/test/CodeGen/Mips/long-call-mcount.ll index 70a4410d060b..580f452526f7 100644 --- a/test/CodeGen/Mips/long-call-mcount.ll +++ b/test/CodeGen/Mips/long-call-mcount.ll @@ -1,8 +1,8 @@ ; Check call to mcount in case of long/short call options. ; RUN: llc -march=mips -target-abi o32 --mattr=+long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefixes=CHECK,LONG %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefixes=CHECK,LONG %s ; RUN: llc -march=mips -target-abi o32 --mattr=-long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefixes=CHECK,SHORT %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefixes=CHECK,SHORT %s ; Function Attrs: noinline nounwind optnone define void @foo() #0 { diff --git a/test/CodeGen/Mips/msa/f16-llvm-ir.ll b/test/CodeGen/Mips/msa/f16-llvm-ir.ll index 9105e9249d4f..8544a75c50a6 100644 --- a/test/CodeGen/Mips/msa/f16-llvm-ir.ll +++ b/test/CodeGen/Mips/msa/f16-llvm-ir.ll @@ -1,22 +1,22 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -relocation-model=pic -mtriple=mipsel-- -mcpu=mips32r5 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS32,MIPSR5,MIPS32-O32,MIPS32R5-O32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r5 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR5,MIPS64-N32,MIPS64R5-N32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r5 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR5,MIPS64-N64,MIPS64R5-N64 ; RUN: llc -relocation-model=pic -mtriple=mipsel-- -mcpu=mips32r6 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS32,MIPSR6,MIPSR6-O32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r6 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR6,MIPS64-N32,MIPSR6-N32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r6 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR6,MIPS64-N64,MIPSR6-N64 diff --git a/test/CodeGen/Mips/o32_cc_byval.ll b/test/CodeGen/Mips/o32_cc_byval.ll index 19eb80b79baf..d9951ebeaf3a 100644 --- a/test/CodeGen/Mips/o32_cc_byval.ll +++ b/test/CodeGen/Mips/o32_cc_byval.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=pic < %s | FileCheck %s +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=pic \ +; RUN: -mips-jalr-reloc=false < %s | FileCheck %s %0 = type { i8, i16, i32, i64, double, i32, [4 x i8] } %struct.S1 = type { i8, i16, i32, i64, double, i32 } diff --git a/test/CodeGen/Mips/reloc-jalr.ll b/test/CodeGen/Mips/reloc-jalr.ll new file mode 100644 index 000000000000..f8fd90311004 --- /dev/null +++ b/test/CodeGen/Mips/reloc-jalr.ll @@ -0,0 +1,154 @@ +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2,TAILCALL-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2,TAILCALL-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips32r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R6,TAILCALL-32R6 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips64r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R6,TAILCALL-64R6 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips32r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2,TAILCALL-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips64r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2,TAILCALL-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mattr=+micromips -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM,TAILCALL-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mattr=+micromips -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips32r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R6 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips64r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R6 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips32r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips64r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mattr=+micromips -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mattr=+micromips -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static -mips-tail-calls=1 \ +; RUN: -O2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O0 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static -mips-tail-calls=1 \ +; RUN: -O0 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -mips-tail-calls=1 \ +; RUN: -O2 -relocation-model=static < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static \ +; RUN: -O0 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +define internal void @foo() noinline { +entry: + ret void +} + +define void @checkCall() { +entry: +; ALL-LABEL: checkCall: + call void @foo() +; JALR-32R2: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; JALR-32R2-NEXT: [[TMPLABEL]]: +; JALR-32R2-NEXT: jalr $25 + +; JALR-64R2: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; JALR-64R2-NEXT: [[TMPLABEL]]: +; JALR-64R2-NEXT: jalr $25 + +; JALR-MM: .reloc ([[TMPLABEL:.*]]), R_MICROMIPS_JALR, foo +; JALR-MM-NEXT: [[TMPLABEL]]: +; JALR-MM-NEXT: jalr $25 + +; JALR-32R6: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; JALR-32R6-NEXT: [[TMPLABEL]]: +; JALR-32R6-NEXT: jalrc $25 + +; JALR-64R6: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; JALR-64R6-NEXT: [[TMPLABEL]]: +; JALR-64R6-NEXT: jalrc $25 + +; NORELOC-NOT: R_MIPS_JALR + ret void +} + +define void @checkTailCall() { +entry: +; ALL-LABEL: checkTailCall: + tail call void @foo() +; TAILCALL-32R2: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; TAILCALL-32R2-NEXT: [[TMPLABEL]]: +; TAILCALL-32R2-NEXT: jr $25 + +; TAILCALL-64R2: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; TAILCALL-64R2-NEXT: [[TMPLABEL]]: +; TAILCALL-64R2-NEXT: jr $25 + +; TAILCALL-MM: .reloc ([[TMPLABEL:.*]]), R_MICROMIPS_JALR, foo +; TAILCALL-MM-NEXT: [[TMPLABEL]]: +; TAILCALL-MM-NEXT: jrc $25 + +; TAILCALL-32R6: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; TAILCALL-32R6-NEXT: [[TMPLABEL]]: +; TAILCALL-32R6-NEXT: jrc $25 + +; TAILCALL-64R6: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; TAILCALL-64R6-NEXT: [[TMPLABEL]]: +; TAILCALL-64R6-NEXT: jrc $25 + +; NORELOC-NOT: R_MIPS_JALR + ret void +} diff --git a/test/CodeGen/Mips/shrink-wrapping.ll b/test/CodeGen/Mips/shrink-wrapping.ll index 54ae8699d1c1..b08d2f1b6467 100644 --- a/test/CodeGen/Mips/shrink-wrapping.ll +++ b/test/CodeGen/Mips/shrink-wrapping.ll @@ -9,11 +9,11 @@ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-STATIC ; RUN: llc -mtriple=mips-unknown-linux-gnu -enable-shrink-wrap=true \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=SHRINK-WRAP-PIC ; RUN: llc -mtriple=mips-unknown-linux-gnu -enable-shrink-wrap=false \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-PIC ; RUN: llc -mtriple=mips64-unknown-linux-gnu -enable-shrink-wrap=true \ @@ -25,11 +25,11 @@ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-64-STATIC ; RUN: llc -mtriple=mips64-unknown-linux-gnu -enable-shrink-wrap=true \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=SHRINK-WRAP-64-PIC ; RUN: llc -mtriple=mips64-unknown-linux-gnu -enable-shrink-wrap=false \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-64-PIC declare void @f(i32 signext) diff --git a/test/CodeGen/X86/debug-loclists.ll b/test/CodeGen/X86/debug-loclists.ll index 20bc0c40378b..0c2ab3dfad5a 100644 --- a/test/CodeGen/X86/debug-loclists.ll +++ b/test/CodeGen/X86/debug-loclists.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0040 => {0x00000040} "A") ; CHECK: .debug_loclists contents: -; CHECK-NEXT: 0x00000000: locations list header: length = 0x00000017, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +; CHECK-NEXT: 0x00000000: locations list header: length = 0x00000015, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 ; CHECK-NEXT: 0x00000000: ; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004): DW_OP_breg5 RDI+0 ; CHECK-NEXT: [0x0000000000000004, 0x0000000000000012): DW_OP_breg3 RBX+0 @@ -32,13 +32,13 @@ ; ASM-NEXT: .byte 4 # DW_LLE_offset_pair ; ASM-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset ; ASM-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # ending offset -; ASM-NEXT: .short 2 # Loc expr size +; ASM-NEXT: .byte 2 # Loc expr size ; ASM-NEXT: .byte 117 # DW_OP_breg5 ; ASM-NEXT: .byte 0 # 0 ; ASM-NEXT: .byte 4 # DW_LLE_offset_pair ; ASM-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # starting offset ; ASM-NEXT: .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset -; ASM-NEXT: .short 2 # Loc expr size +; ASM-NEXT: .byte 2 # Loc expr size ; ASM-NEXT: .byte 115 # DW_OP_breg3 ; ASM-NEXT: .byte 0 # 0 ; ASM-NEXT: .byte 0 # DW_LLE_end_of_list diff --git a/test/CodeGen/X86/discriminate-mem-ops.ll b/test/CodeGen/X86/discriminate-mem-ops.ll index b77a91fafd2c..a30dc22a0d9c 100644 --- a/test/CodeGen/X86/discriminate-mem-ops.ll +++ b/test/CodeGen/X86/discriminate-mem-ops.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc -x86-discriminate-memops < %s | FileCheck %s ; ; original source, compiled with -O3 -gmlt -fdebug-info-for-profiling: ; int sum(int* arr, int pos1, int pos2) { diff --git a/test/CodeGen/X86/insert-prefetch-inline.ll b/test/CodeGen/X86/insert-prefetch-inline.ll index 5f8373f9480c..62c02fa33291 100644 --- a/test/CodeGen/X86/insert-prefetch-inline.ll +++ b/test/CodeGen/X86/insert-prefetch-inline.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch-inline.afdo | FileCheck %s +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch-inline.afdo | FileCheck %s ; ; Verify we can insert prefetch instructions in code belonging to inlined ; functions. diff --git a/test/CodeGen/X86/insert-prefetch-invalid-instr.ll b/test/CodeGen/X86/insert-prefetch-invalid-instr.ll index 004fb56a56eb..d0c4ac378b63 100644 --- a/test/CodeGen/X86/insert-prefetch-invalid-instr.ll +++ b/test/CodeGen/X86/insert-prefetch-invalid-instr.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch-invalid-instr.afdo | FileCheck %s +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch-invalid-instr.afdo | FileCheck %s ; ModuleID = 'prefetch.cc' source_filename = "prefetch.cc" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/CodeGen/X86/insert-prefetch.ll b/test/CodeGen/X86/insert-prefetch.ll index 9e77772df774..fe0fd9877f19 100644 --- a/test/CodeGen/X86/insert-prefetch.ll +++ b/test/CodeGen/X86/insert-prefetch.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch.afdo | FileCheck %s -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch-other.afdo | FileCheck %s -check-prefix=OTHERS +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch.afdo | FileCheck %s +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch-other.afdo | FileCheck %s -check-prefix=OTHERS ; ; original source, compiled with -O3 -gmlt -fdebug-info-for-profiling: ; int sum(int* arr, int pos1, int pos2) { diff --git a/test/DebugInfo/COFF/types-empty-member-fn.ll b/test/DebugInfo/COFF/types-empty-member-fn.ll new file mode 100644 index 000000000000..87cba9d62099 --- /dev/null +++ b/test/DebugInfo/COFF/types-empty-member-fn.ll @@ -0,0 +1,72 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s + +; ModuleID = 'foo.3a1fbbbh-cgu.0' +source_filename = "foo.3a1fbbbh-cgu.0" +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +; Rust source to regenerate: +; $ cat foo.rs +; pub struct Foo; +; impl Foo { +; pub fn foo() {} +; } +; $ rustc foo.rs --crate-type lib -Cdebuginfo=1 --emit=llvm-ir + +; CHECK: CodeViewTypes [ +; CHECK: MemberFunction (0x1006) { +; CHECK-NEXT: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK-NEXT: ReturnType: void (0x3) +; CHECK-NEXT: ClassType: foo::Foo (0x1000) +; CHECK-NEXT: ThisType: 0x0 +; CHECK-NEXT: CallingConvention: NearC (0x0) +; CHECK-NEXT: FunctionOptions [ (0x0) +; CHECK-NEXT: ] +; CHECK-NEXT: NumParameters: 0 +; CHECK-NEXT: ArgListType: () (0x1005) +; CHECK-NEXT: ThisAdjustment: 0 +; CHECK-NEXT: } +; CHECK-NEXT: MemberFuncId (0x1007) { +; CHECK-NEXT: TypeLeafKind: LF_MFUNC_ID (0x1602) +; CHECK-NEXT: ClassType: foo::Foo (0x1000) +; CHECK-NEXT: FunctionType: void foo::Foo::() (0x1006) +; CHECK-NEXT: Name: foo +; CHECK-NEXT: } +; CHECK: CodeViewDebugInfo [ +; CHECK: FunctionLineTable [ +; CHECK-NEXT: LinkageName: _ZN3foo3Foo3foo17hc557c2121772885bE +; CHECK-NEXT: Flags: 0x0 +; CHECK-NEXT: CodeSize: 0x1 +; CHECK-NEXT: FilenameSegment [ +; CHECK-NEXT: Filename: D:\rust\foo.rs (0x0) +; CHECK-NEXT: +0x0 [ +; CHECK-NEXT: LineNumberStart: 3 +; CHECK-NEXT: LineNumberEndDelta: 0 +; CHECK-NEXT: IsStatement: No +; CHECK-NEXT: ] +; CHECK-NEXT: ] +; CHECK-NEXT: ] + +; foo::Foo::foo +; Function Attrs: uwtable +define void @_ZN3foo3Foo3foo17hc557c2121772885bE() unnamed_addr #0 !dbg !5 { +start: + ret void, !dbg !10 +} + +attributes #0 = { uwtable "target-cpu"="x86-64" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.33.0-nightly (8b0f0156e 2019-01-22))", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2) +!1 = !DIFile(filename: "foo.rs", directory: "D:\5Crust") +!2 = !{} +!3 = !{i32 2, !"CodeView", i32 1} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = distinct !DISubprogram(name: "foo", linkageName: "_ZN3foo3Foo3foo17hc557c2121772885bE", scope: !6, file: !1, line: 3, type: !9, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, templateParams: !2, retainedNodes: !2) +!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", scope: !8, file: !7, align: 8, elements: !2, templateParams: !2, identifier: "5105d9fe1a2a3c68518268151b672274") +!7 = !DIFile(filename: "", directory: "") +!8 = !DINamespace(name: "foo", scope: null) +!9 = !DISubroutineType(types: !2) +!10 = !DILocation(line: 3, scope: !5) diff --git a/test/DebugInfo/Mips/dwarfdump-tls.ll b/test/DebugInfo/Mips/dwarfdump-tls.ll index 6aa429adb417..8d8af8c5124a 100644 --- a/test/DebugInfo/Mips/dwarfdump-tls.ll +++ b/test/DebugInfo/Mips/dwarfdump-tls.ll @@ -1,12 +1,34 @@ -; RUN: llc -O0 -march=mips -mcpu=mips32r2 -filetype=obj -o=%t-32.o < %s +; RUN: llc -O0 -march=mips -mcpu=mips32r2 -filetype=obj \ +; RUN: -split-dwarf-file=foo.dwo -o=%t-32.o < %s ; RUN: llvm-dwarfdump %t-32.o 2>&1 | FileCheck %s -; RUN: llc -O0 -march=mips64 -mcpu=mips64r2 -filetype=obj -o=%t-64.o < %s +; RUN: llc -O0 -march=mips64 -mcpu=mips64r2 -filetype=obj \ +; RUN: -split-dwarf-file=foo.dwo -o=%t-64.o < %s ; RUN: llvm-dwarfdump %t-64.o 2>&1 | FileCheck %s +; RUN: llc -O0 -march=mips -mcpu=mips32r2 -filetype=asm \ +; RUN: -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM32 %s +; RUN: llc -O0 -march=mips64 -mcpu=mips64r2 -filetype=asm \ +; RUN: -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM64 %s + @x = thread_local global i32 5, align 4, !dbg !0 ; CHECK-NOT: error: failed to compute relocation: R_MIPS_TLS_DTPREL +; CHECK: DW_AT_name ("x") +; CHECK-NEXT: DW_AT_type (0x00000025 "int") +; CHECK-NEXT: DW_AT_external (true) +; CHECK-NEXT: DW_AT_decl_file (0x01) +; CHECK-NEXT: DW_AT_decl_line (1) +; CHECK-NEXT: DW_AT_location (DW_OP_GNU_const_index 0x0, {{DW_OP_GNU_push_tls_address|DW_OP_form_tls_address}}) + +; ASM32: .section .debug_addr +; ASM32-NEXT: $addr_table_base0: +; ASM32-NEXT: .4byte x+32768 + +; ASM64: .section .debug_addr +; ASM64-NEXT: .Laddr_table_base0: +; ASM64-NEXT: .8byte x+32768 + !llvm.dbg.cu = !{!2} !llvm.module.flags = !{!7, !8} diff --git a/test/DebugInfo/X86/dwarfdump-debug-loclists.test b/test/DebugInfo/X86/dwarfdump-debug-loclists.test index 669607fe557a..32f2482b5117 100644 --- a/test/DebugInfo/X86/dwarfdump-debug-loclists.test +++ b/test/DebugInfo/X86/dwarfdump-debug-loclists.test @@ -9,7 +9,7 @@ # CHECK-NEXT: [0x0000000000000700, 0x0000000000000710): DW_OP_breg5 RDI+0 # CHECK: .debug_loclists contents: -# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000002f, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000002c, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 # CHECK-NEXT: 0x00000000: # CHECK-NEXT: [0x0000000000000000, 0x0000000000000010): DW_OP_breg5 RDI+0 # CHECK-NEXT: [0x0000000000000530, 0x0000000000000540): DW_OP_breg6 RBP-8, DW_OP_deref @@ -37,7 +37,7 @@ .byte 4 # DW_LLE_offset_pair .uleb128 0x0 # starting offset .uleb128 0x10 # ending offset - .short 2 # Loc expr size + .byte 2 # Loc expr size .byte 117 # DW_OP_breg5 .byte 0 # 0 @@ -47,7 +47,7 @@ .byte 4 # DW_LLE_offset_pair .uleb128 0x30 # starting offset .uleb128 0x40 # ending offset - .short 3 # Loc expr size + .byte 3 # Loc expr size .byte 118 # DW_OP_breg6 .byte 120 # -8 .byte 6 # DW_OP_deref @@ -55,7 +55,7 @@ .byte 8 # DW_LLE_start_length .quad 0x700 # Some address .uleb128 0x10 # length - .short 2 # Loc expr size + .byte 2 # Loc expr size .byte 117 # DW_OP_breg5 .byte 0 # 0 diff --git a/test/Transforms/FunctionImport/Inputs/comdat.ll b/test/Transforms/FunctionImport/Inputs/comdat.ll new file mode 100644 index 000000000000..1df6f25351e5 --- /dev/null +++ b/test/Transforms/FunctionImport/Inputs/comdat.ll @@ -0,0 +1,10 @@ +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +define void @main() { +entry: + call i8* @lwt_fun() + ret void +} + +declare i8* @lwt_fun() diff --git a/test/Transforms/FunctionImport/comdat.ll b/test/Transforms/FunctionImport/comdat.ll new file mode 100644 index 000000000000..29e8cb538ab6 --- /dev/null +++ b/test/Transforms/FunctionImport/comdat.ll @@ -0,0 +1,32 @@ +; Test to ensure that comdat is renamed consistently when comdat leader is +; promoted and renamed due to an import. Required by COFF. + +; REQUIRES: x86-registered-target + +; RUN: opt -thinlto-bc -o %t1.bc %s +; RUN: opt -thinlto-bc -o %t2.bc %S/Inputs/comdat.ll +; RUN: llvm-lto2 run -save-temps -o %t3 %t1.bc %t2.bc \ +; RUN: -r %t1.bc,lwt_fun,plx \ +; RUN: -r %t2.bc,main,plx \ +; RUN: -r %t2.bc,lwt_fun, +; RUN: llvm-dis -o - %t3.1.3.import.bc | FileCheck %s + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +; CHECK: $lwt.llvm.[[HASH:[0-9]+]] = comdat any +$lwt = comdat any + +; CHECK: @lwt_aliasee = private unnamed_addr global {{.*}}, comdat($lwt.llvm.[[HASH]]) +@lwt_aliasee = private unnamed_addr global [1 x i8*] [i8* null], comdat($lwt) + +; CHECK: @lwt.llvm.[[HASH]] = hidden unnamed_addr alias +@lwt = internal unnamed_addr alias [1 x i8*], [1 x i8*]* @lwt_aliasee + +; Below function should get imported into other module, resulting in @lwt being +; promoted and renamed. +define i8* @lwt_fun() { + %1 = getelementptr inbounds [1 x i8*], [1 x i8*]* @lwt, i32 0, i32 0 + %2 = load i8*, i8** %1 + ret i8* %2 +} diff --git a/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll b/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll new file mode 100644 index 000000000000..77d09ad53f78 --- /dev/null +++ b/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll @@ -0,0 +1,33 @@ +; RUN: opt -transform-warning -disable-output < %s 2>&1 | FileCheck -allow-empty %s +; +; llvm.org/PR40546 +; Do not warn about about leftover llvm.loop.vectorize.enable for already +; vectorized loops. + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" + +define void @test(i32 %n) { +entry: + %cmp = icmp eq i32 %n, 0 + br i1 %cmp, label %simd.if.end, label %omp.inner.for.body.preheader + +omp.inner.for.body.preheader: + %wide.trip.count = zext i32 %n to i64 + br label %omp.inner.for.body + +omp.inner.for.body: + %indvars.iv = phi i64 [ 0, %omp.inner.for.body.preheader ], [ %indvars.iv.next, %omp.inner.for.body ] + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count + br i1 %exitcond, label %simd.if.end, label %omp.inner.for.body, !llvm.loop !0 + +simd.if.end: + ret void +} + +!0 = distinct !{!0, !1, !2} +!1 = !{!"llvm.loop.vectorize.enable", i1 true} +!2 = !{!"llvm.loop.isvectorized"} + + +; CHECK-NOT: loop not vectorized diff --git a/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll b/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll new file mode 100644 index 000000000000..424ef3846224 --- /dev/null +++ b/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll @@ -0,0 +1,95 @@ +; RUN: opt < %s -loop-vectorize -force-vector-width=4 -transform-warning -S 2>&1 | FileCheck %s +; RUN: opt < %s -loop-vectorize -force-vector-width=1 -transform-warning -S 2>&1 | FileCheck %s -check-prefix=NOANALYSIS +; RUN: opt < %s -loop-vectorize -force-vector-width=4 -transform-warning -pass-remarks-missed='loop-vectorize' -S 2>&1 | FileCheck %s -check-prefix=MOREINFO + +; This test is a copy of no_switch.ll, with the "llvm.loop.vectorize.enable" metadata set to false. +; It tests that vectorization is explicitly disabled and no warnings are emitted. + +; CHECK-NOT: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement +; CHECK-NOT: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering + +; NOANALYSIS-NOT: remark: {{.*}} +; NOANALYSIS-NOT: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering + +; MOREINFO: remark: source.cpp:4:5: loop not vectorized: vectorization is explicitly disabled +; MOREINFO-NOT: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering + +; CHECK: _Z11test_switchPii +; CHECK-NOT: x i32> +; CHECK: ret + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: nounwind optsize ssp uwtable +define void @_Z11test_switchPii(i32* nocapture %A, i32 %Length) #0 !dbg !4 { +entry: + %cmp18 = icmp sgt i32 %Length, 0, !dbg !10 + br i1 %cmp18, label %for.body.preheader, label %for.end, !dbg !10, !llvm.loop !12 + +for.body.preheader: ; preds = %entry + br label %for.body, !dbg !14 + +for.body: ; preds = %for.body.preheader, %for.inc + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %for.body.preheader ] + %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv, !dbg !14 + %0 = load i32, i32* %arrayidx, align 4, !dbg !14, !tbaa !16 + switch i32 %0, label %for.inc [ + i32 0, label %sw.bb + i32 1, label %sw.bb3 + ], !dbg !14 + +sw.bb: ; preds = %for.body + %1 = trunc i64 %indvars.iv to i32, !dbg !20 + %mul = shl nsw i32 %1, 1, !dbg !20 + br label %for.inc, !dbg !22 + +sw.bb3: ; preds = %for.body + %2 = trunc i64 %indvars.iv to i32, !dbg !23 + store i32 %2, i32* %arrayidx, align 4, !dbg !23, !tbaa !16 + br label %for.inc, !dbg !23 + +for.inc: ; preds = %sw.bb3, %for.body, %sw.bb + %storemerge = phi i32 [ %mul, %sw.bb ], [ 0, %for.body ], [ 0, %sw.bb3 ] + store i32 %storemerge, i32* %arrayidx, align 4, !dbg !20, !tbaa !16 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !10 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32, !dbg !10 + %exitcond = icmp eq i32 %lftr.wideiv, %Length, !dbg !10 + br i1 %exitcond, label %for.end.loopexit, label %for.body, !dbg !10, !llvm.loop !12 + +for.end.loopexit: ; preds = %for.inc + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void, !dbg !24 +} + +attributes #0 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0", isOptimized: true, runtimeVersion: 6, emissionKind: LineTablesOnly, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2) +!1 = !DIFile(filename: "source.cpp", directory: ".") +!2 = !{} +!4 = distinct !DISubprogram(name: "test_switch", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !6, retainedNodes: !2) +!5 = !DIFile(filename: "source.cpp", directory: ".") +!6 = !DISubroutineType(types: !2) +!7 = !{i32 2, !"Dwarf Version", i32 2} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 3.5.0"} +!10 = !DILocation(line: 3, column: 8, scope: !11) +!11 = distinct !DILexicalBlock(line: 3, column: 3, file: !1, scope: !4) +!12 = !{!12, !13, !13} +!13 = !{!"llvm.loop.vectorize.enable", i1 false} +!14 = !DILocation(line: 4, column: 5, scope: !15) +!15 = distinct !DILexicalBlock(line: 3, column: 36, file: !1, scope: !11) +!16 = !{!17, !17, i64 0} +!17 = !{!"int", !18, i64 0} +!18 = !{!"omnipotent char", !19, i64 0} +!19 = !{!"Simple C/C++ TBAA"} +!20 = !DILocation(line: 6, column: 7, scope: !21) +!21 = distinct !DILexicalBlock(line: 4, column: 18, file: !1, scope: !15) +!22 = !DILocation(line: 7, column: 5, scope: !21) +!23 = !DILocation(line: 9, column: 7, scope: !21) +!24 = !DILocation(line: 14, column: 1, scope: !4) diff --git a/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s b/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s index 07c68ab2618f..0b2ae5f8e7a4 100644 --- a/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s +++ b/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s @@ -6,7 +6,7 @@ # the final version which uses ULEB128 and not the U32. # CHECK: .debug_loclists contents: -# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000000f, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000000e, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 # CHECK-NEXT: 0x00000000: # CHECK-NEXT: Addr idx 1 (w/ length 16): DW_OP_reg5 RDI @@ -21,7 +21,7 @@ .byte 3 # DW_LLE_startx_length .byte 0x01 # Index .uleb128 0x10 # Length - .short 1 # Loc expr size + .byte 1 # Loc expr size .byte 85 # DW_OP_reg5 .byte 0 # DW_LLE_end_of_list .Ldebug_loclist_table_end0: From d87c9e7da2e87f224c426832f08897269c2e5636 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 5 Feb 2019 18:39:15 +0000 Subject: [PATCH 3/7] Vendor import of clang release_80 branch r353167: https://llvm.org/svn/llvm-project/cfe/branches/release_80@353167 --- docs/LanguageExtensions.rst | 80 +- docs/OpenMPSupport.rst | 82 +- docs/ReleaseNotes.rst | 42 +- include/clang/Basic/BuiltinsAArch64.def | 10 +- include/clang/Basic/Features.def | 2 +- include/clang/Basic/FileManager.h | 5 +- include/clang/Basic/TargetInfo.h | 4 + include/clang/Driver/Options.td | 8 + include/clang/Tooling/ArgumentsAdjusters.h | 4 + lib/Basic/FileManager.cpp | 35 +- lib/Basic/TargetInfo.cpp | 1 + lib/Basic/Targets.cpp | 24 +- lib/Basic/Targets/AArch64.cpp | 1 + lib/Basic/Targets/ARM.cpp | 1 + lib/Basic/Targets/OSTargets.h | 18 +- lib/Basic/Targets/SPIR.h | 1 + lib/Driver/ToolChains/Clang.cpp | 8 + lib/Driver/ToolChains/NetBSD.cpp | 7 + lib/Headers/opencl-c.h | 2 +- lib/Lex/LiteralSupport.cpp | 9 +- lib/Sema/SemaCodeComplete.cpp | 3 +- lib/Sema/SemaDeclCXX.cpp | 7 +- lib/Sema/SemaExpr.cpp | 23 +- lib/Sema/SemaTemplate.cpp | 2 +- lib/Sema/SemaType.cpp | 7 +- lib/Tooling/ArgumentsAdjusters.cpp | 22 + test/AST/float16.cpp | 4 +- test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp | 2 +- test/CodeCompletion/crash-null-type.cpp | 8 + test/CodeGen/arm64-crc32.c | 19 +- test/CodeGen/builtins-arm64.c | 27 +- test/CodeGenCXX/float16-declarations.cpp | 6 - test/CodeGenCXX/mangle-ms.cpp | 5 +- test/CodeGenCXX/trivial_abi.cpp | 19 +- test/CodeGenOpenCL/printf.cl | 20 +- test/Driver/mips-features.c | 12 + test/Lexer/half-literal.cpp | 2 +- test/PCH/leakfiles | 29 + test/Preprocessor/init.c | 982 +++++++----------- test/Sema/Float16.c | 11 + test/SemaCXX/Float16.cpp | 18 + test/SemaCXX/PR40395.cpp | 16 + test/SemaCXX/cxx1z-decomposition.cpp | 17 + test/SemaObjC/enum-fixed-type.m | 2 + .../printf-format-string-warnings.cl | 9 +- test/SemaOpenCL/printf-format-strings.cl | 4 +- unittests/Basic/FileManagerTest.cpp | 27 - unittests/Tooling/ToolingTest.cpp | 31 + 48 files changed, 805 insertions(+), 873 deletions(-) create mode 100644 test/CodeCompletion/crash-null-type.cpp create mode 100644 test/PCH/leakfiles create mode 100644 test/Sema/Float16.c create mode 100644 test/SemaCXX/Float16.cpp create mode 100644 test/SemaCXX/PR40395.cpp diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index e155cefb7890..5782edd35370 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -474,44 +474,58 @@ Half-Precision Floating Point ============================= Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and -``_Float16``. ``__fp16`` is defined in the ARM C Language Extensions (`ACLE -`_) -and ``_Float16`` in ISO/IEC TS 18661-3:2015. +``_Float16``. These types are supported in all language modes. -``__fp16`` is a storage and interchange format only. This means that values of -``__fp16`` promote to (at least) float when used in arithmetic operations. -There are two ``__fp16`` formats. Clang supports the IEEE 754-2008 format and -not the ARM alternative format. +``__fp16`` is supported on every target, as it is purely a storage format; see below. +``_Float16`` is currently only supported on the following targets, with further +targets pending ABI standardization: +- 32-bit ARM +- 64-bit ARM (AArch64) +- SPIR +``_Float16`` will be supported on more targets as they define ABIs for it. -ISO/IEC TS 18661-3:2015 defines C support for additional floating point types. -``_FloatN`` is defined as a binary floating type, where the N suffix denotes -the number of bits and is 16, 32, 64, or greater and equal to 128 and a -multiple of 32. Clang supports ``_Float16``. The difference from ``__fp16`` is -that arithmetic on ``_Float16`` is performed in half-precision, thus it is not -a storage-only format. ``_Float16`` is available as a source language type in -both C and C++ mode. +``__fp16`` is a storage and interchange format only. This means that values of +``__fp16`` are immediately promoted to (at least) ``float`` when used in arithmetic +operations, so that e.g. the result of adding two ``__fp16`` values has type ``float``. +The behavior of ``__fp16`` is specified by the ARM C Language Extensions (`ACLE `_). +Clang uses the ``binary16`` format from IEEE 754-2008 for ``__fp16``, not the ARM +alternative format. -It is recommended that portable code use the ``_Float16`` type because -``__fp16`` is an ARM C-Language Extension (ACLE), whereas ``_Float16`` is -defined by the C standards committee, so using ``_Float16`` will not prevent -code from being ported to architectures other than Arm. Also, ``_Float16`` -arithmetic and operations will directly map on half-precision instructions when -they are available (e.g. Armv8.2-A), avoiding conversions to/from -single-precision, and thus will result in more performant code. If -half-precision instructions are unavailable, values will be promoted to -single-precision, similar to the semantics of ``__fp16`` except that the -results will be stored in single-precision. +``_Float16`` is an extended floating-point type. This means that, just like arithmetic on +``float`` or ``double``, arithmetic on ``_Float16`` operands is formally performed in the +``_Float16`` type, so that e.g. the result of adding two ``_Float16`` values has type +``_Float16``. The behavior of ``_Float16`` is specified by ISO/IEC TS 18661-3:2015 +("Floating-point extensions for C"). As with ``__fp16``, Clang uses the ``binary16`` +format from IEEE 754-2008 for ``_Float16``. -In an arithmetic operation where one operand is of ``__fp16`` type and the -other is of ``_Float16`` type, the ``_Float16`` type is first converted to -``__fp16`` type and then the operation is completed as if both operands were of -``__fp16`` type. +``_Float16`` arithmetic will be performed using native half-precision support +when available on the target (e.g. on ARMv8.2a); otherwise it will be performed +at a higher precision (currently always ``float``) and then truncated down to +``_Float16``. Note that C and C++ allow intermediate floating-point operands +of an expression to be computed with greater precision than is expressible in +their type, so Clang may avoid intermediate truncations in certain cases; this may +lead to results that are inconsistent with native arithmetic. -To define a ``_Float16`` literal, suffix ``f16`` can be appended to the compile-time -constant declaration. There is no default argument promotion for ``_Float16``; this -applies to the standard floating types only. As a consequence, for example, an -explicit cast is required for printing a ``_Float16`` value (there is no string -format specifier for ``_Float16``). +It is recommended that portable code use ``_Float16`` instead of ``__fp16``, +as it has been defined by the C standards committee and has behavior that is +more familiar to most programmers. + +Because ``__fp16`` operands are always immediately promoted to ``float``, the +common real type of ``__fp16`` and ``_Float16`` for the purposes of the usual +arithmetic conversions is ``float``. + +A literal can be given ``_Float16`` type using the suffix ``f16``; for example: +``` +3.14f16 +``` + +Because default argument promotion only applies to the standard floating-point +types, ``_Float16`` values are not promoted to ``double`` when passed as variadic +or untyped arguments. As a consequence, some caution must be taken when using +certain library facilities with ``_Float16``; for example, there is no ``printf`` format +specifier for ``_Float16``, and (unlike ``float``) it will not be implicitly promoted to +``double`` when passed to ``printf``, so the programmer must explicitly cast it to +``double`` before using it with an ``%f`` or similar specifier. Messages on ``deprecated`` and ``unavailable`` Attributes ========================================================= diff --git a/docs/OpenMPSupport.rst b/docs/OpenMPSupport.rst index 04a9648ca294..7b567c966ee5 100644 --- a/docs/OpenMPSupport.rst +++ b/docs/OpenMPSupport.rst @@ -17,60 +17,50 @@ OpenMP Support ================== +Clang supports the following OpenMP 5.0 features + +* The `reduction`-based clauses in the `task` and `target`-based directives. + +* Support relational-op != (not-equal) as one of the canonical forms of random + access iterator. + +* Support for mapping of the lambdas in target regions. + +* Parsing/sema analysis for the requires directive. + +* Nested declare target directives. + +* Make the `this` pointer implicitly mapped as `map(this[:1])`. + +* The `close` *map-type-modifier*. + Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64, PPC64[LE] and has `basic support for Cuda devices`_. -Standalone directives -===================== - -* #pragma omp [for] simd: :good:`Complete`. - * #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic analysis + generation of special attributes for X86 target, but still missing the LLVM pass for vectorization. -* #pragma omp taskloop [simd]: :good:`Complete`. - -* #pragma omp target [enter|exit] data: :good:`Complete`. - -* #pragma omp target update: :good:`Complete`. - -* #pragma omp target: :good:`Complete`. - -* #pragma omp declare target: :good:`Complete`. - -* #pragma omp teams: :good:`Complete`. - -* #pragma omp distribute [simd]: :good:`Complete`. - -* #pragma omp distribute parallel for [simd]: :good:`Complete`. - -Combined directives -=================== - -* #pragma omp parallel for simd: :good:`Complete`. - -* #pragma omp target parallel: :good:`Complete`. - -* #pragma omp target parallel for [simd]: :good:`Complete`. - -* #pragma omp target simd: :good:`Complete`. - -* #pragma omp target teams: :good:`Complete`. - -* #pragma omp teams distribute [simd]: :good:`Complete`. - -* #pragma omp target teams distribute [simd]: :good:`Complete`. - -* #pragma omp teams distribute parallel for [simd]: :good:`Complete`. - -* #pragma omp target teams distribute parallel for [simd]: :good:`Complete`. - -Clang does not support any constructs/updates from OpenMP 5.0 except -for `reduction`-based clauses in the `task` and `target`-based directives. - In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools -Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS. +Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and macOS. + +General improvements +-------------------- +- New collapse clause scheme to avoid expensive remainder operations. + Compute loop index variables after collapsing a loop nest via the + collapse clause by replacing the expensive remainder operation with + multiplications and additions. + +- The default schedules for the `distribute` and `for` constructs in a + parallel region and in SPMD mode have changed to ensure coalesced + accesses. For the `distribute` construct, a static schedule is used + with a chunk size equal to the number of threads per team (default + value of threads or as specified by the `thread_limit` clause if + present). For the `for` construct, the schedule is static with chunk + size of one. + +- Simplified SPMD code generation for `distribute parallel for` when + the new default schedules are applicable. .. _basic support for Cuda devices: diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index b6a405dbc78b..50bf636a51f4 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -127,6 +127,10 @@ Non-comprehensive list of changes in this release manually and rely on the old behaviour you will need to add appropriate compiler flags for finding the corresponding libc++ include directory. +- The integrated assembler is used now by default for all MIPS targets. + +- Improved support for MIPS N32 ABI and MIPS R6 target triples. + New Compiler Flags ------------------ @@ -136,6 +140,13 @@ New Compiler Flags instrumenting for gcov-based profiling. See the :doc:`UsersManual` for details. +- When using a custom stack alignment, the ``stackrealign`` attribute is now + implicitly set on the main function. + +- Emission of ``R_MIPS_JALR`` and ``R_MICROMIPS_JALR`` relocations can now + be controlled by the ``-mrelax-pic-calls`` and ``-mno-relax-pic-calls`` + options. + - ... Deprecated Compiler Flags @@ -179,6 +190,15 @@ Windows Support `dllexport` and `dllimport` attributes not apply to inline member functions. This can significantly reduce compile and link times. See the `User's Manual `_ for more info. + +- For MinGW, ``-municode`` now correctly defines ``UNICODE`` during + preprocessing. + +- For MinGW, clang now produces vtables and RTTI for dllexported classes + without key functions. This fixes building Qt in debug mode. + +- Allow using Address Sanitizer and Undefined Behaviour Sanitizer on MinGW. + - ... @@ -233,12 +253,15 @@ ABI Changes in Clang OpenMP Support in Clang ---------------------------------- -- Support relational-op != (not-equal) as one of the canonical forms of random - access iterator. +- OpenMP 5.0 features -- Added support for mapping of the lambdas in target regions. - -- Added parsing/sema analysis for OpenMP 5.0 requires directive. + - Support relational-op != (not-equal) as one of the canonical forms of random + access iterator. + - Added support for mapping of the lambdas in target regions. + - Added parsing/sema analysis for the requires directive. + - Support nested declare target directives. + - Make the `this` pointer implicitly mapped as `map(this[:1])`. + - Added the `close` *map-type-modifier*. - Various bugfixes and improvements. @@ -250,6 +273,15 @@ New features supported for Cuda devices: - Fixed support for lastprivate/reduction variables in SPMD constructs. +- New collapse clause scheme to avoid expensive remainder operations. + +- New default schedule for distribute and parallel constructs. + +- Simplified code generation for distribute and parallel in SPMD mode. + +- Flag (``-fopenmp_optimistic_collapse``) for user to limit collapsed + loop counter width when safe to do so. + - General performance improvement. CUDA Support in Clang diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def index 1892ff11a31d..690d547f7f3e 100644 --- a/include/clang/Basic/BuiltinsAArch64.def +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -33,7 +33,7 @@ BUILTIN(__builtin_arm_clrex, "v", "") // Bit manipulation BUILTIN(__builtin_arm_rbit, "UiUi", "nc") -BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc") +BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc") // HINT BUILTIN(__builtin_arm_nop, "v", "") @@ -50,8 +50,8 @@ BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc") BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc") -BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc") -BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc") +BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc") +BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc") // Memory barrier BUILTIN(__builtin_arm_dmb, "vUi", "nc") @@ -63,10 +63,10 @@ BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc") // System Registers BUILTIN(__builtin_arm_rsr, "UicC*", "nc") -BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc") +BUILTIN(__builtin_arm_rsr64, "WUicC*", "nc") BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc") BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc") -BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc") +BUILTIN(__builtin_arm_wsr64, "vcC*WUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // MSVC diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def index 05464ed85f13..8b3b59b51c54 100644 --- a/include/clang/Basic/Features.def +++ b/include/clang/Basic/Features.def @@ -96,7 +96,7 @@ FEATURE(objc_arc, LangOpts.ObjCAutoRefCount) FEATURE(objc_arc_fields, true) FEATURE(objc_arc_weak, LangOpts.ObjCWeak) FEATURE(objc_default_synthesize_properties, LangOpts.ObjC) -FEATURE(objc_fixed_enum, true) +FEATURE(objc_fixed_enum, LangOpts.ObjC) FEATURE(objc_instancetype, LangOpts.ObjC) FEATURE(objc_kindof, LangOpts.ObjC) FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules) diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index e7891baf5304..6a71289f74c1 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -70,15 +70,14 @@ class FileEntry { bool IsNamedPipe; bool InPCH; bool IsValid; // Is this \c FileEntry initialized and valid? - bool DeferredOpen; // Created by getFile(OpenFile=0); may open later. /// The open file, if it is owned by the \p FileEntry. mutable std::unique_ptr File; public: FileEntry() - : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false), - DeferredOpen(false) {} + : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false) + {} FileEntry(const FileEntry &) = delete; FileEntry &operator=(const FileEntry &) = delete; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 786b1c251ca8..1e835d992bbe 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -64,6 +64,7 @@ class TargetInfo : public RefCountedBase { bool HasLegalHalfType; // True if the backend supports operations on the half // LLVM IR type. bool HasFloat128; + bool HasFloat16; unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; @@ -517,6 +518,9 @@ class TargetInfo : public RefCountedBase { /// Determine whether the __float128 type is supported on this target. virtual bool hasFloat128Type() const { return HasFloat128; } + /// Determine whether the _Float16 type is supported on this target. + virtual bool hasFloat16Type() const { return HasFloat16; } + /// Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index f02a7190f5a7..d8155a95775c 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2418,6 +2418,14 @@ def modd_spreg : Flag<["-"], "modd-spreg">, Group, def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group, HelpText<"Disable odd single-precision floating point registers">, Flags<[HelpHidden]>; +def mrelax_pic_calls : Flag<["-"], "mrelax-pic-calls">, + Group, + HelpText<"Try turning PIC calls (j{al}r{c} $25) into direct calls " + "(MIPS only)">, Flags<[HelpHidden]>; +def mno_relax_pic_calls : Flag<["-"], "mno-relax-pic-calls">, + Group, + HelpText<"Do not try turning PIC calls (j{al}r{c} $25) into direct calls " + "(MIPS only)">, Flags<[HelpHidden]>; def mglibc : Flag<["-"], "mglibc">, Group, Flags<[HelpHidden]>; def muclibc : Flag<["-"], "muclibc">, Group, Flags<[HelpHidden]>; def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group, diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h index 94ccf1f34e57..e31839b9a8f7 100644 --- a/include/clang/Tooling/ArgumentsAdjusters.h +++ b/include/clang/Tooling/ArgumentsAdjusters.h @@ -61,6 +61,10 @@ ArgumentsAdjuster getInsertArgumentAdjuster( const char *Extra, ArgumentInsertPosition Pos = ArgumentInsertPosition::END); +/// Gets an argument adjuster which strips plugin related command line +/// arguments. +ArgumentsAdjuster getStripPluginsAdjuster(); + /// Gets an argument adjuster which adjusts the arguments in sequence /// with the \p First adjuster and then with the \p Second one. ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index f5a2d4894c13..01ec1d69cde5 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -189,21 +189,15 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, *SeenFileEntries.insert(std::make_pair(Filename, nullptr)).first; // See if there is already an entry in the map. - if (NamedFileEnt.second) { - if (NamedFileEnt.second == NON_EXISTENT_FILE) - return nullptr; - // Entry exists: return it *unless* it wasn't opened and open is requested. - if (!(NamedFileEnt.second->DeferredOpen && openFile)) - return NamedFileEnt.second; - // We previously stat()ed the file, but didn't open it: do that below. - // FIXME: the below does other redundant work too (stats the dir and file). - } else { - // By default, initialize it to invalid. - NamedFileEnt.second = NON_EXISTENT_FILE; - } + if (NamedFileEnt.second) + return NamedFileEnt.second == NON_EXISTENT_FILE ? nullptr + : NamedFileEnt.second; ++NumFileCacheMisses; + // By default, initialize it to invalid. + NamedFileEnt.second = NON_EXISTENT_FILE; + // Get the null-terminated file name as stored as the key of the // SeenFileEntries map. StringRef InterndFileName = NamedFileEnt.first(); @@ -241,7 +235,6 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // It exists. See if we have already opened a file with the same inode. // This occurs when one dir is symlinked to another, for example. FileEntry &UFE = UniqueRealFiles[Data.UniqueID]; - UFE.DeferredOpen = !openFile; NamedFileEnt.second = &UFE; @@ -258,15 +251,6 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, InterndFileName = NamedFileEnt.first().data(); } - // If we opened the file for the first time, record the resulting info. - // Do this even if the cache entry was valid, maybe we didn't previously open. - if (F && !UFE.File) { - if (auto PathName = F->getName()) - fillRealPathName(&UFE, *PathName); - UFE.File = std::move(F); - assert(!UFE.DeferredOpen && "we just opened it!"); - } - if (UFE.isValid()) { // Already have an entry with this inode, return it. // FIXME: this hack ensures that if we look up a file by a virtual path in @@ -297,9 +281,13 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, UFE.UniqueID = Data.UniqueID; UFE.IsNamedPipe = Data.IsNamedPipe; UFE.InPCH = Data.InPCH; + UFE.File = std::move(F); UFE.IsValid = true; - // Note File and DeferredOpen were initialized above. + if (UFE.File) { + if (auto PathName = UFE.File->getName()) + fillRealPathName(&UFE, *PathName); + } return &UFE; } @@ -371,7 +359,6 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, UFE->UID = NextFileUID++; UFE->IsValid = true; UFE->File.reset(); - UFE->DeferredOpen = false; return UFE; } diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 269fad38b8d5..8b7621d7962e 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -35,6 +35,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { NoAsmVariants = false; HasLegalHalfType = false; HasFloat128 = false; + HasFloat16 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index cf87bc484621..3c139d724796 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -570,19 +570,27 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, Triple.getVendor() != llvm::Triple::UnknownVendor || !Triple.isOSBinFormatWasm()) return nullptr; - if (Triple.getOS() != llvm::Triple::UnknownOS && - Triple.getOS() != llvm::Triple::WASI) - return nullptr; - return new WebAssemblyOSTargetInfo(Triple, Opts); + switch (Triple.getOS()) { + case llvm::Triple::WASI: + return new WASITargetInfo(Triple, Opts); + case llvm::Triple::UnknownOS: + return new WebAssemblyOSTargetInfo(Triple, Opts); + default: + return nullptr; + } case llvm::Triple::wasm64: if (Triple.getSubArch() != llvm::Triple::NoSubArch || Triple.getVendor() != llvm::Triple::UnknownVendor || !Triple.isOSBinFormatWasm()) return nullptr; - if (Triple.getOS() != llvm::Triple::UnknownOS && - Triple.getOS() != llvm::Triple::WASI) - return nullptr; - return new WebAssemblyOSTargetInfo(Triple, Opts); + switch (Triple.getOS()) { + case llvm::Triple::WASI: + return new WASITargetInfo(Triple, Opts); + case llvm::Triple::UnknownOS: + return new WebAssemblyOSTargetInfo(Triple, Opts); + default: + return nullptr; + } case llvm::Triple::renderscript32: return new LinuxTargetInfo(Triple, Opts); diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp index 62919a02dcb9..6297f23c5aa4 100644 --- a/lib/Basic/Targets/AArch64.cpp +++ b/lib/Basic/Targets/AArch64.cpp @@ -50,6 +50,7 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, // All AArch64 implementations support ARMv8 FP, which makes half a legal type. HasLegalHalfType = true; + HasFloat16 = true; LongWidth = LongAlign = PointerWidth = PointerAlign = 64; MaxVectorAlign = 128; diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp index 16644ace108b..23eee34eaa93 100644 --- a/lib/Basic/Targets/ARM.cpp +++ b/lib/Basic/Targets/ARM.cpp @@ -397,6 +397,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector &Features, SoftFloat = SoftFloatABI = false; HWDiv = 0; DotProd = 0; + HasFloat16 = true; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h index 085efa02cc5f..09867d82c382 100644 --- a/lib/Basic/Targets/OSTargets.h +++ b/lib/Basic/Targets/OSTargets.h @@ -764,8 +764,9 @@ class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo { template class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo : public OSTargetInfo { +protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const final { + MacroBuilder &Builder) const { // A common platform macro. if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); @@ -783,6 +784,21 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo } }; +// WASI target +template +class LLVM_LIBRARY_VISIBILITY WASITargetInfo + : public WebAssemblyOSTargetInfo { + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const final { + WebAssemblyOSTargetInfo::getOSDefines(Opts, Triple, Builder); + Builder.defineMacro("__wasi__"); + } + +public: + explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WebAssemblyOSTargetInfo(Triple, Opts) {} +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H diff --git a/lib/Basic/Targets/SPIR.h b/lib/Basic/Targets/SPIR.h index 9815292fc276..e8d92f11a122 100644 --- a/lib/Basic/Targets/SPIR.h +++ b/lib/Basic/Targets/SPIR.h @@ -48,6 +48,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo { AddrSpaceMap = &SPIRAddrSpaceMap; UseAddrSpaceMapMangling = true; HasLegalHalfType = true; + HasFloat16 = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 75f16898dfaf..589f53b11921 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -1716,6 +1716,14 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } else D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName; } + + if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls, + options::OPT_mno_relax_pic_calls)) { + if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mips-jalr-reloc=0"); + } + } } void Clang::AddPPCTargetArgs(const ArgList &Args, diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp index b1321cacaf7a..c1eae5b05ace 100644 --- a/lib/Driver/ToolChains/NetBSD.cpp +++ b/lib/Driver/ToolChains/NetBSD.cpp @@ -256,6 +256,13 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs(); + if (SanArgs.needsSharedRt()) { + CmdArgs.push_back("-rpath"); + CmdArgs.push_back(Args.MakeArgString( + ToolChain.getCompilerRTPath().c_str())); + } + unsigned Major, Minor, Micro; ToolChain.getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; diff --git a/lib/Headers/opencl-c.h b/lib/Headers/opencl-c.h index 160bae807174..3d3dfb74905f 100644 --- a/lib/Headers/opencl-c.h +++ b/lib/Headers/opencl-c.h @@ -14470,7 +14470,7 @@ half16 __ovld __cnfn shuffle2(half16 x, half16 y, ushort16 mask); #if __OPENCL_C_VERSION__ >= CL_VERSION_1_2 // OpenCL v1.2 s6.12.13, v2.0 s6.13.13 - printf -int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2))); +int printf(__constant const char* st, ...); #endif // OpenCL v1.1 s6.11.3, v1.2 s6.12.14, v2.0 s6.13.14 - Image Read and Write Functions diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index fa0815eb9c6c..3c1da075b0e2 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -617,10 +617,11 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (isHalf || isFloat || isLong || isFloat128) break; // HF, FF, LF, QF invalid. - if (s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') { - s += 2; // success, eat up 2 characters. - isFloat16 = true; - continue; + if (PP.getTargetInfo().hasFloat16Type() && s + 2 < ThisTokEnd && + s[1] == '1' && s[2] == '6') { + s += 2; // success, eat up 2 characters. + isFloat16 = true; + continue; } isFloat = true; diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index d9f007a46da5..980d7b455ece 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -681,7 +681,8 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { T = Property->getType(); else if (const auto *Value = dyn_cast(ND)) T = Value->getType(); - else + + if (T.isNull()) return QualType(); // Dig through references, function pointers, and block pointers to diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 43b289d8d0de..8b3556f715bf 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1301,6 +1301,10 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc, static bool checkMemberDecomposition(Sema &S, ArrayRef Bindings, ValueDecl *Src, QualType DecompType, const CXXRecordDecl *OrigRD) { + if (S.RequireCompleteType(Src->getLocation(), DecompType, + diag::err_incomplete_type)) + return true; + CXXCastPath BasePath; DeclAccessPair BasePair = findDecomposableBaseClass(S, Src->getLocation(), OrigRD, BasePath); @@ -5886,9 +5890,6 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D, if (D->isDependentType() || D->isInvalidDecl()) return false; - if (D->hasAttr()) - return true; - // Clang <= 4 used the pre-C++11 rule, which ignores move operations. // The PS4 platform ABI follows the behavior of Clang 3.2. if (CCK == TargetInfo::CCK_ClangABI4OrPS4) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d5416d4d057c..2bcd47abe356 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -738,33 +738,20 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { return ExprError(); E = Res.get(); - QualType ScalarTy = Ty; - unsigned NumElts = 0; - if (const ExtVectorType *VecTy = Ty->getAs()) { - NumElts = VecTy->getNumElements(); - ScalarTy = VecTy->getElementType(); - } - // If this is a 'float' or '__fp16' (CVR qualified or typedef) // promote to double. // Note that default argument promotion applies only to float (and // half/fp16); it does not apply to _Float16. - const BuiltinType *BTy = ScalarTy->getAs(); + const BuiltinType *BTy = Ty->getAs(); if (BTy && (BTy->getKind() == BuiltinType::Half || BTy->getKind() == BuiltinType::Float)) { if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp64")) { - if (BTy->getKind() == BuiltinType::Half) { - QualType Ty = Context.FloatTy; - if (NumElts != 0) - Ty = Context.getExtVectorType(Ty, NumElts); - E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); - } + if (BTy->getKind() == BuiltinType::Half) { + E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); + } } else { - QualType Ty = Context.DoubleTy; - if (NumElts != 0) - Ty = Context.getExtVectorType(Ty, NumElts); - E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); + E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); } } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3f9dc989103f..f974bedffe00 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -6309,7 +6309,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // -- a predefined __func__ variable if (auto *E = Value.getLValueBase().dyn_cast()) { if (isa(E)) { - Converted = TemplateArgument(ArgResult.get()); + Converted = TemplateArgument(ArgResult.get()->IgnoreImpCasts()); break; } Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref) diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index b4c075e9c46d..1ae94c8aec99 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1442,7 +1442,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { else Result = Context.Int128Ty; break; - case DeclSpec::TST_float16: Result = Context.Float16Ty; break; + case DeclSpec::TST_float16: + if (!S.Context.getTargetInfo().hasFloat16Type()) + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) + << "_Float16"; + Result = Context.Float16Ty; + break; case DeclSpec::TST_half: Result = Context.HalfTy; break; case DeclSpec::TST_float: Result = Context.FloatTy; break; case DeclSpec::TST_double: diff --git a/lib/Tooling/ArgumentsAdjusters.cpp b/lib/Tooling/ArgumentsAdjusters.cpp index c8e9c167422e..f5040b8a09d5 100644 --- a/lib/Tooling/ArgumentsAdjusters.cpp +++ b/lib/Tooling/ArgumentsAdjusters.cpp @@ -108,5 +108,27 @@ ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, }; } +ArgumentsAdjuster getStripPluginsAdjuster() { + return [](const CommandLineArguments &Args, StringRef /*unused*/) { + CommandLineArguments AdjustedArgs; + for (size_t I = 0, E = Args.size(); I != E; I++) { + // According to https://clang.llvm.org/docs/ClangPlugins.html + // plugin arguments are in the form: + // -Xclang {-load, -plugin, -plugin-arg-, -add-plugin} + // -Xclang + if (I + 4 < E && Args[I] == "-Xclang" && + (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" || + llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") || + Args[I + 1] == "-add-plugin") && + Args[I + 2] == "-Xclang") { + I += 3; + continue; + } + AdjustedArgs.push_back(Args[I]); + } + return AdjustedArgs; + }; +} + } // end namespace tooling } // end namespace clang diff --git a/test/AST/float16.cpp b/test/AST/float16.cpp index aa65270c75d4..2f428e7085ff 100644 --- a/test/AST/float16.cpp +++ b/test/AST/float16.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace -// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace +// RUN: %clang_cc1 -std=c++11 -ast-dump -triple aarch64-linux-gnu %s | FileCheck %s --strict-whitespace +// RUN: %clang_cc1 -std=c++11 -ast-dump -triple aarch64-linux-gnu -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace /* Various contexts where type _Float16 can appear. */ diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp index 686aac2802ad..e435bee2c88e 100644 --- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++11 -verify %s -triple x86_64-linux-gnu alignas(double) void f(); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}} alignas(double) unsigned char c[sizeof(double)]; // expected-note {{previous}} diff --git a/test/CodeCompletion/crash-null-type.cpp b/test/CodeCompletion/crash-null-type.cpp new file mode 100644 index 000000000000..c5b3d1e79390 --- /dev/null +++ b/test/CodeCompletion/crash-null-type.cpp @@ -0,0 +1,8 @@ +void test() { + for (auto [loopVar] : y) { // y has to be unresolved + loopVa + } +} +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:3:11 %s -o - \ +// RUN: | FileCheck %s +// CHECK: COMPLETION: loopVar diff --git a/test/CodeGen/arm64-crc32.c b/test/CodeGen/arm64-crc32.c index 2d913fb123b7..26d69a23b6a1 100644 --- a/test/CodeGen/arm64-crc32.c +++ b/test/CodeGen/arm64-crc32.c @@ -1,54 +1,57 @@ // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple arm64-none-linux-gnu \ // RUN: -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-windows \ +// RUN: -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +#include -int crc32b(int a, char b) +uint32_t crc32b(uint32_t a, uint8_t b) { return __builtin_arm_crc32b(a,b); // CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32b(i32 %a, i32 [[T0]]) } -int crc32cb(int a, char b) +uint32_t crc32cb(uint32_t a, uint8_t b) { return __builtin_arm_crc32cb(a,b); // CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32cb(i32 %a, i32 [[T0]]) } -int crc32h(int a, short b) +uint32_t crc32h(uint32_t a, uint16_t b) { return __builtin_arm_crc32h(a,b); // CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32h(i32 %a, i32 [[T0]]) } -int crc32ch(int a, short b) +uint32_t crc32ch(uint32_t a, uint16_t b) { return __builtin_arm_crc32ch(a,b); // CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32ch(i32 %a, i32 [[T0]]) } -int crc32w(int a, int b) +uint32_t crc32w(uint32_t a, uint32_t b) { return __builtin_arm_crc32w(a,b); // CHECK: call i32 @llvm.aarch64.crc32w(i32 %a, i32 %b) } -int crc32cw(int a, int b) +uint32_t crc32cw(uint32_t a, uint32_t b) { return __builtin_arm_crc32cw(a,b); // CHECK: call i32 @llvm.aarch64.crc32cw(i32 %a, i32 %b) } -int crc32d(int a, long b) +uint32_t crc32d(uint32_t a, uint64_t b) { return __builtin_arm_crc32d(a,b); // CHECK: call i32 @llvm.aarch64.crc32x(i32 %a, i64 %b) } -int crc32cd(int a, long b) +uint32_t crc32cd(uint32_t a, uint64_t b) { return __builtin_arm_crc32cd(a,b); // CHECK: call i32 @llvm.aarch64.crc32cx(i32 %a, i64 %b) diff --git a/test/CodeGen/builtins-arm64.c b/test/CodeGen/builtins-arm64.c index 7027a6e220f3..f164c2f6f364 100644 --- a/test/CodeGen/builtins-arm64.c +++ b/test/CodeGen/builtins-arm64.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LINUX +// RUN: %clang_cc1 -triple aarch64-windows -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WIN +#include void f0(void *a, void *b) { __clear_cache(a,b); @@ -15,8 +17,15 @@ unsigned rbit(unsigned a) { return __builtin_arm_rbit(a); } +// CHECK-WIN: [[A64:%[^ ]+]] = zext i32 %a to i64 +// CHECK-WIN: call i64 @llvm.bitreverse.i64(i64 [[A64]]) +// CHECK-LINUX: call i64 @llvm.bitreverse.i64(i64 %a) +unsigned long rbitl(unsigned long a) { + return __builtin_arm_rbit64(a); +} + // CHECK: call {{.*}} @llvm.bitreverse.i64(i64 %a) -unsigned long long rbit64(unsigned long long a) { +uint64_t rbit64(uint64_t a) { return __builtin_arm_rbit64(a); } @@ -49,13 +58,17 @@ void prefetch() { // CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 3, i32 0) } -unsigned rsr() { +__typeof__(__builtin_arm_rsr("1:2:3:4:5")) rsr(void); + +uint32_t rsr() { // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) // CHECK-NEXT: trunc i64 [[V0]] to i32 return __builtin_arm_rsr("1:2:3:4:5"); } -unsigned long rsr64() { +__typeof__(__builtin_arm_rsr64("1:2:3:4:5")) rsr64(void); + +uint64_t rsr64(void) { // CHECK: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) return __builtin_arm_rsr64("1:2:3:4:5"); } @@ -66,13 +79,17 @@ void *rsrp() { return __builtin_arm_rsrp("1:2:3:4:5"); } +__typeof__(__builtin_arm_wsr("1:2:3:4:5", 0)) wsr(unsigned); + void wsr(unsigned v) { // CHECK: [[V0:[%A-Za-z0-9.]+]] = zext i32 %v to i64 // CHECK-NEXT: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 [[V0]]) __builtin_arm_wsr("1:2:3:4:5", v); } -void wsr64(unsigned long v) { +__typeof__(__builtin_arm_wsr64("1:2:3:4:5", 0)) wsr64(uint64_t); + +void wsr64(uint64_t v) { // CHECK: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %v) __builtin_arm_wsr64("1:2:3:4:5", v); } diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp index 7e1c1e8db93c..7d07eac48111 100644 --- a/test/CodeGenCXX/float16-declarations.cpp +++ b/test/CodeGenCXX/float16-declarations.cpp @@ -1,5 +1,4 @@ // RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64 -// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86 /* Various contexts where type _Float16 can appear. */ @@ -15,7 +14,6 @@ namespace { _Float16 arr1n[10]; // CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2 -// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16 _Float16 arr2n[] = { 1.2, 3.0, 3.e4 }; // CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2 @@ -30,14 +28,12 @@ namespace { _Float16 f1f; // CHECK-AARCH64-DAG: @f1f = dso_local global half 0xH0000, align 2 -// CHECK-X86-DAG: @f1f = dso_local global half 0xH0000, align 2 _Float16 f2f = 32.4; // CHECK-DAG: @f2f = dso_local global half 0xH500D, align 2 _Float16 arr1f[10]; // CHECK-AARCH64-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 2 -// CHECK-X86-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 16 _Float16 arr2f[] = { -1.2, -3.0, -3.e4 }; // CHECK-DAG: @arr2f = dso_local global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2 @@ -137,8 +133,6 @@ int main(void) { long double cvtld = f2n; //CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128 //CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16 -//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80 -//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16 _Float16 f2h = 42.0f; //CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2 diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index e128c9443153..0175b961e5e9 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s +// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=aarch64-pc-win32 -std=c++98 -DARM | FileCheck -check-prefixes=X64,ARM %s int a; // CHECK-DAG: @"?a@@3HA" @@ -466,10 +467,12 @@ namespace Complex { // CHECK-DAG: define dso_local void @"?f@Complex@@YAXU?$_Complex@H@__clang@@@Z"( void f(_Complex int) {} } +#ifdef ARM namespace Float16 { -// CHECK-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"( +// ARM-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"( void f(_Float16) {} } +#endif // ARM namespace PR26029 { template diff --git a/test/CodeGenCXX/trivial_abi.cpp b/test/CodeGenCXX/trivial_abi.cpp index e37c8ff615a2..2cf07b22581a 100644 --- a/test/CodeGenCXX/trivial_abi.cpp +++ b/test/CodeGenCXX/trivial_abi.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s // CHECK: %[[STRUCT_SMALL:.*]] = type { i32* } // CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] } @@ -43,13 +43,6 @@ struct HasNonTrivial { NonTrivial m; }; -struct __attribute__((trivial_abi)) CopyMoveDeleted { - CopyMoveDeleted(int); - CopyMoveDeleted(const CopyMoveDeleted &) = delete; - CopyMoveDeleted(CopyMoveDeleted &&) = delete; - int a; -}; - // CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]]) // CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0 @@ -244,11 +237,3 @@ void calleeExceptionLarge(Large, Large); void testExceptionLarge() { calleeExceptionLarge(Large(), Large()); } - -// A class with deleted copy and move constructors can still be passed or -// returned in registers if the class is annotated with trivial_abi. - -// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 % -CopyMoveDeleted testCopyMoveDeleted(int a) { - return a; -} diff --git a/test/CodeGenOpenCL/printf.cl b/test/CodeGenOpenCL/printf.cl index 346f6c35bae4..fc139d776db6 100644 --- a/test/CodeGenOpenCL/printf.cl +++ b/test/CodeGenOpenCL/printf.cl @@ -12,28 +12,26 @@ int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2))) // ALL-LABEL: @test_printf_float2( -// FP64: %conv = fpext <2 x float> %0 to <2 x double> -// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv) +// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([7 x i8], [7 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0) -// NOFP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0) + +// NOFP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([7 x i8], [7 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0) kernel void test_printf_float2(float2 arg) { - printf("%v2f", arg); + printf("%v2hlf", arg); } // ALL-LABEL: @test_printf_half2( -// FP64: %conv = fpext <2 x half> %0 to <2 x double> -// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv) #2 +// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.1, i32 0, i32 0), <2 x half> %0) -// NOFP64: %conv = fpext <2 x half> %0 to <2 x float> -// NOFP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %conv) #2 +// NOFP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.1, i32 0, i32 0), <2 x half> %0) kernel void test_printf_half2(half2 arg) { - printf("%v2f", arg); + printf("%v2hf", arg); } #ifdef cl_khr_fp64 // FP64-LABEL: @test_printf_double2( -// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %0) #2 +// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.2, i32 0, i32 0), <2 x double> %0) kernel void test_printf_double2(double2 arg) { - printf("%v2f", arg); + printf("%v2lf", arg); } #endif diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c index f63fb8de55d6..19725bc096b5 100644 --- a/test/Driver/mips-features.c +++ b/test/Driver/mips-features.c @@ -444,3 +444,15 @@ // RUN: -mginv -mno-ginv 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-GINV %s // CHECK-NO-GINV: "-target-feature" "-ginv" +// +// -mrelax-pic-calls +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -mno-relax-pic-calls -mrelax-pic-calls 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RELAX-PIC-CALLS %s +// CHECK-RELAX-PIC-CALLS-NOT: "-mllvm" "-mips-jalr-reloc=0" +// +// -mno-relax-pic-calls +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -mrelax-pic-calls -mno-relax-pic-calls 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-RELAX-PIC-CALLS %s +// CHECK-NO-RELAX-PIC-CALLS: "-mllvm" "-mips-jalr-reloc=0" diff --git a/test/Lexer/half-literal.cpp b/test/Lexer/half-literal.cpp index 8e0034d491dd..2f1cf9589fab 100644 --- a/test/Lexer/half-literal.cpp +++ b/test/Lexer/half-literal.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -triple aarch64-linux-gnu %s float a = 1.0h; // expected-error{{no matching literal operator for call to 'operator""h' with argument of type 'long double' or 'const char *', and no matching literal operator template}} float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}} diff --git a/test/PCH/leakfiles b/test/PCH/leakfiles new file mode 100644 index 000000000000..90b279026bc1 --- /dev/null +++ b/test/PCH/leakfiles @@ -0,0 +1,29 @@ +// Test that compiling using a PCH doesn't leak file descriptors. +// https://bugs.chromium.org/p/chromium/issues/detail?id=924225 +// +// This test requires bash loops and ulimit. +// REQUIRES: shell +// UNSUPPORTED: win32 +// +// Set up source files. lib/lib.h includes lots of lib*.h files in that dir. +// client.c includes lib/lib.h, and also the individual files directly. +// +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: cd %t +// RUN: mkdir lib +// RUN: for i in {1..300}; do touch lib/lib$i.h; done +// RUN: for i in {1..300}; do echo "#include \"lib$i.h\"" >> lib/lib.h; done +// RUN: echo "#include \"lib/lib.h\"" > client.c +// RUN: for i in {1..300}; do echo "#include \"lib/lib$i.h\"" >> client.c; done +// +// We want to verify that we don't hold all the files open at the same time. +// This is important e.g. on mac, which has a low default FD limit. +// RUN: ulimit -n 100 +// +// Test without PCH. +// RUN: %clang_cc1 -fsyntax-only -Ilib/ client.c +// +// Test with PCH. +// RUN: %clang_cc1 -emit-pch -o pch -Ilib/ client.c +// RUN: %clang_cc1 -include-pch pch -Ilib/ client.c -fsyntax-only diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index 940dddade337..770e52cc7843 100644 --- a/test/Preprocessor/init.c +++ b/test/Preprocessor/init.c @@ -9110,667 +9110,383 @@ // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm32-unknown-unknown \ // RUN: < /dev/null \ -// RUN: | FileCheck -match-full-lines -check-prefix=WEBASSEMBLY32 %s +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \ +// RUN: < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm32-unknown-wasi \ +// RUN: < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WEBASSEMBLY-WASI %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-wasi \ +// RUN: < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WEBASSEMBLY-WASI %s // // WEBASSEMBLY32:#define _ILP32 1 // WEBASSEMBLY32-NOT:#define _LP64 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_ACQUIRE 2 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_ACQ_REL 4 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_CONSUME 1 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_RELAXED 0 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_RELEASE 3 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_SEQ_CST 5 -// WEBASSEMBLY32-NEXT:#define __BIGGEST_ALIGNMENT__ 16 -// WEBASSEMBLY32-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -// WEBASSEMBLY32-NEXT:#define __CHAR16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __CHAR32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __CHAR_BIT__ 8 -// WEBASSEMBLY32-NOT:#define __CHAR_UNSIGNED__ -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CONSTANT_CFSTRINGS__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_DECIMAL_DIG__ 17 -// WEBASSEMBLY32-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 -// WEBASSEMBLY32-NEXT:#define __DBL_DIG__ 15 -// WEBASSEMBLY32-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16 -// WEBASSEMBLY32-NEXT:#define __DBL_HAS_DENORM__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_HAS_INFINITY__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_MANT_DIG__ 53 -// WEBASSEMBLY32-NEXT:#define __DBL_MAX_10_EXP__ 308 -// WEBASSEMBLY32-NEXT:#define __DBL_MAX_EXP__ 1024 -// WEBASSEMBLY32-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308 -// WEBASSEMBLY32-NEXT:#define __DBL_MIN_10_EXP__ (-307) -// WEBASSEMBLY32-NEXT:#define __DBL_MIN_EXP__ (-1021) -// WEBASSEMBLY32-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308 -// WEBASSEMBLY32-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ -// WEBASSEMBLY32-NOT:#define __ELF__ -// WEBASSEMBLY32-NEXT:#define __FINITE_MATH_ONLY__ 0 -// WEBASSEMBLY32:#define __FLT_DECIMAL_DIG__ 9 -// WEBASSEMBLY32-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F -// WEBASSEMBLY32-NEXT:#define __FLT_DIG__ 6 -// WEBASSEMBLY32-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F -// WEBASSEMBLY32-NEXT:#define __FLT_EVAL_METHOD__ 0 -// WEBASSEMBLY32-NEXT:#define __FLT_HAS_DENORM__ 1 -// WEBASSEMBLY32-NEXT:#define __FLT_HAS_INFINITY__ 1 -// WEBASSEMBLY32-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY32-NEXT:#define __FLT_MANT_DIG__ 24 -// WEBASSEMBLY32-NEXT:#define __FLT_MAX_10_EXP__ 38 -// WEBASSEMBLY32-NEXT:#define __FLT_MAX_EXP__ 128 -// WEBASSEMBLY32-NEXT:#define __FLT_MAX__ 3.40282347e+38F -// WEBASSEMBLY32-NEXT:#define __FLT_MIN_10_EXP__ (-37) -// WEBASSEMBLY32-NEXT:#define __FLT_MIN_EXP__ (-125) -// WEBASSEMBLY32-NEXT:#define __FLT_MIN__ 1.17549435e-38F -// WEBASSEMBLY32-NEXT:#define __FLT_RADIX__ 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GNUC_MINOR__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __GNUC_STDC_INLINE__ 1 -// WEBASSEMBLY32-NEXT:#define __GNUC__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __GXX_ABI_VERSION 1002 +// WEBASSEMBLY64-NOT:#define _ILP32 +// WEBASSEMBLY64:#define _LP64 1 +// WEBASSEMBLY-NEXT:#define __ATOMIC_ACQUIRE 2 +// WEBASSEMBLY-NEXT:#define __ATOMIC_ACQ_REL 4 +// WEBASSEMBLY-NEXT:#define __ATOMIC_CONSUME 1 +// WEBASSEMBLY-NEXT:#define __ATOMIC_RELAXED 0 +// WEBASSEMBLY-NEXT:#define __ATOMIC_RELEASE 3 +// WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5 +// WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16 +// WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +// WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __CHAR32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __CHAR_BIT__ 8 +// WEBASSEMBLY-NOT:#define __CHAR_UNSIGNED__ +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CONSTANT_CFSTRINGS__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_DECIMAL_DIG__ 17 +// WEBASSEMBLY-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +// WEBASSEMBLY-NEXT:#define __DBL_DIG__ 15 +// WEBASSEMBLY-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16 +// WEBASSEMBLY-NEXT:#define __DBL_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_MANT_DIG__ 53 +// WEBASSEMBLY-NEXT:#define __DBL_MAX_10_EXP__ 308 +// WEBASSEMBLY-NEXT:#define __DBL_MAX_EXP__ 1024 +// WEBASSEMBLY-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308 +// WEBASSEMBLY-NEXT:#define __DBL_MIN_10_EXP__ (-307) +// WEBASSEMBLY-NEXT:#define __DBL_MIN_EXP__ (-1021) +// WEBASSEMBLY-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308 +// WEBASSEMBLY-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ +// WEBASSEMBLY-NOT:#define __ELF__ +// WEBASSEMBLY-NEXT:#define __FINITE_MATH_ONLY__ 0 +// WEBASSEMBLY-NEXT:#define __FLT16_DECIMAL_DIG__ 5 +// WEBASSEMBLY-NEXT:#define __FLT16_DENORM_MIN__ 5.9604644775390625e-8F16 +// WEBASSEMBLY-NEXT:#define __FLT16_DIG__ 3 +// WEBASSEMBLY-NEXT:#define __FLT16_EPSILON__ 9.765625e-4F16 +// WEBASSEMBLY-NEXT:#define __FLT16_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __FLT16_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __FLT16_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __FLT16_MANT_DIG__ 11 +// WEBASSEMBLY-NEXT:#define __FLT16_MAX_10_EXP__ 4 +// WEBASSEMBLY-NEXT:#define __FLT16_MAX_EXP__ 15 +// WEBASSEMBLY-NEXT:#define __FLT16_MAX__ 6.5504e+4F16 +// WEBASSEMBLY-NEXT:#define __FLT16_MIN_10_EXP__ (-13) +// WEBASSEMBLY-NEXT:#define __FLT16_MIN_EXP__ (-14) +// WEBASSEMBLY-NEXT:#define __FLT16_MIN__ 6.103515625e-5F16 +// WEBASSEMBLY-NEXT:#define __FLT_DECIMAL_DIG__ 9 +// WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F +// WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6 +// WEBASSEMBLY-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F +// WEBASSEMBLY-NEXT:#define __FLT_EVAL_METHOD__ 0 +// WEBASSEMBLY-NEXT:#define __FLT_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __FLT_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __FLT_MANT_DIG__ 24 +// WEBASSEMBLY-NEXT:#define __FLT_MAX_10_EXP__ 38 +// WEBASSEMBLY-NEXT:#define __FLT_MAX_EXP__ 128 +// WEBASSEMBLY-NEXT:#define __FLT_MAX__ 3.40282347e+38F +// WEBASSEMBLY-NEXT:#define __FLT_MIN_10_EXP__ (-37) +// WEBASSEMBLY-NEXT:#define __FLT_MIN_EXP__ (-125) +// WEBASSEMBLY-NEXT:#define __FLT_MIN__ 1.17549435e-38F +// WEBASSEMBLY-NEXT:#define __FLT_RADIX__ 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GNUC_MINOR__ {{.*}} +// WEBASSEMBLY-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}} +// WEBASSEMBLY-NEXT:#define __GNUC_STDC_INLINE__ 1 +// WEBASSEMBLY-NEXT:#define __GNUC__ {{.*}} +// WEBASSEMBLY-NEXT:#define __GXX_ABI_VERSION 1002 // WEBASSEMBLY32-NEXT:#define __ILP32__ 1 -// WEBASSEMBLY32-NEXT:#define __INT16_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __INT16_FMTd__ "hd" -// WEBASSEMBLY32-NEXT:#define __INT16_FMTi__ "hi" -// WEBASSEMBLY32-NEXT:#define __INT16_MAX__ 32767 -// WEBASSEMBLY32-NEXT:#define __INT16_TYPE__ short -// WEBASSEMBLY32-NEXT:#define __INT32_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __INT32_FMTd__ "d" -// WEBASSEMBLY32-NEXT:#define __INT32_FMTi__ "i" -// WEBASSEMBLY32-NEXT:#define __INT32_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __INT32_TYPE__ int -// WEBASSEMBLY32-NEXT:#define __INT64_C_SUFFIX__ LL -// WEBASSEMBLY32-NEXT:#define __INT64_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INT64_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INT64_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INT64_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INT8_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __INT8_FMTd__ "hhd" -// WEBASSEMBLY32-NEXT:#define __INT8_FMTi__ "hhi" -// WEBASSEMBLY32-NEXT:#define __INT8_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __INT8_TYPE__ signed char -// WEBASSEMBLY32-NEXT:#define __INTMAX_C_SUFFIX__ LL -// WEBASSEMBLY32-NEXT:#define __INTMAX_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INTMAX_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INTMAX_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INTMAX_WIDTH__ 64 -// WEBASSEMBLY32-NEXT:#define __INTPTR_FMTd__ "ld" -// WEBASSEMBLY32-NEXT:#define __INTPTR_FMTi__ "li" +// WEBASSEMBLY64-NOT:#define __ILP32__ +// WEBASSEMBLY-NEXT:#define __INT16_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __INT16_FMTd__ "hd" +// WEBASSEMBLY-NEXT:#define __INT16_FMTi__ "hi" +// WEBASSEMBLY-NEXT:#define __INT16_MAX__ 32767 +// WEBASSEMBLY-NEXT:#define __INT16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT32_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __INT32_FMTd__ "d" +// WEBASSEMBLY-NEXT:#define __INT32_FMTi__ "i" +// WEBASSEMBLY-NEXT:#define __INT32_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __INT32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT64_C_SUFFIX__ LL +// WEBASSEMBLY-NEXT:#define __INT64_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INT64_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INT64_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INT64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT8_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __INT8_FMTd__ "hhd" +// WEBASSEMBLY-NEXT:#define __INT8_FMTi__ "hhi" +// WEBASSEMBLY-NEXT:#define __INT8_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __INT8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INTMAX_C_SUFFIX__ LL +// WEBASSEMBLY-NEXT:#define __INTMAX_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INTMAX_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INTMAX_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INTMAX_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __INTPTR_FMTd__ "ld" +// WEBASSEMBLY-NEXT:#define __INTPTR_FMTi__ "li" // WEBASSEMBLY32-NEXT:#define __INTPTR_MAX__ 2147483647L -// WEBASSEMBLY32-NEXT:#define __INTPTR_TYPE__ long int +// WEBASSEMBLY64-NEXT:#define __INTPTR_MAX__ 9223372036854775807L +// WEBASSEMBLY-NEXT:#define __INTPTR_TYPE__ long int // WEBASSEMBLY32-NEXT:#define __INTPTR_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_FMTd__ "hd" -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_FMTi__ "hi" -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_MAX__ 32767 -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_TYPE__ short -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_FMTd__ "d" -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_FMTi__ "i" -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_TYPE__ int -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_FMTd__ "hhd" -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_FMTi__ "hhi" -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_TYPE__ signed char -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_FMTd__ "hd" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_FMTi__ "hi" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_MAX__ 32767 -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_TYPE__ short -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_FMTd__ "d" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_FMTi__ "i" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_TYPE__ int -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_FMTd__ "hhd" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_FMTi__ "hhi" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_TYPE__ signed char -// WEBASSEMBLY32-NEXT:#define __INT_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __LDBL_DECIMAL_DIG__ 36 -// WEBASSEMBLY32-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L -// WEBASSEMBLY32-NEXT:#define __LDBL_DIG__ 33 -// WEBASSEMBLY32-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L -// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_DENORM__ 1 -// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_INFINITY__ 1 -// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY32-NEXT:#define __LDBL_MANT_DIG__ 113 -// WEBASSEMBLY32-NEXT:#define __LDBL_MAX_10_EXP__ 4932 -// WEBASSEMBLY32-NEXT:#define __LDBL_MAX_EXP__ 16384 -// WEBASSEMBLY32-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L -// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_10_EXP__ (-4931) -// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_EXP__ (-16381) -// WEBASSEMBLY32-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L -// WEBASSEMBLY32-NEXT:#define __LITTLE_ENDIAN__ 1 -// WEBASSEMBLY32-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL +// WEBASSEMBLY64-NEXT:#define __INTPTR_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTd__ "hd" +// WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTi__ "hi" +// WEBASSEMBLY-NEXT:#define __INT_FAST16_MAX__ 32767 +// WEBASSEMBLY-NEXT:#define __INT_FAST16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTd__ "d" +// WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTi__ "i" +// WEBASSEMBLY-NEXT:#define __INT_FAST32_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __INT_FAST32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INT_FAST64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTd__ "hhd" +// WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTi__ "hhi" +// WEBASSEMBLY-NEXT:#define __INT_FAST8_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __INT_FAST8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTd__ "hd" +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTi__ "hi" +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_MAX__ 32767 +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTd__ "d" +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTi__ "i" +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTd__ "hhd" +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTi__ "hhi" +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INT_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __LDBL_DECIMAL_DIG__ 36 +// WEBASSEMBLY-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L +// WEBASSEMBLY-NEXT:#define __LDBL_DIG__ 33 +// WEBASSEMBLY-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L +// WEBASSEMBLY-NEXT:#define __LDBL_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __LDBL_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __LDBL_MANT_DIG__ 113 +// WEBASSEMBLY-NEXT:#define __LDBL_MAX_10_EXP__ 4932 +// WEBASSEMBLY-NEXT:#define __LDBL_MAX_EXP__ 16384 +// WEBASSEMBLY-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L +// WEBASSEMBLY-NEXT:#define __LDBL_MIN_10_EXP__ (-4931) +// WEBASSEMBLY-NEXT:#define __LDBL_MIN_EXP__ (-16381) +// WEBASSEMBLY-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L +// WEBASSEMBLY-NEXT:#define __LITTLE_ENDIAN__ 1 +// WEBASSEMBLY-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL // WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L // WEBASSEMBLY32-NOT:#define __LP64__ -// WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1 -// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 -// WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321 -// WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234 -// WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412 +// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L +// WEBASSEMBLY64-NEXT:#define __LP64__ 1 +// WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1 +// WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_BOOL 0 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 +// WEBASSEMBLY-NEXT:#define __ORDER_BIG_ENDIAN__ 4321 +// WEBASSEMBLY-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234 +// WEBASSEMBLY-NEXT:#define __ORDER_PDP_ENDIAN__ 3412 // WEBASSEMBLY32-NEXT:#define __POINTER_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1 -// WEBASSEMBLY32-NEXT:#define __PTRDIFF_FMTd__ "ld" -// WEBASSEMBLY32-NEXT:#define __PTRDIFF_FMTi__ "li" +// WEBASSEMBLY64-NEXT:#define __POINTER_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1 +// WEBASSEMBLY-NEXT:#define __PTRDIFF_FMTd__ "ld" +// WEBASSEMBLY-NEXT:#define __PTRDIFF_FMTi__ "li" // WEBASSEMBLY32-NEXT:#define __PTRDIFF_MAX__ 2147483647L -// WEBASSEMBLY32-NEXT:#define __PTRDIFF_TYPE__ long int +// WEBASSEMBLY64-NEXT:#define __PTRDIFF_MAX__ 9223372036854775807L +// WEBASSEMBLY-NEXT:#define __PTRDIFF_TYPE__ long int // WEBASSEMBLY32-NEXT:#define __PTRDIFF_WIDTH__ 32 -// WEBASSEMBLY32-NOT:#define __REGISTER_PREFIX__ -// WEBASSEMBLY32-NEXT:#define __SCHAR_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __SHRT_MAX__ 32767 +// WEBASSEMBLY64-NEXT:#define __PTRDIFF_WIDTH__ 64 +// WEBASSEMBLY-NOT:#define __REGISTER_PREFIX__ +// WEBASSEMBLY-NEXT:#define __SCHAR_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __SHRT_MAX__ 32767 // WEBASSEMBLY32-NEXT:#define __SIG_ATOMIC_MAX__ 2147483647L // WEBASSEMBLY32-NEXT:#define __SIG_ATOMIC_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_DOUBLE__ 8 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_FLOAT__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_INT128__ 16 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_INT__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG_LONG__ 8 +// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_MAX__ 9223372036854775807L +// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __SIZEOF_DOUBLE__ 8 +// WEBASSEMBLY-NEXT:#define __SIZEOF_FLOAT__ 4 +// WEBASSEMBLY-NEXT:#define __SIZEOF_INT128__ 16 +// WEBASSEMBLY-NEXT:#define __SIZEOF_INT__ 4 +// WEBASSEMBLY-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16 +// WEBASSEMBLY-NEXT:#define __SIZEOF_LONG_LONG__ 8 // WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG__ 4 // WEBASSEMBLY32-NEXT:#define __SIZEOF_POINTER__ 4 // WEBASSEMBLY32-NEXT:#define __SIZEOF_PTRDIFF_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_SHORT__ 2 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_SIZE_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_WCHAR_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_WINT_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTX__ "lX" -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTo__ "lo" -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTu__ "lu" -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTx__ "lx" -// WEBASSEMBLY32-NEXT:#define __SIZE_MAX__ 4294967295UL -// WEBASSEMBLY32-NEXT:#define __SIZE_TYPE__ long unsigned int -// WEBASSEMBLY32-NEXT:#define __SIZE_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __STDC_HOSTED__ 0 -// WEBASSEMBLY32-NOT:#define __STDC_MB_MIGHT_NEQ_WC__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_ATOMICS__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_COMPLEX__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_VLA__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_THREADS__ -// WEBASSEMBLY32-NEXT:#define __STDC_UTF_16__ 1 -// WEBASSEMBLY32-NEXT:#define __STDC_UTF_32__ 1 -// WEBASSEMBLY32-NEXT:#define __STDC_VERSION__ 201112L -// WEBASSEMBLY32-NEXT:#define __STDC__ 1 -// WEBASSEMBLY32-NEXT:#define __UINT16_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTX__ "hX" -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTo__ "ho" -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTu__ "hu" -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTx__ "hx" -// WEBASSEMBLY32-NEXT:#define __UINT16_MAX__ 65535 -// WEBASSEMBLY32-NEXT:#define __UINT16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __UINT32_C_SUFFIX__ U -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTX__ "X" -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTo__ "o" -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTu__ "u" -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTx__ "x" -// WEBASSEMBLY32-NEXT:#define __UINT32_MAX__ 4294967295U -// WEBASSEMBLY32-NEXT:#define __UINT32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT64_C_SUFFIX__ ULL -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINT64_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT8_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTX__ "hhX" -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTo__ "hho" -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTu__ "hhu" -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTx__ "hhx" -// WEBASSEMBLY32-NEXT:#define __UINT8_MAX__ 255 -// WEBASSEMBLY32-NEXT:#define __UINT8_TYPE__ unsigned char -// WEBASSEMBLY32-NEXT:#define __UINTMAX_C_SUFFIX__ ULL -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINTMAX_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINTMAX_WIDTH__ 64 -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTX__ "lX" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTo__ "lo" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTu__ "lu" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTx__ "lx" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_MAX__ 4294967295UL -// WEBASSEMBLY32-NEXT:#define __UINTPTR_TYPE__ long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINTPTR_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTX__ "hX" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTo__ "ho" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTu__ "hu" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTx__ "hx" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_MAX__ 65535 -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTX__ "X" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTo__ "o" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTu__ "u" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTx__ "x" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_MAX__ 4294967295U -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTX__ "hhX" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTo__ "hho" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTu__ "hhu" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTx__ "hhx" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_MAX__ 255 -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_TYPE__ unsigned char -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTX__ "hX" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTo__ "ho" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTu__ "hu" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTx__ "hx" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_MAX__ 65535 -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTX__ "X" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTo__ "o" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTu__ "u" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTx__ "x" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTX__ "hhX" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTo__ "hho" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTu__ "hhu" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTx__ "hhx" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_MAX__ 255 -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char -// WEBASSEMBLY32-NEXT:#define __USER_LABEL_PREFIX__ -// WEBASSEMBLY32-NEXT:#define __VERSION__ "{{.*}}" -// WEBASSEMBLY32-NEXT:#define __WCHAR_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __WCHAR_TYPE__ int -// WEBASSEMBLY32-NOT:#define __WCHAR_UNSIGNED__ -// WEBASSEMBLY32-NEXT:#define __WCHAR_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __WINT_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __WINT_TYPE__ int -// WEBASSEMBLY32-NOT:#define __WINT_UNSIGNED__ -// WEBASSEMBLY32-NEXT:#define __WINT_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __clang__ 1 -// WEBASSEMBLY32-NEXT:#define __clang_major__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __clang_minor__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __clang_patchlevel__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __clang_version__ "{{.*}}" -// WEBASSEMBLY32-NEXT:#define __llvm__ 1 -// WEBASSEMBLY32-NOT:#define __wasm_simd128__ -// WEBASSEMBLY32-NOT:#define __wasm_simd256__ -// WEBASSEMBLY32-NOT:#define __wasm_simd512__ -// WEBASSEMBLY32-NOT:#define __unix -// WEBASSEMBLY32-NOT:#define __unix__ -// WEBASSEMBLY32-NEXT:#define __wasm 1 -// WEBASSEMBLY32-NEXT:#define __wasm32 1 -// WEBASSEMBLY32-NEXT:#define __wasm32__ 1 -// WEBASSEMBLY32-NOT:#define __wasm64 -// WEBASSEMBLY32-NOT:#define __wasm64__ -// WEBASSEMBLY32-NEXT:#define __wasm__ 1 -// -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \ -// RUN: < /dev/null \ -// RUN: | FileCheck -match-full-lines -check-prefix=WEBASSEMBLY64 %s -// -// WEBASSEMBLY64-NOT:#define _ILP32 -// WEBASSEMBLY64:#define _LP64 1 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_ACQUIRE 2 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_ACQ_REL 4 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_CONSUME 1 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_RELAXED 0 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_RELEASE 3 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_SEQ_CST 5 -// WEBASSEMBLY64-NEXT:#define __BIGGEST_ALIGNMENT__ 16 -// WEBASSEMBLY64-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -// WEBASSEMBLY64-NEXT:#define __CHAR16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __CHAR32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __CHAR_BIT__ 8 -// WEBASSEMBLY64-NOT:#define __CHAR_UNSIGNED__ -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CONSTANT_CFSTRINGS__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_DECIMAL_DIG__ 17 -// WEBASSEMBLY64-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 -// WEBASSEMBLY64-NEXT:#define __DBL_DIG__ 15 -// WEBASSEMBLY64-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16 -// WEBASSEMBLY64-NEXT:#define __DBL_HAS_DENORM__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_HAS_INFINITY__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_MANT_DIG__ 53 -// WEBASSEMBLY64-NEXT:#define __DBL_MAX_10_EXP__ 308 -// WEBASSEMBLY64-NEXT:#define __DBL_MAX_EXP__ 1024 -// WEBASSEMBLY64-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308 -// WEBASSEMBLY64-NEXT:#define __DBL_MIN_10_EXP__ (-307) -// WEBASSEMBLY64-NEXT:#define __DBL_MIN_EXP__ (-1021) -// WEBASSEMBLY64-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308 -// WEBASSEMBLY64-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ -// WEBASSEMBLY64-NOT:#define __ELF__ -// WEBASSEMBLY64-NEXT:#define __FINITE_MATH_ONLY__ 0 -// WEBASSEMBLY64:#define __FLT_DECIMAL_DIG__ 9 -// WEBASSEMBLY64-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F -// WEBASSEMBLY64-NEXT:#define __FLT_DIG__ 6 -// WEBASSEMBLY64-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F -// WEBASSEMBLY64-NEXT:#define __FLT_EVAL_METHOD__ 0 -// WEBASSEMBLY64-NEXT:#define __FLT_HAS_DENORM__ 1 -// WEBASSEMBLY64-NEXT:#define __FLT_HAS_INFINITY__ 1 -// WEBASSEMBLY64-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY64-NEXT:#define __FLT_MANT_DIG__ 24 -// WEBASSEMBLY64-NEXT:#define __FLT_MAX_10_EXP__ 38 -// WEBASSEMBLY64-NEXT:#define __FLT_MAX_EXP__ 128 -// WEBASSEMBLY64-NEXT:#define __FLT_MAX__ 3.40282347e+38F -// WEBASSEMBLY64-NEXT:#define __FLT_MIN_10_EXP__ (-37) -// WEBASSEMBLY64-NEXT:#define __FLT_MIN_EXP__ (-125) -// WEBASSEMBLY64-NEXT:#define __FLT_MIN__ 1.17549435e-38F -// WEBASSEMBLY64-NEXT:#define __FLT_RADIX__ 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GNUC_MINOR__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __GNUC_STDC_INLINE__ 1 -// WEBASSEMBLY64-NEXT:#define __GNUC__ {{.}} -// WEBASSEMBLY64-NEXT:#define __GXX_ABI_VERSION 1002 -// WEBASSEMBLY64-NOT:#define __ILP32__ -// WEBASSEMBLY64-NEXT:#define __INT16_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __INT16_FMTd__ "hd" -// WEBASSEMBLY64-NEXT:#define __INT16_FMTi__ "hi" -// WEBASSEMBLY64-NEXT:#define __INT16_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __INT16_TYPE__ short -// WEBASSEMBLY64-NEXT:#define __INT32_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __INT32_FMTd__ "d" -// WEBASSEMBLY64-NEXT:#define __INT32_FMTi__ "i" -// WEBASSEMBLY64-NEXT:#define __INT32_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __INT32_TYPE__ int -// WEBASSEMBLY64-NEXT:#define __INT64_C_SUFFIX__ LL -// WEBASSEMBLY64-NEXT:#define __INT64_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INT64_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INT64_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INT64_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INT8_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __INT8_FMTd__ "hhd" -// WEBASSEMBLY64-NEXT:#define __INT8_FMTi__ "hhi" -// WEBASSEMBLY64-NEXT:#define __INT8_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __INT8_TYPE__ signed char -// WEBASSEMBLY64-NEXT:#define __INTMAX_C_SUFFIX__ LL -// WEBASSEMBLY64-NEXT:#define __INTMAX_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INTMAX_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INTMAX_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INTMAX_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __INTPTR_FMTd__ "ld" -// WEBASSEMBLY64-NEXT:#define __INTPTR_FMTi__ "li" -// WEBASSEMBLY64-NEXT:#define __INTPTR_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __INTPTR_TYPE__ long int -// WEBASSEMBLY64-NEXT:#define __INTPTR_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_FMTd__ "hd" -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_FMTi__ "hi" -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_TYPE__ short -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_FMTd__ "d" -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_FMTi__ "i" -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_TYPE__ int -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_FMTd__ "hhd" -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_FMTi__ "hhi" -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_TYPE__ signed char -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_FMTd__ "hd" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_FMTi__ "hi" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_TYPE__ short -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_FMTd__ "d" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_FMTi__ "i" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_TYPE__ int -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_FMTd__ "hhd" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_FMTi__ "hhi" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_TYPE__ signed char -// WEBASSEMBLY64-NEXT:#define __INT_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __LDBL_DECIMAL_DIG__ 36 -// WEBASSEMBLY64-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L -// WEBASSEMBLY64-NEXT:#define __LDBL_DIG__ 33 -// WEBASSEMBLY64-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L -// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_DENORM__ 1 -// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_INFINITY__ 1 -// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY64-NEXT:#define __LDBL_MANT_DIG__ 113 -// WEBASSEMBLY64-NEXT:#define __LDBL_MAX_10_EXP__ 4932 -// WEBASSEMBLY64-NEXT:#define __LDBL_MAX_EXP__ 16384 -// WEBASSEMBLY64-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L -// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_10_EXP__ (-4931) -// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_EXP__ (-16381) -// WEBASSEMBLY64-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L -// WEBASSEMBLY64-NEXT:#define __LITTLE_ENDIAN__ 1 -// WEBASSEMBLY64-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __LP64__ 1 -// WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1 -// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 -// WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321 -// WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234 -// WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412 -// WEBASSEMBLY64-NEXT:#define __POINTER_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1 -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_FMTd__ "ld" -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_FMTi__ "li" -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_TYPE__ long int -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_WIDTH__ 64 -// WEBASSEMBLY64-NOT:#define __REGISTER_PREFIX__ -// WEBASSEMBLY64-NEXT:#define __SCHAR_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __SHRT_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_DOUBLE__ 8 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_FLOAT__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_INT128__ 16 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_INT__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG_LONG__ 8 // WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG__ 8 // WEBASSEMBLY64-NEXT:#define __SIZEOF_POINTER__ 8 // WEBASSEMBLY64-NEXT:#define __SIZEOF_PTRDIFF_T__ 8 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_SHORT__ 2 +// WEBASSEMBLY-NEXT:#define __SIZEOF_SHORT__ 2 +// WEBASSEMBLY32-NEXT:#define __SIZEOF_SIZE_T__ 4 // WEBASSEMBLY64-NEXT:#define __SIZEOF_SIZE_T__ 8 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_WCHAR_T__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_WINT_T__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTX__ "lX" -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTo__ "lo" -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTu__ "lu" -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTx__ "lx" +// WEBASSEMBLY-NEXT:#define __SIZEOF_WCHAR_T__ 4 +// WEBASSEMBLY-NEXT:#define __SIZEOF_WINT_T__ 4 +// WEBASSEMBLY-NEXT:#define __SIZE_FMTX__ "lX" +// WEBASSEMBLY-NEXT:#define __SIZE_FMTo__ "lo" +// WEBASSEMBLY-NEXT:#define __SIZE_FMTu__ "lu" +// WEBASSEMBLY-NEXT:#define __SIZE_FMTx__ "lx" +// WEBASSEMBLY32-NEXT:#define __SIZE_MAX__ 4294967295UL // WEBASSEMBLY64-NEXT:#define __SIZE_MAX__ 18446744073709551615UL -// WEBASSEMBLY64-NEXT:#define __SIZE_TYPE__ long unsigned int +// WEBASSEMBLY-NEXT:#define __SIZE_TYPE__ long unsigned int +// WEBASSEMBLY32-NEXT:#define __SIZE_WIDTH__ 32 // WEBASSEMBLY64-NEXT:#define __SIZE_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __STDC_HOSTED__ 0 -// WEBASSEMBLY64-NOT:#define __STDC_MB_MIGHT_NEQ_WC__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_ATOMICS__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_COMPLEX__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_VLA__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_THREADS__ -// WEBASSEMBLY64-NEXT:#define __STDC_UTF_16__ 1 -// WEBASSEMBLY64-NEXT:#define __STDC_UTF_32__ 1 -// WEBASSEMBLY64-NEXT:#define __STDC_VERSION__ 201112L -// WEBASSEMBLY64-NEXT:#define __STDC__ 1 -// WEBASSEMBLY64-NEXT:#define __UINT16_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTX__ "hX" -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTo__ "ho" -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTu__ "hu" -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTx__ "hx" -// WEBASSEMBLY64-NEXT:#define __UINT16_MAX__ 65535 -// WEBASSEMBLY64-NEXT:#define __UINT16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __UINT32_C_SUFFIX__ U -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTX__ "X" -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTo__ "o" -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTu__ "u" -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTx__ "x" -// WEBASSEMBLY64-NEXT:#define __UINT32_MAX__ 4294967295U -// WEBASSEMBLY64-NEXT:#define __UINT32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT64_C_SUFFIX__ ULL -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINT64_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT8_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTX__ "hhX" -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTo__ "hho" -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTu__ "hhu" -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTx__ "hhx" -// WEBASSEMBLY64-NEXT:#define __UINT8_MAX__ 255 -// WEBASSEMBLY64-NEXT:#define __UINT8_TYPE__ unsigned char -// WEBASSEMBLY64-NEXT:#define __UINTMAX_C_SUFFIX__ ULL -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINTMAX_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINTMAX_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTX__ "lX" -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTo__ "lo" -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTu__ "lu" -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTx__ "lx" +// WEBASSEMBLY-NEXT:#define __STDC_HOSTED__ 0 +// WEBASSEMBLY-NOT:#define __STDC_MB_MIGHT_NEQ_WC__ +// WEBASSEMBLY-NOT:#define __STDC_NO_ATOMICS__ +// WEBASSEMBLY-NOT:#define __STDC_NO_COMPLEX__ +// WEBASSEMBLY-NOT:#define __STDC_NO_VLA__ +// WEBASSEMBLY-NOT:#define __STDC_NO_THREADS__ +// WEBASSEMBLY-NEXT:#define __STDC_UTF_16__ 1 +// WEBASSEMBLY-NEXT:#define __STDC_UTF_32__ 1 +// WEBASSEMBLY-NEXT:#define __STDC_VERSION__ 201112L +// WEBASSEMBLY-NEXT:#define __STDC__ 1 +// WEBASSEMBLY-NEXT:#define __UINT16_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __UINT16_FMTX__ "hX" +// WEBASSEMBLY-NEXT:#define __UINT16_FMTo__ "ho" +// WEBASSEMBLY-NEXT:#define __UINT16_FMTu__ "hu" +// WEBASSEMBLY-NEXT:#define __UINT16_FMTx__ "hx" +// WEBASSEMBLY-NEXT:#define __UINT16_MAX__ 65535 +// WEBASSEMBLY-NEXT:#define __UINT16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT32_C_SUFFIX__ U +// WEBASSEMBLY-NEXT:#define __UINT32_FMTX__ "X" +// WEBASSEMBLY-NEXT:#define __UINT32_FMTo__ "o" +// WEBASSEMBLY-NEXT:#define __UINT32_FMTu__ "u" +// WEBASSEMBLY-NEXT:#define __UINT32_FMTx__ "x" +// WEBASSEMBLY-NEXT:#define __UINT32_MAX__ 4294967295U +// WEBASSEMBLY-NEXT:#define __UINT32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT64_C_SUFFIX__ ULL +// WEBASSEMBLY-NEXT:#define __UINT64_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINT64_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINT64_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINT64_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINT64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT8_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __UINT8_FMTX__ "hhX" +// WEBASSEMBLY-NEXT:#define __UINT8_FMTo__ "hho" +// WEBASSEMBLY-NEXT:#define __UINT8_FMTu__ "hhu" +// WEBASSEMBLY-NEXT:#define __UINT8_FMTx__ "hhx" +// WEBASSEMBLY-NEXT:#define __UINT8_MAX__ 255 +// WEBASSEMBLY-NEXT:#define __UINT8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __UINTMAX_C_SUFFIX__ ULL +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINTMAX_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINTMAX_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTX__ "lX" +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTo__ "lo" +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTu__ "lu" +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTx__ "lx" +// WEBASSEMBLY32-NEXT:#define __UINTPTR_MAX__ 4294967295UL // WEBASSEMBLY64-NEXT:#define __UINTPTR_MAX__ 18446744073709551615UL -// WEBASSEMBLY64-NEXT:#define __UINTPTR_TYPE__ long unsigned int +// WEBASSEMBLY-NEXT:#define __UINTPTR_TYPE__ long unsigned int +// WEBASSEMBLY32-NEXT:#define __UINTPTR_WIDTH__ 32 // WEBASSEMBLY64-NEXT:#define __UINTPTR_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTX__ "hX" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTo__ "ho" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTu__ "hu" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTx__ "hx" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_MAX__ 65535 -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTX__ "X" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTo__ "o" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTu__ "u" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTx__ "x" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_MAX__ 4294967295U -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTX__ "hhX" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTo__ "hho" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTu__ "hhu" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTx__ "hhx" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_MAX__ 255 -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_TYPE__ unsigned char -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTX__ "hX" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTo__ "ho" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTu__ "hu" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTx__ "hx" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_MAX__ 65535 -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTX__ "X" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTo__ "o" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTu__ "u" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTx__ "x" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTX__ "hhX" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTo__ "hho" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTu__ "hhu" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTx__ "hhx" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_MAX__ 255 -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char -// WEBASSEMBLY64-NEXT:#define __USER_LABEL_PREFIX__ -// WEBASSEMBLY64-NEXT:#define __VERSION__ "{{.*}}" -// WEBASSEMBLY64-NEXT:#define __WCHAR_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __WCHAR_TYPE__ int -// WEBASSEMBLY64-NOT:#define __WCHAR_UNSIGNED__ -// WEBASSEMBLY64-NEXT:#define __WCHAR_WIDTH__ 32 -// WEBASSEMBLY64-NEXT:#define __WINT_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __WINT_TYPE__ int -// WEBASSEMBLY64-NOT:#define __WINT_UNSIGNED__ -// WEBASSEMBLY64-NEXT:#define __WINT_WIDTH__ 32 -// WEBASSEMBLY64-NEXT:#define __clang__ 1 -// WEBASSEMBLY64-NEXT:#define __clang_major__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __clang_minor__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __clang_patchlevel__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __clang_version__ "{{.*}}" -// WEBASSEMBLY64-NEXT:#define __llvm__ 1 -// WEBASSEMBLY64-NOT:#define __wasm_simd128__ -// WEBASSEMBLY64-NOT:#define __wasm_simd256__ -// WEBASSEMBLY64-NOT:#define __wasm_simd512__ -// WEBASSEMBLY64-NOT:#define __unix -// WEBASSEMBLY64-NOT:#define __unix__ -// WEBASSEMBLY64-NEXT:#define __wasm 1 +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTX__ "hX" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTo__ "ho" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTu__ "hu" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTx__ "hx" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_MAX__ 65535 +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTX__ "X" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTo__ "o" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTu__ "u" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTx__ "x" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_MAX__ 4294967295U +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTX__ "hhX" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTo__ "hho" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTu__ "hhu" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTx__ "hhx" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_MAX__ 255 +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTX__ "hX" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTo__ "ho" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTu__ "hu" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTx__ "hx" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_MAX__ 65535 +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTX__ "X" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTo__ "o" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTu__ "u" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTx__ "x" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTX__ "hhX" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTo__ "hho" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTu__ "hhu" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTx__ "hhx" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_MAX__ 255 +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __USER_LABEL_PREFIX__ +// WEBASSEMBLY-NEXT:#define __VERSION__ "{{.*}}" +// WEBASSEMBLY-NEXT:#define __WCHAR_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __WCHAR_TYPE__ int +// WEBASSEMBLY-NOT:#define __WCHAR_UNSIGNED__ +// WEBASSEMBLY-NEXT:#define __WCHAR_WIDTH__ 32 +// WEBASSEMBLY-NEXT:#define __WINT_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __WINT_TYPE__ int +// WEBASSEMBLY-NOT:#define __WINT_UNSIGNED__ +// WEBASSEMBLY-NEXT:#define __WINT_WIDTH__ 32 +// WEBASSEMBLY-NEXT:#define __clang__ 1 +// WEBASSEMBLY-NEXT:#define __clang_major__ {{.*}} +// WEBASSEMBLY-NEXT:#define __clang_minor__ {{.*}} +// WEBASSEMBLY-NEXT:#define __clang_patchlevel__ {{.*}} +// WEBASSEMBLY-NEXT:#define __clang_version__ "{{.*}}" +// WEBASSEMBLY-NEXT:#define __llvm__ 1 +// WEBASSEMBLY-NOT:#define __unix +// WEBASSEMBLY-NOT:#define __unix__ +// WEBASSEMBLY-WASI-NEXT:#define __wasi__ 1 +// WEBASSEMBLY-NOT:#define __wasm_simd128__ +// WEBASSEMBLY-NOT:#define __wasm_simd256__ +// WEBASSEMBLY-NOT:#define __wasm_simd512__ +// WEBASSEMBLY-NEXT:#define __wasm 1 +// WEBASSEMBLY32-NEXT:#define __wasm32 1 // WEBASSEMBLY64-NOT:#define __wasm32 +// WEBASSEMBLY32-NEXT:#define __wasm32__ 1 // WEBASSEMBLY64-NOT:#define __wasm32__ +// WEBASSEMBLY32-NOT:#define __wasm64__ +// WEBASSEMBLY32-NOT:#define __wasm64 // WEBASSEMBLY64-NEXT:#define __wasm64 1 // WEBASSEMBLY64-NEXT:#define __wasm64__ 1 -// WEBASSEMBLY64-NEXT:#define __wasm__ 1 +// WEBASSEMBLY-NEXT:#define __wasm__ 1 // RUN: %clang_cc1 -E -dM -ffreestanding -triple i686-windows-cygnus < /dev/null | FileCheck -match-full-lines -check-prefix CYGWIN-X32 %s // CYGWIN-X32: #define __USER_LABEL_PREFIX__ _ diff --git a/test/Sema/Float16.c b/test/Sema/Float16.c new file mode 100644 index 000000000000..bdfb01702c37 --- /dev/null +++ b/test/Sema/Float16.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE + +#ifdef HAVE +// expected-no-diagnostics +#else +// expected-error@+2{{_Float16 is not supported on this target}} +#endif // HAVE +_Float16 f; diff --git a/test/SemaCXX/Float16.cpp b/test/SemaCXX/Float16.cpp new file mode 100644 index 000000000000..f27c3839854e --- /dev/null +++ b/test/SemaCXX/Float16.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE + +#ifdef HAVE +// expected-no-diagnostics +#endif // HAVE + +#ifndef HAVE +// expected-error@+2{{_Float16 is not supported on this target}} +#endif // !HAVE +_Float16 f; + +#ifndef HAVE +// expected-error@+2{{invalid suffix 'F16' on floating constant}} +#endif // !HAVE +const auto g = 1.1F16; diff --git a/test/SemaCXX/PR40395.cpp b/test/SemaCXX/PR40395.cpp new file mode 100644 index 000000000000..469c86d56209 --- /dev/null +++ b/test/SemaCXX/PR40395.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++17 -fms-extensions -triple=x86_64-pc-win32 -verify %s +// expected-no-diagnostics + +// PR40395 - ConstantExpr shouldn't cause the template object to infinitely +// expand. +struct _GUID {}; +struct __declspec(uuid("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}")) B {}; + +template +struct A { + virtual void baz() { A(); } +}; + +void f() { + A<&__uuidof(B)>(); +} diff --git a/test/SemaCXX/cxx1z-decomposition.cpp b/test/SemaCXX/cxx1z-decomposition.cpp index 3c9b181f1c8f..8b5fd6809bb4 100644 --- a/test/SemaCXX/cxx1z-decomposition.cpp +++ b/test/SemaCXX/cxx1z-decomposition.cpp @@ -81,4 +81,21 @@ struct PR37352 { void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}} }; +namespace instantiate_template { + +template +struct pair { + T1 a; + T2 b; +}; + +const pair &f1(); + +int f2() { + const auto &[a, b] = f1(); + return a + b; +} + +} // namespace instantiate_template + // FIXME: by-value array copies diff --git a/test/SemaObjC/enum-fixed-type.m b/test/SemaObjC/enum-fixed-type.m index 88c895a33982..b4135a555a23 100644 --- a/test/SemaObjC/enum-fixed-type.m +++ b/test/SemaObjC/enum-fixed-type.m @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -xc %s +#ifdef __OBJC__ #if !__has_feature(objc_fixed_enum) # error Enumerations with a fixed underlying type are not supported #endif +#endif #if !__has_extension(cxx_fixed_enum) # error Enumerations with a fixed underlying type are not supported diff --git a/test/SemaOpenCL/printf-format-string-warnings.cl b/test/SemaOpenCL/printf-format-string-warnings.cl index 2b9c5cc3f319..39b859402702 100644 --- a/test/SemaOpenCL/printf-format-string-warnings.cl +++ b/test/SemaOpenCL/printf-format-string-warnings.cl @@ -1,13 +1,14 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header -// Make sure warnings are produced based on printf format strings. +// FIXME: Make sure warnings are produced based on printf format strings. +// expected-no-diagnostics kernel void format_string_warnings(__constant char* arg) { - printf("%d", arg); // expected-warning {{format specifies type 'int' but the argument has type '__constant char *'}} + printf("%d", arg); - printf("not enough arguments %d %d", 4); // expected-warning {{more '%' conversions than data arguments}} + printf("not enough arguments %d %d", 4); - printf("too many arguments", 4); // expected-warning {{data argument not used by format string}} + printf("too many arguments", 4); } diff --git a/test/SemaOpenCL/printf-format-strings.cl b/test/SemaOpenCL/printf-format-strings.cl index 079a83495685..212e1f8981cb 100644 --- a/test/SemaOpenCL/printf-format-strings.cl +++ b/test/SemaOpenCL/printf-format-strings.cl @@ -13,10 +13,10 @@ int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2))) kernel void format_v4f32(float4 arg) { #ifdef cl_khr_fp64 - printf("%v4f\n", arg); + printf("%v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}} // Precision modifier - printf("%.2v4f\n", arg); + printf("%.2v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}} #else // FIXME: These should not warn, and the type should be expected to be float. printf("%v4f\n", arg); // expected-warning {{double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}} diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp index 746d9ad5e89b..8e98f44fa46d 100644 --- a/unittests/Basic/FileManagerTest.cpp +++ b/unittests/Basic/FileManagerTest.cpp @@ -222,33 +222,6 @@ TEST_F(FileManagerTest, getFileReturnsNULLForNonexistentFile) { EXPECT_EQ(nullptr, file); } -// When calling getFile(OpenFile=false); getFile(OpenFile=true) the file is -// opened for the second call. -TEST_F(FileManagerTest, getFileDefersOpen) { - llvm::IntrusiveRefCntPtr FS( - new llvm::vfs::InMemoryFileSystem()); - FS->addFile("/tmp/test", 0, llvm::MemoryBuffer::getMemBufferCopy("test")); - FS->addFile("/tmp/testv", 0, llvm::MemoryBuffer::getMemBufferCopy("testv")); - FileManager manager(options, FS); - - const FileEntry *file = manager.getFile("/tmp/test", /*OpenFile=*/false); - ASSERT_TRUE(file != nullptr); - ASSERT_TRUE(file->isValid()); - // "real path name" reveals whether the file was actually opened. - EXPECT_FALSE(file->isOpenForTests()); - - file = manager.getFile("/tmp/test", /*OpenFile=*/true); - ASSERT_TRUE(file != nullptr); - ASSERT_TRUE(file->isValid()); - EXPECT_TRUE(file->isOpenForTests()); - - // However we should never try to open a file previously opened as virtual. - ASSERT_TRUE(manager.getVirtualFile("/tmp/testv", 5, 0)); - ASSERT_TRUE(manager.getFile("/tmp/testv", /*OpenFile=*/false)); - file = manager.getFile("/tmp/testv", /*OpenFile=*/true); - EXPECT_FALSE(file->isOpenForTests()); -} - // The following tests apply to Unix-like system only. #ifndef _WIN32 diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp index 186463f80af7..5813552a6cd3 100644 --- a/unittests/Tooling/ToolingTest.cpp +++ b/unittests/Tooling/ToolingTest.cpp @@ -450,6 +450,37 @@ TEST(ClangToolTest, StripDependencyFileAdjuster) { EXPECT_TRUE(HasFlag("-w")); } +// Check getClangStripPluginsAdjuster strips plugin related args. +TEST(ClangToolTest, StripPluginsAdjuster) { + FixedCompilationDatabase Compilations( + "/", {"-Xclang", "-add-plugin", "-Xclang", "random-plugin"}); + + ClangTool Tool(Compilations, std::vector(1, "/a.cc")); + Tool.mapVirtualFile("/a.cc", "void a() {}"); + + std::unique_ptr Action( + newFrontendActionFactory()); + + CommandLineArguments FinalArgs; + ArgumentsAdjuster CheckFlagsAdjuster = + [&FinalArgs](const CommandLineArguments &Args, StringRef /*unused*/) { + FinalArgs = Args; + return Args; + }; + Tool.clearArgumentsAdjusters(); + Tool.appendArgumentsAdjuster(getStripPluginsAdjuster()); + Tool.appendArgumentsAdjuster(CheckFlagsAdjuster); + Tool.run(Action.get()); + + auto HasFlag = [&FinalArgs](const std::string &Flag) { + return std::find(FinalArgs.begin(), FinalArgs.end(), Flag) != + FinalArgs.end(); + }; + EXPECT_FALSE(HasFlag("-Xclang")); + EXPECT_FALSE(HasFlag("-add-plugin")); + EXPECT_FALSE(HasFlag("-random-plugin")); +} + namespace { /// Find a target name such that looking for it in TargetRegistry by that name /// returns the same target. We expect that there is at least one target From 648606c4b555111c26c44a5fb51bc827d8039515 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 5 Feb 2019 18:39:32 +0000 Subject: [PATCH 4/7] Vendor import of compiler-rt release_80 branch r353167: https://llvm.org/svn/llvm-project/compiler-rt/branches/release_80@353167 --- cmake/config-ix.cmake | 1 + lib/xray/tests/CMakeLists.txt | 3 ++- test/CMakeLists.txt | 4 ---- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index db5c4645dc0a..5b9433877178 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -118,6 +118,7 @@ check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +check_library_exists(execinfo backtrace "" COMPILER_RT_HAS_LIBEXECINFO) # Look for terminfo library, used in unittests that depend on LLVMSupport. if(LLVM_ENABLE_TERMINFO) diff --git a/lib/xray/tests/CMakeLists.txt b/lib/xray/tests/CMakeLists.txt index 89a2b3b01ed8..deddc5101e76 100644 --- a/lib/xray/tests/CMakeLists.txt +++ b/lib/xray/tests/CMakeLists.txt @@ -71,13 +71,14 @@ if (NOT APPLE) endforeach() # We also add the actual libraries to link as dependencies. - list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMTestingSupport) + list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMDemangle -lLLVMTestingSupport) endif() append_list_if(COMPILER_RT_HAS_LIBM -lm XRAY_UNITTEST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBRT -lrt XRAY_UNITTEST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBDL -ldl XRAY_UNITTEST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread XRAY_UNITTEST_LINK_FLAGS) + append_list_if(COMPILER_RT_HAS_LIBEXECINFO -lexecinfo XRAY_UNITTEST_LINK_FLAGS) endif() macro(add_xray_unittest testname) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2e239d54e29c..7070fb789520 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,10 +14,6 @@ if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE) list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS profile) endif() -if(COMPILER_RT_STANDALONE_BUILD) - list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS FileCheck) -endif() - # When ANDROID, we build tests with the host compiler (i.e. CMAKE_C_COMPILER), # and run tests with tools from the host toolchain. if(NOT ANDROID) From e74ddc8e09294f9ea07d54cbe120ad82579d7beb Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 5 Feb 2019 18:39:44 +0000 Subject: [PATCH 5/7] Vendor import of libc++ release_80 branch r353167: https://llvm.org/svn/llvm-project/libcxx/branches/release_80@353167 --- cmake/Modules/HandleOutOfTreeLLVM.cmake | 2 +- .../new.delete.array/delete_align_val_t_replace.pass.cpp | 8 +++++--- .../new.delete/new.delete.array/new_align_val_t.pass.cpp | 8 +++++--- .../new.delete.array/new_align_val_t_nothrow.pass.cpp | 8 +++++--- .../new_align_val_t_nothrow_replace.pass.cpp | 8 +++++--- .../new.delete.single/delete_align_val_t_replace.pass.cpp | 8 +++++--- .../new.delete/new.delete.single/new_align_val_t.pass.cpp | 8 +++++--- .../new.delete.single/new_align_val_t_nothrow.pass.cpp | 8 +++++--- .../new_align_val_t_nothrow_replace.pass.cpp | 8 +++++--- 9 files changed, 41 insertions(+), 25 deletions(-) diff --git a/cmake/Modules/HandleOutOfTreeLLVM.cmake b/cmake/Modules/HandleOutOfTreeLLVM.cmake index 70eed1d70ba1..11c13315585b 100644 --- a/cmake/Modules/HandleOutOfTreeLLVM.cmake +++ b/cmake/Modules/HandleOutOfTreeLLVM.cmake @@ -116,7 +116,7 @@ macro(configure_out_of_tree_llvm) # Required LIT Configuration ------------------------------------------------ # Define the default arguments to use with 'lit', and an option for the user # to override. - set(LLVM_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") + set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") if (MSVC OR XCODE) set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp index 4dd9390c4fdc..bd20e090637d 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp @@ -17,9 +17,11 @@ // None of the current GCC compilers support this. // UNSUPPORTED: gcc-5, gcc-6 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp index d6194b00aa02..6b4e1c1924b4 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp @@ -15,9 +15,11 @@ // FIXME change this to XFAIL. // UNSUPPORTED: no-aligned-allocation && !gcc -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp index 59878aefd18a..3188cc587dde 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp @@ -15,9 +15,11 @@ // FIXME turn this into an XFAIL // UNSUPPORTED: no-aligned-allocation && !gcc -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp index fc713dbf8ed8..29d8fd06a701 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp @@ -10,9 +10,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // UNSUPPORTED: sanitizer-new-delete -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp index 19cabcce1edd..c01e39915ec0 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp @@ -16,9 +16,11 @@ // None of the current GCC compilers support this. // UNSUPPORTED: gcc-5, gcc-6 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13 +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp index 7cf1aca3b9f8..8cb40885c466 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp @@ -9,9 +9,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp index dd2666e00aad..9d7f13bee328 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp @@ -9,9 +9,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13 +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp index 514a2b8afc8c..82367d7de093 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp @@ -10,9 +10,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // UNSUPPORTED: sanitizer-new-delete -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13 +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 From 774c33a182f027f50320a37542a6b47a0f9caeb3 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 5 Feb 2019 18:39:57 +0000 Subject: [PATCH 6/7] Vendor import of lld release_80 branch r353167: https://llvm.org/svn/llvm-project/lld/branches/release_80@353167 --- COFF/Chunks.cpp | 24 +++++++++++- COFF/Chunks.h | 13 ++++++- COFF/DLL.cpp | 16 +++++++- COFF/ICF.cpp | 20 +++++----- COFF/Writer.cpp | 60 ++++++++++++++++++++-------- ELF/ICF.cpp | 25 ++++++------ ELF/InputFiles.cpp | 44 ++++++++++----------- ELF/InputFiles.h | 1 - ELF/ScriptParser.cpp | 65 +++++++++++++------------------ ELF/SyntheticSections.cpp | 4 +- MinGW/Options.td | 6 +++ docs/ReleaseNotes.rst | 10 +++++ test/COFF/arm-thumb-thunks-pdb.s | 18 +++++++++ test/COFF/arm64-branch-range.test | 16 -------- test/COFF/arm64-thunks.s | 27 +++++++++++++ test/COFF/imports.test | 13 +++++++ test/ELF/arm-gnu-ifunc.s | 5 ++- test/ELF/comdat-linkonce.s | 7 +++- test/ELF/emulation-aarch64.s | 23 +++++++++++ test/ELF/emulation-ppc.s | 32 +++++++++++++++ test/ELF/emulation-x86.s | 10 ++++- test/ELF/no-discard-this_module.s | 41 +++++++++++++++++++ test/ELF/sht-group-empty.test | 55 ++++++++++++++++++++++++++ 23 files changed, 411 insertions(+), 124 deletions(-) create mode 100644 test/COFF/arm-thumb-thunks-pdb.s delete mode 100644 test/COFF/arm64-branch-range.test create mode 100644 test/COFF/arm64-thunks.s create mode 100644 test/ELF/no-discard-this_module.s create mode 100644 test/ELF/sht-group-empty.test diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp index 29131d7eb8db..2bb9aa01e539 100644 --- a/COFF/Chunks.cpp +++ b/COFF/Chunks.cpp @@ -669,18 +669,38 @@ const uint8_t ArmThunk[] = { 0xe7, 0x44, // L1: add pc, ip }; -size_t RangeExtensionThunk::getSize() const { +size_t RangeExtensionThunkARM::getSize() const { assert(Config->Machine == ARMNT); return sizeof(ArmThunk); } -void RangeExtensionThunk::writeTo(uint8_t *Buf) const { +void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const { assert(Config->Machine == ARMNT); uint64_t Offset = Target->getRVA() - RVA - 12; memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk)); applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset)); } +// A position independent ARM64 adrp+add thunk, with a maximum range of +// +/- 4 GB, which is enough for any PE-COFF. +const uint8_t Arm64Thunk[] = { + 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest + 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest + 0x00, 0x02, 0x1f, 0xd6, // br x16 +}; + +size_t RangeExtensionThunkARM64::getSize() const { + assert(Config->Machine == ARM64); + return sizeof(Arm64Thunk); +} + +void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const { + assert(Config->Machine == ARM64); + memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk)); + applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12); + applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0); +} + void LocalImportChunk::getBaserels(std::vector *Res) { Res->emplace_back(getRVA()); } diff --git a/COFF/Chunks.h b/COFF/Chunks.h index f8a0ddd8ef3b..e132fdf8adfa 100644 --- a/COFF/Chunks.h +++ b/COFF/Chunks.h @@ -355,9 +355,18 @@ class ImportThunkChunkARM64 : public Chunk { Defined *ImpSymbol; }; -class RangeExtensionThunk : public Chunk { +class RangeExtensionThunkARM : public Chunk { public: - explicit RangeExtensionThunk(Defined *T) : Target(T) {} + explicit RangeExtensionThunkARM(Defined *T) : Target(T) {} + size_t getSize() const override; + void writeTo(uint8_t *Buf) const override; + + Defined *Target; +}; + +class RangeExtensionThunkARM64 : public Chunk { +public: + explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {} size_t getSize() const override; void writeTo(uint8_t *Buf) const override; diff --git a/COFF/DLL.cpp b/COFF/DLL.cpp index 599cc5892a16..c06027d3e5c3 100644 --- a/COFF/DLL.cpp +++ b/COFF/DLL.cpp @@ -47,6 +47,7 @@ class HintNameChunk : public Chunk { } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); write16le(Buf + OutputSectionOff, Hint); memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size()); } @@ -63,7 +64,10 @@ class LookupChunk : public Chunk { size_t getSize() const override { return Config->Wordsize; } void writeTo(uint8_t *Buf) const override { - write32le(Buf + OutputSectionOff, HintName->getRVA()); + if (Config->is64()) + write64le(Buf + OutputSectionOff, HintName->getRVA()); + else + write32le(Buf + OutputSectionOff, HintName->getRVA()); } Chunk *HintName; @@ -99,6 +103,8 @@ class ImportDirectoryChunk : public Chunk { size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff); E->ImportLookupTableRVA = LookupTab->getRVA(); E->NameRVA = DLLName->getRVA(); @@ -118,6 +124,10 @@ class NullChunk : public Chunk { bool hasData() const override { return false; } size_t getSize() const override { return Size; } + void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, Size); + } + private: size_t Size; }; @@ -160,6 +170,8 @@ class DelayDirectoryChunk : public Chunk { } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff); E->Attributes = 1; E->Name = DLLName->getRVA(); @@ -392,6 +404,8 @@ class ExportDirectoryChunk : public Chunk { } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff); E->NameRVA = DLLName->getRVA(); E->OrdinalBase = 0; diff --git a/COFF/ICF.cpp b/COFF/ICF.cpp index 34ea360fa925..f6904eb7d24f 100644 --- a/COFF/ICF.cpp +++ b/COFF/ICF.cpp @@ -263,19 +263,21 @@ void ICF::run(ArrayRef Vec) { // Initially, we use hash values to partition sections. parallelForEach(Chunks, [&](SectionChunk *SC) { - SC->Class[1] = xxHash64(SC->getContents()); + SC->Class[0] = xxHash64(SC->getContents()); }); // Combine the hashes of the sections referenced by each section into its // hash. - parallelForEach(Chunks, [&](SectionChunk *SC) { - uint32_t Hash = SC->Class[1]; - for (Symbol *B : SC->symbols()) - if (auto *Sym = dyn_cast_or_null(B)) - Hash ^= Sym->getChunk()->Class[1]; - // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[0] = Hash | (1U << 31); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Chunks, [&](SectionChunk *SC) { + uint32_t Hash = SC->Class[Cnt % 2]; + for (Symbol *B : SC->symbols()) + if (auto *Sym = dyn_cast_or_null(B)) + Hash += Sym->getChunk()->Class[Cnt % 2]; + // Set MSB to 1 to avoid collisions with non-hash classs. + SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31); + }); + } // From now on, sections in Chunks are ordered so that sections in // the same group are consecutive in the vector. diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp index 258796ea6057..6acfaf9a4454 100644 --- a/COFF/Writer.cpp +++ b/COFF/Writer.cpp @@ -306,16 +306,31 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { // Check whether the target address S is in range from a relocation // of type RelType at address P. static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) { - assert(Config->Machine == ARMNT); - int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; - switch (RelType) { - case IMAGE_REL_ARM_BRANCH20T: - return isInt<21>(Diff); - case IMAGE_REL_ARM_BRANCH24T: - case IMAGE_REL_ARM_BLX23T: - return isInt<25>(Diff); - default: - return true; + if (Config->Machine == ARMNT) { + int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; + switch (RelType) { + case IMAGE_REL_ARM_BRANCH20T: + return isInt<21>(Diff); + case IMAGE_REL_ARM_BRANCH24T: + case IMAGE_REL_ARM_BLX23T: + return isInt<25>(Diff); + default: + return true; + } + } else if (Config->Machine == ARM64) { + int64_t Diff = AbsoluteDifference(S, P) + Margin; + switch (RelType) { + case IMAGE_REL_ARM64_BRANCH26: + return isInt<28>(Diff); + case IMAGE_REL_ARM64_BRANCH19: + return isInt<21>(Diff); + case IMAGE_REL_ARM64_BRANCH14: + return isInt<16>(Diff); + default: + return true; + } + } else { + llvm_unreachable("Unexpected architecture"); } } @@ -327,7 +342,17 @@ getThunk(DenseMap &LastThunks, Defined *Target, uint64_t P, Defined *&LastThunk = LastThunks[Target->getRVA()]; if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin)) return {LastThunk, false}; - RangeExtensionThunk *C = make(Target); + Chunk *C; + switch (Config->Machine) { + case ARMNT: + C = make(Target); + break; + case ARM64: + C = make(Target); + break; + default: + llvm_unreachable("Unexpected architecture"); + } Defined *D = make("", C); LastThunk = D; return {D, true}; @@ -344,14 +369,14 @@ getThunk(DenseMap &LastThunks, Defined *Target, uint64_t P, // After adding thunks, we verify that all relocations are in range (with // no extra margin requirements). If this failed, we restart (throwing away // the previously created thunks) and retry with a wider margin. -static bool createThunks(std::vector &Chunks, int Margin) { +static bool createThunks(OutputSection *OS, int Margin) { bool AddressesChanged = false; DenseMap LastThunks; size_t ThunksSize = 0; // Recheck Chunks.size() each iteration, since we can insert more // elements into it. - for (size_t I = 0; I != Chunks.size(); ++I) { - SectionChunk *SC = dyn_cast_or_null(Chunks[I]); + for (size_t I = 0; I != OS->Chunks.size(); ++I) { + SectionChunk *SC = dyn_cast_or_null(OS->Chunks[I]); if (!SC) continue; size_t ThunkInsertionSpot = I + 1; @@ -388,7 +413,8 @@ static bool createThunks(std::vector &Chunks, int Margin) { Chunk *ThunkChunk = Thunk->getChunk(); ThunkChunk->setRVA( ThunkInsertionRVA); // Estimate of where it will be located. - Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk); + ThunkChunk->setOutputSection(OS); + OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk); ThunkInsertionSpot++; ThunksSize += ThunkChunk->getSize(); ThunkInsertionRVA += ThunkChunk->getSize(); @@ -428,7 +454,7 @@ static bool verifyRanges(const std::vector Chunks) { // Assign addresses and add thunks if necessary. void Writer::finalizeAddresses() { assignAddresses(); - if (Config->Machine != ARMNT) + if (Config->Machine != ARMNT && Config->Machine != ARM64) return; size_t OrigNumChunks = 0; @@ -477,7 +503,7 @@ void Writer::finalizeAddresses() { // to avoid things going out of range due to the added thunks. bool AddressesChanged = false; for (OutputSection *Sec : OutputSections) - AddressesChanged |= createThunks(Sec->Chunks, Margin); + AddressesChanged |= createThunks(Sec, Margin); // If the verification above thought we needed thunks, we should have // added some. assert(AddressesChanged); diff --git a/ELF/ICF.cpp b/ELF/ICF.cpp index e917ae76a689..d08ac73ded80 100644 --- a/ELF/ICF.cpp +++ b/ELF/ICF.cpp @@ -426,16 +426,17 @@ void ICF::forEachClass(llvm::function_ref Fn) { // Combine the hashes of the sections referenced by the given section into its // hash. template -static void combineRelocHashes(InputSection *IS, ArrayRef Rels) { - uint32_t Hash = IS->Class[1]; +static void combineRelocHashes(unsigned Cnt, InputSection *IS, + ArrayRef Rels) { + uint32_t Hash = IS->Class[Cnt % 2]; for (RelTy Rel : Rels) { Symbol &S = IS->template getFile()->getRelocTargetSym(Rel); if (auto *D = dyn_cast(&S)) if (auto *RelSec = dyn_cast_or_null(D->Section)) - Hash ^= RelSec->Class[1]; + Hash += RelSec->Class[Cnt % 2]; } // Set MSB to 1 to avoid collisions with non-hash IDs. - IS->Class[0] = Hash | (1U << 31); + IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31); } static void print(const Twine &S) { @@ -453,15 +454,17 @@ template void ICF::run() { // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { - S->Class[1] = xxHash64(S->data()); + S->Class[0] = xxHash64(S->data()); }); - parallelForEach(Sections, [&](InputSection *S) { - if (S->AreRelocsRela) - combineRelocHashes(S, S->template relas()); - else - combineRelocHashes(S, S->template rels()); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Sections, [&](InputSection *S) { + if (S->AreRelocsRela) + combineRelocHashes(Cnt, S, S->template relas()); + else + combineRelocHashes(Cnt, S, S->template rels()); + }); + } // From now on, sections in Sections vector are ordered so that sections // in the same equivalence class are consecutive in the vector. diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp index e4d1dec7cbcb..bc7e61072e64 100644 --- a/ELF/InputFiles.cpp +++ b/ELF/InputFiles.cpp @@ -320,17 +320,6 @@ StringRef ObjFile::getShtGroupSignature(ArrayRef Sections, return Signature; } -template -ArrayRef::Elf_Word> -ObjFile::getShtGroupEntries(const Elf_Shdr &Sec) { - const ELFFile &Obj = this->getObj(); - ArrayRef Entries = - CHECK(Obj.template getSectionContentsAsArray(&Sec), this); - if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); -} - template bool ObjFile::shouldMerge(const Elf_Shdr &Sec) { // On a regular link we don't merge sections if -O0 (default is -O1). This // sometimes makes the linker significantly faster, although the output will @@ -440,26 +429,34 @@ void ObjFile::initializeSections( case SHT_GROUP: { // De-duplicate section groups by their signatures. StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; this->Sections[I] = &InputSection::Discarded; - // We only support GRP_COMDAT type of group. Get the all entries of the - // section here to let getShtGroupEntries to check the type early for us. - ArrayRef Entries = getShtGroupEntries(Sec); - // If it is a new section group, we want to keep group members. - // Group leader sections, which contain indices of group members, are - // discarded because they are useless beyond this point. The only - // exception is the -r option because in order to produce re-linkable - // object files, we want to pass through basically everything. + ArrayRef Entries = + CHECK(Obj.template getSectionContentsAsArray(&Sec), this); + if (Entries.empty()) + fatal(toString(this) + ": empty SHT_GROUP"); + + // The first word of a SHT_GROUP section contains flags. Currently, + // the standard defines only "GRP_COMDAT" flag for the COMDAT group. + // An group with the empty flag doesn't define anything; such sections + // are just skipped. + if (Entries[0] == 0) + continue; + + if (Entries[0] != GRP_COMDAT) + fatal(toString(this) + ": unsupported SHT_GROUP format"); + + bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; if (IsNew) { if (Config->Relocatable) this->Sections[I] = createInputSection(Sec); - continue; + continue; } + // Otherwise, discard group members. - for (uint32_t SecIndex : Entries) { + for (uint32_t SecIndex : Entries.slice(1)) { if (SecIndex >= Size) fatal(toString(this) + ": invalid section index in group: " + Twine(SecIndex)); @@ -739,7 +736,8 @@ InputSectionBase *ObjFile::createInputSection(const Elf_Shdr &Sec) { // sections. Drop those sections to avoid duplicate symbol errors. // FIXME: This is glibc PR20543, we should remove this hack once that has been // fixed for a while. - if (Name.startswith(".gnu.linkonce.")) + if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" || + Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx") return &InputSection::Discarded; // If we are creating a new .build-id section, strip existing .build-id diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h index 5094ddd804a5..d7cbbc67a365 100644 --- a/ELF/InputFiles.h +++ b/ELF/InputFiles.h @@ -175,7 +175,6 @@ template class ObjFile : public ELFFileBase { StringRef getShtGroupSignature(ArrayRef Sections, const Elf_Shdr &Sec); - ArrayRef getShtGroupEntries(const Elf_Shdr &Sec); public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp index eee3f0e330cc..7cce94659c9e 100644 --- a/ELF/ScriptParser.cpp +++ b/ELF/ScriptParser.cpp @@ -94,7 +94,6 @@ class ScriptParser final : ScriptLexer { SortSectionPolicy readSortKind(); SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); SymbolAssignment *readAssignment(StringRef Tok); - std::tuple readBfdName(); void readSort(); Expr readAssert(); Expr readConstant(); @@ -385,39 +384,24 @@ void ScriptParser::readOutputArch() { skip(); } -std::tuple ScriptParser::readBfdName() { - StringRef S = unquote(next()); - if (S == "elf32-i386") - return std::make_tuple(ELF32LEKind, EM_386, false); - if (S == "elf32-iamcu") - return std::make_tuple(ELF32LEKind, EM_IAMCU, false); - if (S == "elf32-littlearm") - return std::make_tuple(ELF32LEKind, EM_ARM, false); - if (S == "elf32-x86-64") - return std::make_tuple(ELF32LEKind, EM_X86_64, false); - if (S == "elf64-littleaarch64") - return std::make_tuple(ELF64LEKind, EM_AARCH64, false); - if (S == "elf64-powerpc") - return std::make_tuple(ELF64BEKind, EM_PPC64, false); - if (S == "elf64-powerpcle") - return std::make_tuple(ELF64LEKind, EM_PPC64, false); - if (S == "elf64-x86-64") - return std::make_tuple(ELF64LEKind, EM_X86_64, false); - if (S == "elf32-tradbigmips") - return std::make_tuple(ELF32BEKind, EM_MIPS, false); - if (S == "elf32-ntradbigmips") - return std::make_tuple(ELF32BEKind, EM_MIPS, true); - if (S == "elf32-tradlittlemips") - return std::make_tuple(ELF32LEKind, EM_MIPS, false); - if (S == "elf32-ntradlittlemips") - return std::make_tuple(ELF32LEKind, EM_MIPS, true); - if (S == "elf64-tradbigmips") - return std::make_tuple(ELF64BEKind, EM_MIPS, false); - if (S == "elf64-tradlittlemips") - return std::make_tuple(ELF64LEKind, EM_MIPS, false); - - setError("unknown output format name: " + S); - return std::make_tuple(ELFNoneKind, EM_NONE, false); +static std::pair parseBfdName(StringRef S) { + return StringSwitch>(S) + .Case("elf32-i386", {ELF32LEKind, EM_386}) + .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) + .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) + .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) + .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) + .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) + .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) + .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) + .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) + .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS}) + .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) + .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) + .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) + .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS}) + .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS}) + .Default({ELFNoneKind, EM_NONE}); } // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little). @@ -425,9 +409,16 @@ std::tuple ScriptParser::readBfdName() { void ScriptParser::readOutputFormat() { expect("("); - std::tuple BfdTuple = readBfdName(); - if (Config->EKind == ELFNoneKind) - std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple; + StringRef Name = unquote(next()); + StringRef S = Name; + if (S.consume_back("-freebsd")) + Config->OSABI = ELFOSABI_FREEBSD; + + std::tie(Config->EKind, Config->EMachine) = parseBfdName(S); + if (Config->EMachine == EM_NONE) + setError("unknown output format name: " + Name); + if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips") + Config->MipsN32Abi = true; if (consume(")")) return; diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index f459c1b6b479..b1a3f8bc70ae 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1513,8 +1513,10 @@ void RelocationBaseSection::finalizeContents() { else getParent()->Link = 0; - if (In.RelaIplt == this || In.RelaPlt == this) + if (In.RelaPlt == this) getParent()->Info = In.GotPlt->getParent()->SectionIndex; + if (In.RelaIplt == this) + getParent()->Info = In.IgotPlt->getParent()->SectionIndex; } RelrBaseSection::RelrBaseSection() diff --git a/MinGW/Options.td b/MinGW/Options.td index 948faa687521..0cda2447e522 100644 --- a/MinGW/Options.td +++ b/MinGW/Options.td @@ -78,3 +78,9 @@ def version: F<"version">, HelpText<"Display the version number and exit">; def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias; def alias_strip_s: Flag<["-"], "s">, Alias; def alias_strip_S: Flag<["-"], "S">, Alias; + +// Ignored options +def: S<"plugin">; +def: J<"plugin=">; +def: S<"plugin-opt">; +def: J<"plugin-opt=">; diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index dc5df6795d99..c02cc586c795 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -40,6 +40,9 @@ ELF Improvements * The following flags have been added: ``-z interpose``, ``-z global`` +* lld now uses the ``sigrie`` instruction as a trap instruction for + MIPS targets. + COFF Improvements ----------------- @@ -66,6 +69,13 @@ MinGW Improvements linked in a different order than with GNU ld, inserting a DWARF exception table terminator too early.) +* lld now supports COFF embedded directives for linking to nondefault + libraries, just like for the normal COFF target. + +* Actually generate a codeview build id signature, even if not creating a PDB. + Previously, the ``--build-id`` option did not actually generate a build id + unless ``--pdb`` was specified. + MachO Improvements ------------------ diff --git a/test/COFF/arm-thumb-thunks-pdb.s b/test/COFF/arm-thumb-thunks-pdb.s new file mode 100644 index 000000000000..9e972a78d37f --- /dev/null +++ b/test/COFF/arm-thumb-thunks-pdb.s @@ -0,0 +1,18 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj +// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE + +// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes + + .syntax unified + .globl main + .globl func1 + .text +main: + bne func1 + bx lr + .section .text$a, "xr" + .space 0x100000 + .section .text$b, "xr" +func1: + bx lr diff --git a/test/COFF/arm64-branch-range.test b/test/COFF/arm64-branch-range.test deleted file mode 100644 index 0b581e9c464d..000000000000 --- a/test/COFF/arm64-branch-range.test +++ /dev/null @@ -1,16 +0,0 @@ -// REQUIRES: aarch64 - -// RUN: echo -e '.globl _start\n _start:\n bl too_far26\n' > %t.main26.s -// RUN: echo -e '.globl _start\n _start:\n b.ne too_far19\n' > %t.main19.s -// RUN: echo -e '.globl _start\n _start:\n tbz x0, #0, too_far14\n' > %t.main14.s - -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main26.s -o %t.main26.obj -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main19.s -o %t.main19.obj -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main14.s -o %t.main14.obj -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/far-arm64-abs.s -o %t.far.obj - -// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main26.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s -// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main19.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s -// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main14.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s - -// CHECK: relocation out of range diff --git a/test/COFF/arm64-thunks.s b/test/COFF/arm64-thunks.s new file mode 100644 index 000000000000..49004544c438 --- /dev/null +++ b/test/COFF/arm64-thunks.s @@ -0,0 +1,27 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj +// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s +// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s + +// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes + + .globl main + .globl func1 + .text +main: + tbz w0, #0, func1 + ret + .section .text$a, "xr" + .space 0x8000 + .section .text$b, "xr" +func1: + ret + +// DISASM: 0000000140001000 .text: +// DISASM: 140001000: 40 00 00 36 tbz w0, #0, #8 <.text+0x8> +// DISASM: 140001004: c0 03 5f d6 ret +// DISASM: 140001008: 50 00 00 90 adrp x16, #32768 +// DISASM: 14000100c: 10 52 00 91 add x16, x16, #20 +// DISASM: 140001010: 00 02 1f d6 br x16 + +// DISASM: 140009014: c0 03 5f d6 ret diff --git a/test/COFF/imports.test b/test/COFF/imports.test index 64f3900a1c2f..f54bdfd88dfa 100644 --- a/test/COFF/imports.test +++ b/test/COFF/imports.test @@ -34,3 +34,16 @@ IMPORT-NEXT: Symbol: ExitProcess (0) IMPORT-NEXT: Symbol: (50) IMPORT-NEXT: Symbol: MessageBoxA (1) IMPORT-NEXT: } + +# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \ +# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess +# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s + +MERGE: Import { +MERGE-NEXT: Name: std64.dll +MERGE-NEXT: ImportLookupTableRVA: 0x1090 +MERGE-NEXT: ImportAddressTableRVA: 0x10B0 +MERGE-NEXT: Symbol: ExitProcess (0) +MERGE-NEXT: Symbol: (50) +MERGE-NEXT: Symbol: MessageBoxA (1) +MERGE-NEXT: } diff --git a/test/ELF/arm-gnu-ifunc.s b/test/ELF/arm-gnu-ifunc.s index 8a7cb0ae237a..92f87b5d5fae 100644 --- a/test/ELF/arm-gnu-ifunc.s +++ b/test/ELF/arm-gnu-ifunc.s @@ -35,6 +35,8 @@ _start: // CHECK-NEXT: Address: 0x100F4 // CHECK-NEXT: Offset: 0xF4 // CHECK-NEXT: Size: 16 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: 4 // CHECK: Name: .plt // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ @@ -44,7 +46,8 @@ _start: // CHECK-NEXT: Address: 0x11020 // CHECK-NEXT: Offset: 0x1020 // CHECK-NEXT: Size: 32 -// CHECK: Name: .got +// CHECK: Index: 4 +// CHECK-NEXT: Name: .got // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC diff --git a/test/ELF/comdat-linkonce.s b/test/ELF/comdat-linkonce.s index 8721f58bb20c..8b1d4b362e86 100644 --- a/test/ELF/comdat-linkonce.s +++ b/test/ELF/comdat-linkonce.s @@ -4,7 +4,12 @@ // RUN: ld.lld -shared %t.o %t2.o -o %t // RUN: ld.lld -shared %t2.o %t.o -o %t -.section .gnu.linkonce.t.zed +.section .gnu.linkonce.t.__x86.get_pc_thunk.bx .globl abc abc: nop + +.section .gnu.linkonce.t.__i686.get_pc_thunk.bx +.globl def +def: +nop diff --git a/test/ELF/emulation-aarch64.s b/test/ELF/emulation-aarch64.s index b9a6428fa953..c0edc9a69d36 100644 --- a/test/ELF/emulation-aarch64.s +++ b/test/ELF/emulation-aarch64.s @@ -30,5 +30,28 @@ # AARCH64-NEXT: Flags [ (0x0) # AARCH64-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd +# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script +# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd +# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s +# AARCH64-FBSD: ElfHeader { +# AARCH64-FBSD-NEXT: Ident { +# AARCH64-FBSD-NEXT: Magic: (7F 45 4C 46) +# AARCH64-FBSD-NEXT: Class: 64-bit (0x2) +# AARCH64-FBSD-NEXT: DataEncoding: LittleEndian (0x1) +# AARCH64-FBSD-NEXT: FileVersion: 1 +# AARCH64-FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# AARCH64-FBSD-NEXT: ABIVersion: 0 +# AARCH64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# AARCH64-FBSD-NEXT: } +# AARCH64-FBSD-NEXT: Type: Executable (0x2) +# AARCH64-FBSD-NEXT: Machine: EM_AARCH64 (0xB7) +# AARCH64-FBSD-NEXT: Version: 1 +# AARCH64-FBSD-NEXT: Entry: +# AARCH64-FBSD-NEXT: ProgramHeaderOffset: 0x40 +# AARCH64-FBSD-NEXT: SectionHeaderOffset: +# AARCH64-FBSD-NEXT: Flags [ (0x0) +# AARCH64-FBSD-NEXT: ] + .globl _start _start: diff --git a/test/ELF/emulation-ppc.s b/test/ELF/emulation-ppc.s index 12e84782252f..843e77604779 100644 --- a/test/ELF/emulation-ppc.s +++ b/test/ELF/emulation-ppc.s @@ -35,6 +35,38 @@ # PPC64-NEXT: StringTableSectionIndex: # PPC64-NEXT: } +# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd +# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script +# RUN: ld.lld %tppc64fbsd.script %tppc64fbsd -o %t2ppc64fbsd +# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s + +# PPC64-FBSD: ElfHeader { +# PPC64-FBSD-NEXT: Ident { +# PPC64-FBSD-NEXT: Magic: (7F 45 4C 46) +# PPC64-FBSD-NEXT: Class: 64-bit (0x2) +# PPC64-FBSD-NEXT: DataEncoding: BigEndian (0x2) +# PPC64-FBSD-NEXT: FileVersion: 1 +# PPC64-FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# PPC64-FBSD-NEXT: ABIVersion: 0 +# PPC64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# PPC64-FBSD-NEXT: } +# PPC64-FBSD-NEXT: Type: Executable (0x2) +# PPC64-FBSD-NEXT: Machine: EM_PPC64 (0x15) +# PPC64-FBSD-NEXT: Version: 1 +# PPC64-FBSD-NEXT: Entry: +# PPC64-FBSD-NEXT: ProgramHeaderOffset: 0x40 +# PPC64-FBSD-NEXT: SectionHeaderOffset: +# PPC64-FBSD-NEXT: Flags [ (0x2) +# PPC64-FBSD-NEXT: 0x2 +# PPC64-FBSD-NEXT: ] +# PPC64-FBSD-NEXT: HeaderSize: 64 +# PPC64-FBSD-NEXT: ProgramHeaderEntrySize: 56 +# PPC64-FBSD-NEXT: ProgramHeaderCount: +# PPC64-FBSD-NEXT: SectionHeaderEntrySize: 64 +# PPC64-FBSD-NEXT: SectionHeaderCount: +# PPC64-FBSD-NEXT: StringTableSectionIndex: +# PPC64-FBSD-NEXT: } + # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le # RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s diff --git a/test/ELF/emulation-x86.s b/test/ELF/emulation-x86.s index 65d807c67f2f..02b894356692 100644 --- a/test/ELF/emulation-x86.s +++ b/test/ELF/emulation-x86.s @@ -7,6 +7,9 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv # RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd # RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s +# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script +# RUN: ld.lld %t4x64.script %tx64 -o %t4x64 +# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s # AMD64: ElfHeader { # AMD64-NEXT: Ident { # AMD64-NEXT: Magic: (7F 45 4C 46) @@ -137,10 +140,13 @@ # X86-NEXT: } # RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd -# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd -# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd +# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s # RUN: ld.lld %tx86fbsd -o %t3x86fbsd # RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script +# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd +# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s # X86FBSD: ElfHeader { # X86FBSD-NEXT: Ident { # X86FBSD-NEXT: Magic: (7F 45 4C 46) diff --git a/test/ELF/no-discard-this_module.s b/test/ELF/no-discard-this_module.s new file mode 100644 index 000000000000..3ce56d165fc1 --- /dev/null +++ b/test/ELF/no-discard-this_module.s @@ -0,0 +1,41 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t +// RUN: ld.lld %t -o %t2 +// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s + +.global _start +_start: + +// This section and symbol is used by Linux kernel modules. Ensure it's not +// accidentally discarded. +.section .gnu.linkonce.this_module: +__this_module: +.byte 0x00 + +// CHECK: Section { +// CHECK: Index: +// CHECK: Name: .gnu.linkonce.this_module +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00 |.| +// CHECK-NEXT: ) +// CHECK-NEXT: } + +// CHECK: Symbol { +// CHECK: Name: __this_module +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .gnu.linkonce.this_module: +// CHECK-NEXT: } diff --git a/test/ELF/sht-group-empty.test b/test/ELF/sht-group-empty.test new file mode 100644 index 000000000000..46c77f332e7e --- /dev/null +++ b/test/ELF/sht-group-empty.test @@ -0,0 +1,55 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t -r +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Name: .text.foo +# CHECK: Name: .rela.text.foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Link: .symtab + Info: foo + Members: + - SectionOrType: GRP_COMDAT + - SectionOrType: .text.foo + - SectionOrType: .text.bar + - SectionOrType: .note + - Name: .note + Type: SHT_NOTE + Flags: [ SHF_GROUP ] + - Name: .text.foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .text.bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .rela.text.foo + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.foo + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_64 + - Name: .rela.text.bar + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.bar + Relocations: + - Offset: 0x0000000000000000 + Symbol: bar + Type: R_X86_64_64 +Symbols: + Global: + - Name: foo + - Name: bar + From 012155a8760772089d507063b47b7f4c911a782b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 5 Feb 2019 18:40:11 +0000 Subject: [PATCH 7/7] Vendor import of lldb release_80 branch r353167: https://llvm.org/svn/llvm-project/lldb/branches/release_80@353167 --- cmake/modules/AddLLDB.cmake | 4 +++- cmake/modules/LLDBStandalone.cmake | 2 +- lit/CMakeLists.txt | 11 ++++++++--- source/Plugins/Process/NetBSD/CMakeLists.txt | 1 + 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cmake/modules/AddLLDB.cmake b/cmake/modules/AddLLDB.cmake index f7cac3dad837..f82c11d3d317 100644 --- a/cmake/modules/AddLLDB.cmake +++ b/cmake/modules/AddLLDB.cmake @@ -88,7 +88,9 @@ function(add_lldb_library name) # Hack: only some LLDB libraries depend on the clang autogenerated headers, # but it is simple enough to make all of LLDB depend on some of those # headers without negatively impacting much of anything. - add_dependencies(${name} clang-tablegen-targets) + if(NOT LLDB_BUILT_STANDALONE) + add_dependencies(${name} clang-tablegen-targets) + endif() # Add in any extra C++ compilation flags for this library. target_compile_options(${name} PRIVATE ${PARAM_EXTRA_CXXFLAGS}) diff --git a/cmake/modules/LLDBStandalone.cmake b/cmake/modules/LLDBStandalone.cmake index e63b2694e6a4..a9059dd5f9eb 100644 --- a/cmake/modules/LLDBStandalone.cmake +++ b/cmake/modules/LLDBStandalone.cmake @@ -58,7 +58,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(LLVM_DIR ${LLVM_OBJ_ROOT}/cmake/modules/CMakeFiles CACHE PATH "Path to LLVM build tree CMake files") set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") - set(LLVM_EXTERNAL_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit CACHE PATH "Path to llvm-lit") + set(LLVM_DEFAULT_EXTERNAL_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit CACHE PATH "Path to llvm-lit") find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) diff --git a/lit/CMakeLists.txt b/lit/CMakeLists.txt index 1ac013b2eed3..804e950b3bb0 100644 --- a/lit/CMakeLists.txt +++ b/lit/CMakeLists.txt @@ -26,9 +26,6 @@ list(APPEND LLDB_TEST_DEPS llvm-config llvm-mc llvm-objcopy - FileCheck - count - not ) if(TARGET lld) @@ -55,6 +52,14 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Suite/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/Suite/lit.site.cfg) +if(NOT LLDB_BUILT_STANDALONE) + list(APPEND LLDB_TEST_DEPS + FileCheck + count + not + ) +endif() + add_lit_testsuite(check-lldb-lit "Running lldb lit test suite" ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${LLDB_TEST_DEPS} diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt index e131e6d70468..586725bb7a56 100644 --- a/source/Plugins/Process/NetBSD/CMakeLists.txt +++ b/source/Plugins/Process/NetBSD/CMakeLists.txt @@ -11,6 +11,7 @@ add_lldb_library(lldbPluginProcessNetBSD PLUGIN lldbUtility lldbPluginProcessPOSIX lldbPluginProcessUtility + util LINK_COMPONENTS Support )