aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@chromium.org>2013-03-11 15:38:11 -0700
committerEli Bendersky <eliben@chromium.org>2013-03-20 14:49:21 -0700
commitd41567d2ffd3413600162653c08b2365bd5bcbbf (patch)
treeaa1c212bcf816f4011315b80826acfb85ae7d9f3
parent23c00401dad33ca247d2818e71540079bed63c5b (diff)
Apply after-merge fixes to return to working state.
-rw-r--r--lib/CodeGen/Passes.cpp10
-rw-r--r--lib/Linker/LinkArchives.cpp213
-rw-r--r--lib/Linker/LinkItems.cpp242
-rw-r--r--lib/MC/MCObjectStreamer.cpp3
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp6
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp2
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp17
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp11
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp15
-rw-r--r--lib/Target/Mips/MipsDelaySlotFiller.cpp30
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp12
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td8
-rw-r--r--lib/Target/Mips/MipsMCInstLower.cpp1
-rw-r--r--lib/Target/Mips/MipsNaClRewritePass.cpp1
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp9
-rw-r--r--lib/Target/X86/X86FastISel.cpp69
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp42
-rw-r--r--lib/Target/X86/X86InstrArithmetic.td1
-rw-r--r--lib/Target/X86/X86InstrInfo.td10
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp12
-rw-r--r--lib/Transforms/NaCl/ExpandTls.cpp5
-rw-r--r--lib/Transforms/Scalar/NaClCcRewrite.cpp1053
-rw-r--r--test/NaCl/ARM/neon-vld1-sandboxing.ll8
-rw-r--r--test/NaCl/ARM/neon-vld2-sandboxing.ll12
-rw-r--r--test/NaCl/ARM/neon-vld3-sandboxing.ll6
-rw-r--r--test/NaCl/ARM/neon-vld4-sandboxing.ll16
-rw-r--r--test/NaCl/ARM/neon-vlddup-sandboxing.ll8
-rw-r--r--test/NaCl/ARM/neon-vldlane-sandboxing.ll20
-rw-r--r--test/NaCl/ARM/neon-vst1-sandboxing.ll6
-rw-r--r--test/NaCl/ARM/neon-vst2-sandboxing.ll10
-rw-r--r--test/NaCl/ARM/neon-vst3-sandboxing.ll2
-rw-r--r--test/NaCl/ARM/neon-vst4-sandboxing.ll6
-rw-r--r--test/NaCl/ARM/neon-vstlane-sandboxing.ll18
33 files changed, 202 insertions, 1682 deletions
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index f8e390c753..b79f9f9816 100644
--- a/lib/CodeGen/Passes.cpp
+++ b/lib/CodeGen/Passes.cpp
@@ -352,16 +352,6 @@ void TargetPassConfig::addIRPasses() {
addPass(createTypeBasedAliasAnalysisPass());
addPass(createBasicAliasAnalysisPass());
- // @LOCALMOD-START
- addPass(createNaClCcRewritePass(TM->getTargetLowering()));
- // TODO: consider adding a cleanup pass, e.g. constant propagation
- // Note: we run this before the verfier step because it may cause
- // a *temporary* inconsistency:
- // A function may have been rewritting before we are rewriting
- // its callers - which would lead to a parameter mismatch complaint
- // from the verifier.
- // @LOCALMOD-END
-
// Before running any passes, run the verifier to determine if the input
// coming from the front-end and/or optimizer is valid.
if (!DisableVerify)
diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp
deleted file mode 100644
index e5ec0b83b8..0000000000
--- a/lib/Linker/LinkArchives.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-//===- lib/Linker/LinkArchives.cpp - Link LLVM objects and libraries ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains routines to handle linking together LLVM bitcode files,
-// and to handle annoying things like static libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Linker.h"
-#include "llvm/ADT/SetOperations.h"
-#include "llvm/Bitcode/Archive.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/CommandLine.h" // @LOCALMOD
-
-#include <memory>
-#include <set>
-using namespace llvm;
-
-// @LOCALMOD-START
-// NOTE: this has a similar effect as
-// tools/llvm/llvm-preserve.ll
-// which in turn is similar to the GNUS's attribute((used))
-// TODO(robertm): This is a little hackish for now
-static cl::list<std::string>
-UndefList("referenced-list", cl::value_desc("list"),
- cl::desc("A list of symbols assumed to be referenced externally"),
- cl::CommaSeparated);
-// @LOCALMOD-END
-
-/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still
-/// exist in an LLVM module. This is a bit tricky because there may be two
-/// symbols with the same name but different LLVM types that will be resolved to
-/// each other but aren't currently (thus we need to treat it as resolved).
-///
-/// Inputs:
-/// M - The module in which to find undefined symbols.
-///
-/// Outputs:
-/// UndefinedSymbols - A set of C++ strings containing the name of all
-/// undefined symbols.
-///
-static void
-GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
- std::set<std::string> DefinedSymbols;
- UndefinedSymbols.clear();
- // @LOCALMOD-START
- UndefinedSymbols.insert(UndefList.begin(), UndefList.end());
- // @LOCALMOD-END
-
- // If the program doesn't define a main, try pulling one in from a .a file.
- // This is needed for programs where the main function is defined in an
- // archive, such f2c'd programs.
- Function *Main = M->getFunction("main");
- if (Main == 0 || Main->isDeclaration())
- UndefinedSymbols.insert("main");
-
- for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
- if (I->hasName()) {
- if (I->isDeclaration())
- UndefinedSymbols.insert(I->getName());
- else if (!I->hasLocalLinkage()) {
- assert(!I->hasDLLImportLinkage()
- && "Found dllimported non-external symbol!");
- DefinedSymbols.insert(I->getName());
- }
- }
-
- for (Module::global_iterator I = M->global_begin(), E = M->global_end();
- I != E; ++I)
- if (I->hasName()) {
- if (I->isDeclaration())
- UndefinedSymbols.insert(I->getName());
- else if (!I->hasLocalLinkage()) {
- assert(!I->hasDLLImportLinkage()
- && "Found dllimported non-external symbol!");
- DefinedSymbols.insert(I->getName());
- }
- }
-
- for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
- I != E; ++I)
- if (I->hasName())
- DefinedSymbols.insert(I->getName());
-
- // Prune out any defined symbols from the undefined symbols set...
- for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
- I != UndefinedSymbols.end(); )
- if (DefinedSymbols.count(*I))
- UndefinedSymbols.erase(I++); // This symbol really is defined!
- else
- ++I; // Keep this symbol in the undefined symbols list
-}
-
-/// LinkInArchive - opens an archive library and link in all objects which
-/// provide symbols that are currently undefined.
-///
-/// Inputs:
-/// Filename - The pathname of the archive.
-///
-/// Return Value:
-/// TRUE - An error occurred.
-/// FALSE - No errors.
-bool
-Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) {
- // Make sure this is an archive file we're dealing with
- if (!Filename.isArchive())
- return error("File '" + Filename.str() + "' is not an archive.");
-
- // Open the archive file
- verbose("Linking archive file '" + Filename.str() + "'");
-
- // Find all of the symbols currently undefined in the bitcode program.
- // If all the symbols are defined, the program is complete, and there is
- // no reason to link in any archive files.
- std::set<std::string> UndefinedSymbols;
- GetAllUndefinedSymbols(Composite, UndefinedSymbols);
-
- if (UndefinedSymbols.empty()) {
- verbose("No symbols undefined, skipping library '" + Filename.str() + "'");
- return false; // No need to link anything in!
- }
-
- std::string ErrMsg;
- std::auto_ptr<Archive> AutoArch (
- Archive::OpenAndLoadSymbols(Filename, Context, &ErrMsg));
-
- Archive* arch = AutoArch.get();
-
- if (!arch)
- return error("Cannot read archive '" + Filename.str() +
- "': " + ErrMsg);
- if (!arch->isBitcodeArchive()) {
- is_native = true;
- return false;
- }
- is_native = false;
-
- // Save a set of symbols that are not defined by the archive. Since we're
- // entering a loop, there's no point searching for these multiple times. This
- // variable is used to "set_subtract" from the set of undefined symbols.
- std::set<std::string> NotDefinedByArchive;
-
- // Save the current set of undefined symbols, because we may have to make
- // multiple passes over the archive:
- std::set<std::string> CurrentlyUndefinedSymbols;
-
- do {
- CurrentlyUndefinedSymbols = UndefinedSymbols;
-
- // Find the modules we need to link into the target module. Note that arch
- // keeps ownership of these modules and may return the same Module* from a
- // subsequent call.
- SmallVector<Module*, 16> Modules;
- if (!arch->findModulesDefiningSymbols(UndefinedSymbols, Modules, &ErrMsg))
- return error("Cannot find symbols in '" + Filename.str() +
- "': " + ErrMsg);
-
- // If we didn't find any more modules to link this time, we are done
- // searching this archive.
- if (Modules.empty())
- break;
-
- // Any symbols remaining in UndefinedSymbols after
- // findModulesDefiningSymbols are ones that the archive does not define. So
- // we add them to the NotDefinedByArchive variable now.
- NotDefinedByArchive.insert(UndefinedSymbols.begin(),
- UndefinedSymbols.end());
-
- // Loop over all the Modules that we got back from the archive
- for (SmallVectorImpl<Module*>::iterator I=Modules.begin(), E=Modules.end();
- I != E; ++I) {
-
- // Get the module we must link in.
- std::string moduleErrorMsg;
- Module* aModule = *I;
- if (aModule != NULL) {
- if (aModule->MaterializeAll(&moduleErrorMsg))
- return error("Could not load a module: " + moduleErrorMsg);
-
- verbose(" Linking in module: " + aModule->getModuleIdentifier());
-
- // Link it in
- if (LinkInModule(aModule, &moduleErrorMsg))
- return error("Cannot link in module '" +
- aModule->getModuleIdentifier() + "': " + moduleErrorMsg);
- }
- }
-
- // Get the undefined symbols from the aggregate module. This recomputes the
- // symbols we still need after the new modules have been linked in.
- GetAllUndefinedSymbols(Composite, UndefinedSymbols);
-
- // At this point we have two sets of undefined symbols: UndefinedSymbols
- // which holds the undefined symbols from all the modules, and
- // NotDefinedByArchive which holds symbols we know the archive doesn't
- // define. There's no point searching for symbols that we won't find in the
- // archive so we subtract these sets.
- set_subtract(UndefinedSymbols, NotDefinedByArchive);
-
- // If there's no symbols left, no point in continuing to search the
- // archive.
- if (UndefinedSymbols.empty())
- break;
- } while (CurrentlyUndefinedSymbols != UndefinedSymbols);
-
- return false;
-}
diff --git a/lib/Linker/LinkItems.cpp b/lib/Linker/LinkItems.cpp
deleted file mode 100644
index 0ab551d14d..0000000000
--- a/lib/Linker/LinkItems.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-//===- lib/Linker/LinkItems.cpp - Link LLVM objects and libraries ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains routines to handle linking together LLVM bitcode files,
-// and to handle annoying things like static libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Linker.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
-using namespace llvm;
-
-// LinkItems - This function is the main entry point into linking. It takes a
-// list of LinkItem which indicates the order the files should be linked and
-// how each file should be treated (plain file or with library search). The
-// function only links bitcode and produces a result list of items that are
-// native objects.
-bool
-Linker::LinkInItems(const ItemList& Items, ItemList& NativeItems) {
- // Clear the NativeItems just in case
- NativeItems.clear();
-
- // For each linkage item ...
- for (ItemList::const_iterator I = Items.begin(), E = Items.end();
- I != E; ++I) {
- if (I->second) {
- // Link in the library suggested.
- bool is_native = false;
- if (LinkInLibrary(I->first, is_native))
- return true;
- if (is_native)
- NativeItems.push_back(*I);
- } else {
- // Link in the file suggested
- bool is_native = false;
- if (LinkInFile(sys::Path(I->first), is_native))
- return true;
- if (is_native)
- NativeItems.push_back(*I);
- }
- }
-
- // @LOCALMOD-BEGIN
- // At this point we have processed all the link items provided to us. Since
- // we have an aggregated module at this point, the dependent libraries in
- // that module should also be aggregated with duplicates eliminated. This is
- // now the time to process the dependent libraries to resolve any remaining
- // symbols.
- bool is_native;
- for (Module::lib_iterator I = Composite->lib_begin(),
- E = Composite->lib_end(); I != E; ++I) {
- if(LinkInLibrary(*I, is_native))
- return true;
- if (is_native)
- NativeItems.push_back(std::make_pair(*I, true));
- }
- // @LOCALMOD-END
- return false;
-}
-
-
-/// LinkInLibrary - links one library into the HeadModule.
-///
-bool Linker::LinkInLibrary(StringRef Lib, bool& is_native) {
- is_native = false;
- // Determine where this library lives.
- sys::Path Pathname = FindLib(Lib);
- if (Pathname.isEmpty())
- return error("Cannot find library '" + Lib.str() + "'");
-
- // If its an archive, try to link it in
- std::string Magic;
- Pathname.getMagicNumber(Magic, 64);
- switch (sys::IdentifyFileType(Magic.c_str(), 64)) {
- default: llvm_unreachable("Bad file type identification");
- case sys::Unknown_FileType:
- return warning("Supposed library '" + Lib.str() + "' isn't a library.");
-
- case sys::Bitcode_FileType:
- // LLVM ".so" file.
- if (LinkInFile(Pathname, is_native))
- return true;
- break;
-
- case sys::Archive_FileType:
- if (LinkInArchive(Pathname, is_native))
- return error("Cannot link archive '" + Pathname.str() + "'");
- break;
-
- case sys::ELF_Relocatable_FileType:
- case sys::ELF_SharedObject_FileType:
- case sys::Mach_O_Object_FileType:
- case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
- case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
- case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
- case sys::COFF_FileType:
- is_native = true;
- break;
- }
- return false;
-}
-
-/// LinkLibraries - takes the specified library files and links them into the
-/// main bitcode object file.
-///
-/// Inputs:
-/// Libraries - The list of libraries to link into the module.
-///
-/// Return value:
-/// FALSE - No error.
-/// TRUE - Error.
-///
-bool Linker::LinkInLibraries(const std::vector<std::string> &Libraries) {
-
- // Process the set of libraries we've been provided.
- bool is_native = false;
- for (unsigned i = 0; i < Libraries.size(); ++i)
- if (LinkInLibrary(Libraries[i], is_native))
- return true;
- // @LOCALMOD-BEGIN
- // At this point we have processed all the libraries provided to us. Since
- // we have an aggregated module at this point, the dependent libraries in
- // that module should also be aggregated with duplicates eliminated. This is
- // now the time to process the dependent libraries to resolve any remaining
- // symbols.
- const Module::LibraryListType& DepLibs = Composite->getLibraries();
- for (Module::LibraryListType::const_iterator I = DepLibs.begin(),
- E = DepLibs.end(); I != E; ++I)
- if (LinkInLibrary(*I, is_native))
- return true;
- // @LOCALMOD-END
- return false;
-}
-
-/// LinkInFile - opens a bitcode file and links in all objects which
-/// provide symbols that are currently undefined.
-///
-/// Inputs:
-/// File - The pathname of the bitcode file.
-///
-/// Outputs:
-/// ErrorMessage - A C++ string detailing what error occurred, if any.
-///
-/// Return Value:
-/// TRUE - An error occurred.
-/// FALSE - No errors.
-///
-bool Linker::LinkInFile(const sys::Path &File, bool &is_native) {
- is_native = false;
-
- // Check for a file of name "-", which means "read standard input"
- if (File.str() == "-") {
- std::auto_ptr<Module> M;
- OwningPtr<MemoryBuffer> Buffer;
- error_code ec;
- if (!(ec = MemoryBuffer::getSTDIN(Buffer))) {
- if (!Buffer->getBufferSize()) {
- Error = "standard input is empty";
- } else {
- M.reset(ParseBitcodeFile(Buffer.get(), Context, &Error));
- if (M.get())
- if (!LinkInModule(M.get(), &Error))
- return false;
- }
- }
- return error("Cannot link stdin: " + ec.message());
- }
-
- // Determine what variety of file it is.
- std::string Magic;
- if (!File.getMagicNumber(Magic, 64))
- return error("Cannot find linker input '" + File.str() + "'");
-
- switch (sys::IdentifyFileType(Magic.c_str(), 64)) {
- default: llvm_unreachable("Bad file type identification");
- case sys::Unknown_FileType:
- return warning("Ignoring file '" + File.str() +
- "' because does not contain bitcode.");
-
- case sys::Archive_FileType:
- // A user may specify an ar archive without -l, perhaps because it
- // is not installed as a library. Detect that and link the archive.
- if (LinkInArchive(File, is_native))
- return true;
- break;
-
- case sys::Bitcode_FileType: {
- verbose("Linking bitcode file '" + File.str() + "'");
- std::auto_ptr<Module> M(LoadObject(File));
- if (M.get() == 0)
- return error("Cannot load file '" + File.str() + "': " + Error);
- if (LinkInModule(M.get(), &Error))
- return error("Cannot link file '" + File.str() + "': " + Error);
-
- verbose("Linked in file '" + File.str() + "'");
- break;
- }
-
- case sys::ELF_Relocatable_FileType:
- case sys::ELF_SharedObject_FileType:
- case sys::Mach_O_Object_FileType:
- case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
- case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
- case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
- case sys::COFF_FileType:
- is_native = true;
- break;
- }
- return false;
-}
-
-/// LinkFiles - takes a module and a list of files and links them all together.
-/// It locates the file either in the current directory, as its absolute
-/// or relative pathname, or as a file somewhere in LLVM_LIB_SEARCH_PATH.
-///
-/// Inputs:
-/// Files - A vector of sys::Path indicating the LLVM bitcode filenames
-/// to be linked. The names can refer to a mixture of pure LLVM
-/// bitcode files and archive (ar) formatted files.
-///
-/// Return value:
-/// FALSE - No errors.
-/// TRUE - Some error occurred.
-///
-bool Linker::LinkInFiles(const std::vector<sys::Path> &Files) {
- bool is_native;
- for (unsigned i = 0; i < Files.size(); ++i)
- if (LinkInFile(Files[i], is_native))
- return true;
- return false;
-}
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index e835eea7df..1dff3f2977 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -176,7 +176,8 @@ void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
// @LOCALMOD-BEGIN
- if (getAssembler().getBackend().CustomExpandInst(Inst, *this)) {
+ if (getAssembler().isBundlingEnabled() &&
+ getAssembler().getBackend().CustomExpandInst(Inst, *this)) {
return;
}
// @LOCALMOD-END
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index 65b334bac4..c48df8a96f 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1824,10 +1824,8 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Non-Darwin binutils don't yet support the "trap" mnemonic.
// FIXME: Remove this special case when they do.
if (!Subtarget->isTargetDarwin()) {
- // @LOCALMOD-START
- //.long 0xe7fedef0 @ trap
- uint32_t Val = 0xe7fedef0UL;
- // @LOCALMOD-END
+ //.long 0xe7ffdefe @ trap
+ uint32_t Val = 0xe7ffdefeUL;
OutStreamer.AddComment("trap");
OutStreamer.EmitIntValue(Val, 4);
return;
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 1e54c3bb74..0501ee4c1d 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -74,7 +74,7 @@ void ARMSubtarget::initializeEnvironment() {
HasVFPv4 = false;
HasNEON = false;
UseNEONForSinglePrecisionFP = false;
- UseInlineJumpTables(!NoInlineJumpTables);
+ UseInlineJumpTables = !NoInlineJumpTables;
UseMulOps = UseFusedMulOps;
SlowFPVMLx = false;
HasVMLxForwarding = false;
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index c39d3fad3b..6c080408dd 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -49,7 +49,6 @@ namespace {
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const;
- virtual unsigned getEFlags() const;
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
@@ -68,22 +67,6 @@ MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI,
MipsELFObjectWriter::~MipsELFObjectWriter() {}
-// FIXME: get the real EABI Version from the Subtarget class.
-unsigned MipsELFObjectWriter::getEFlags() const {
-
- // FIXME: We can't tell if we are PIC (dynamic) or CPIC (static)
- unsigned Flag = ELF::EF_MIPS_NOREORDER;
-
- if (is64Bit())
- Flag |= ELF::EF_MIPS_ARCH_64R2;
- else
- Flag |= ELF::EF_MIPS_ARCH_32R2;
- /* @LOCLAMOD-START */
- if (RelocModelOption == Reloc::PIC_ || RelocModelOption == Reloc::Default)
- Flag |= ELF::EF_MIPS_PIC;
- /* @LOCLAMOD-END */
- return Flag;
-}
const MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index c77be4f743..ea29621ae2 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -133,11 +133,14 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
Triple TheTriple(TT);
// @LOCALMOD-BEGIN
- MCStreamer *Streamer = createELFStreamer(Ctx, MAB, _OS, _Emitter,
- RelaxAll, NoExecStack);
- if (TheTriple.isOSNaCl())
+ if (TheTriple.isOSNaCl()) {
+ MCStreamer *Streamer = createELFStreamer(Ctx, MAB, _OS, _Emitter,
+ RelaxAll, NoExecStack);
Streamer->EmitBundleAlignMode(4);
- return Streamer;
+ return Streamer;
+ } else {
+ return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
+ }
// @LOCALMOD-END
}
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 58a009ff02..5e0a80f416 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -13,11 +13,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mips-asm-printer"
-#include "MipsAsmPrinter.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsELFStreamer.h"
#include "Mips.h"
+#include "MipsAsmPrinter.h"
#include "MipsInstrInfo.h"
#include "MipsMCInstLower.h"
#include "llvm/ADT/SmallString.h"
@@ -67,7 +67,7 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
- // @LOCALMOD-START
+ // @LOCALMOD-BEGIN:
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(OutStreamer, MI))
return;
@@ -81,15 +81,8 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
if (emitPseudoExpansionLowering(OutStreamer, &*I))
continue;
- // The inMips16Mode() test is not permanent.
- // Some instructions are marked as pseudo right now which
- // would make the test fail for the wrong reason but
- // that will be fixed soon. We need this here because we are
- // removing another test for this situation downstream in the
- // callchain.
- //
- if (I->isPseudo() && !Subtarget->inMips16Mode())
- llvm_unreachable("Pseudo opcode found in EmitInstruction()");
+ // @LOCALMOD: the I->isPseudo() assertion here has been removed because
+ // we may have SFI pseudos in I.
MCInst TmpInst0;
MCInstLowering.Lower(I, TmpInst0);
diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp
index af81426bc0..49475d1740 100644
--- a/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -70,7 +70,6 @@ namespace {
return "Mips Delay Slot Filler";
}
- bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
bool runOnMachineFunction(MachineFunction &F) {
if (SkipDelaySlotFiller)
return false;
@@ -169,7 +168,6 @@ bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
/// We assume there is only one delay slot per delayed instruction.
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
bool Changed = false;
- LastFiller = MBB.instr_end();
for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
if (!I->hasDelaySlot())
@@ -192,7 +190,6 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
}
return Changed;
-
}
/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
@@ -206,11 +203,9 @@ extern bool IsDangerousLoad(const MachineInstr &MI, int *AddrIdx);
extern bool IsDangerousStore(const MachineInstr &MI, int *AddrIdx);
// @LOCALMOD-END
-bool Filler::findDelayInstr(MachineBasicBlock &MBB,
- InstrIter slot,
- InstrIter &Filler) {
- SmallSet<unsigned, 32> RegDefs;
- SmallSet<unsigned, 32> RegUses;
+bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
+ Iter &Filler) const {
+ RegDefsUses RegDU(TM);
RegDU.init(*Slot);
@@ -223,17 +218,22 @@ bool Filler::findDelayInstr(MachineBasicBlock &MBB,
continue;
// @LOCALMOD-START - Don't put in delay slot instructions that could be masked.
- int Dummy;
- if (terminateSearch(*I) || (Triple(TM.getTargetTriple()).isOSNaCl() &&
- (IsDangerousLoad(*FI, &Dummy)
- || IsDangerousStore(*FI, &Dummy)
- || FI->modifiesRegister(Mips::SP, TM.getRegisterInfo()))))
- break;
- // @LOCALMOD-END
//
// Should not allow:
// ERET, DERET or WAIT, PAUSE. Need to add these to instruction
// list. TBD.
+ if (Triple(TM.getTargetTriple()).isOSNaCl()) {
+ int Dummy;
+ Iter FI(llvm::next(I).base());
+ if (terminateSearch(*I) || (IsDangerousLoad(*FI, &Dummy)
+ || IsDangerousStore(*FI, &Dummy)
+ || FI->modifiesRegister(Mips::SP, TM.getRegisterInfo())))
+ break;
+ } else {
+ if (terminateSearch(*I))
+ break;
+ }
+ // @LOCALMOD-END
if (delayHasHazard(*I, SawLoad, SawStore, RegDU))
continue;
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index 7c61318aac..78c74ef879 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -392,20 +392,12 @@ bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
}
}
}
+
+ return false;
}
bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
SDValue &Offset) const {
- // @LOCALMOD-START
- // If an indexed floating point load/store can be emitted, return false.
- const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);
-
- if (LS &&
- (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) &&
- Subtarget.hasFPIdx())
- return false;
- // @LOCALMOD-END
-
Base = Addr;
Offset = CurDAG->getTargetConstant(0, Addr.getValueType());
return true;
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index 73074f5b58..d22400d211 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -319,23 +319,23 @@ let Predicates = [NotN64, NotMips64, HasStdEnc] in {
}
// Indexed loads and stores.
-let Predicates = [HasFPIdx, IsNotNaCl/*@LOCALMOD*/] in {
+let Predicates = [HasFPIdx, HasStdEnc, IsNotNaCl/*@LOCALMOD*/] in {
def LWXC1 : LWXC1_FT<"lwxc1", FGR32, CPURegs, IILoad, load>, LWXC1_FM<0>;
def SWXC1 : SWXC1_FT<"swxc1", FGR32, CPURegs, IIStore, store>, SWXC1_FM<8>;
}
-let Predicates = [HasMips32r2, NotMips64, IsNotNaCl/*@LOCALMOD*/] in {
+let Predicates = [HasMips32r2, NotMips64, HasStdEnc, IsNotNaCl/*@LOCALMOD*/] in {
def LDXC1 : LWXC1_FT<"ldxc1", AFGR64, CPURegs, IILoad, load>, LWXC1_FM<1>;
def SDXC1 : SWXC1_FT<"sdxc1", AFGR64, CPURegs, IIStore, store>, SWXC1_FM<9>;
}
-let Predicates = [HasMips64, NotN64, IsNotNaCl/*@LOCALMOD*/], DecoderNamespace="Mips64" in {
+let Predicates = [HasMips64, NotN64, HasStdEnc, IsNotNaCl/*@LOCALMOD*/], DecoderNamespace="Mips64" in {
def LDXC164 : LWXC1_FT<"ldxc1", FGR64, CPURegs, IILoad, load>, LWXC1_FM<1>;
def SDXC164 : SWXC1_FT<"sdxc1", FGR64, CPURegs, IIStore, store>, SWXC1_FM<9>;
}
// n64
-let Predicates = [IsN64, IsNotNaCl/*@LOCALMOD*/], isCodeGenOnly=1 in {
+let Predicates = [IsN64, HasStdEnc, IsNotNaCl/*@LOCALMOD*/], isCodeGenOnly=1 in {
def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32, CPU64Regs, IILoad, load>, LWXC1_FM<0>;
def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64, CPU64Regs, IILoad, load>,
LWXC1_FM<1>;
diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp
index e0d884dfda..d836975eb7 100644
--- a/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/lib/Target/Mips/MipsMCInstLower.cpp
@@ -164,4 +164,3 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
}
}
-
diff --git a/lib/Target/Mips/MipsNaClRewritePass.cpp b/lib/Target/Mips/MipsNaClRewritePass.cpp
index 5e4e5e3b8f..d4407e835e 100644
--- a/lib/Target/Mips/MipsNaClRewritePass.cpp
+++ b/lib/Target/Mips/MipsNaClRewritePass.cpp
@@ -112,6 +112,7 @@ void MipsNaClRewritePass::SandboxStackChange(MachineBasicBlock &MBB,
// Get to next instr (one + to get the original, and one more + to get past).
MachineBasicBlock::iterator MBBINext = (MBBI++);
+ (void) MBBINext;
MachineBasicBlock::iterator MBBINext2 = (MBBI++);
BuildMI(MBB, MBBINext2, MI.getDebugLoc(),
diff --git a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
index 370eebe1f3..2039b7d210 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
@@ -77,18 +77,21 @@ X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple)
void X86ELFMCAsmInfo::anchor() { }
X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
- // @LOCALMOD-BEGIN s/gnux32/nacl/
bool is64Bit = T.getArch() == Triple::x86_64;
+ bool isX32 = T.getEnvironment() == Triple::GNUX32;
+
+ // @LOCALMOD-BEGIN(eliben)
+ // Until Nacl implies x32, we add &&!isNaCl in the PointerSize condition
bool isNaCl = T.isOSNaCl();
// For ELF, x86-64 pointer size depends on the ABI.
// For x86-64 without the x32 ABI, pointer size is 8. For x86 and for x86-64
// with the x32 ABI, pointer size remains the default 4.
- PointerSize = (is64Bit && !isNaCl) ? 8 : 4;
+ PointerSize = (is64Bit && !isX32 && !isNaCl) ? 8 : 4;
+ // @LOCALMOD-END
// OTOH, stack slot size is always 8 for x86-64, even with the x32 ABI.
CalleeSaveStackSlotSize = is64Bit ? 8 : 4;
- // @LOCALMOD-END
AssemblerDialect = AsmWriterFlavor;
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index efacf5be4a..89e3538558 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -341,6 +341,74 @@ bool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT,
return true;
}
+/// @LOCALMOD-BEGIN
+/// isLegalAddressingModeForNaCl - Determine if the addressing mode is
+/// legal for NaCl translation. If not, the caller is expected to
+/// reject the instruction for fast-ISel code generation.
+///
+/// The logic for the test is translated from the corresponding logic
+/// in X86DAGToDAGISel::LegalizeAddressingModeForNaCl(). It can't be
+/// used directly due to the X86AddressMode vs X86ISelAddressMode
+/// types. As such, any changes to isLegalAddressingModeForNaCl() and
+/// X86DAGToDAGISel::LegalizeAddressingModeForNaCl() need to be
+/// synchronized. The original conditions are indicated in comments.
+static bool isLegalAddressingModeForNaCl(const X86Subtarget *Subtarget,
+ const X86AddressMode &AM) {
+ if (Subtarget->isTargetNaCl64()) {
+ // Return true (i.e., is legal) if the equivalent of
+ // X86ISelAddressMode::isRIPRelative() is true.
+ if (AM.BaseType == X86AddressMode::RegBase &&
+ AM.Base.Reg == X86::RIP)
+ return true;
+
+ // Check for the equivalent of
+ // (!AM.hasBaseOrIndexReg() &&
+ // !AM.hasSymbolicDisplacement() &&
+ // AM.Disp < 0)
+ if (!((AM.BaseType == X86AddressMode::RegBase && AM.Base.Reg) ||
+ AM.IndexReg) &&
+ !AM.GV &&
+ AM.Disp < 0) {
+ ++NumFastIselNaClFailures;
+ return false;
+ }
+
+ // At this point in the LegalizeAddressingModeForNaCl() code, it
+ // normalizes an addressing mode with a base register and no index
+ // register into an equivalent mode with an index register and no
+ // base register. Since we don't modify AM, we may have to check
+ // both the base and index register fields in the remainder of the
+ // tests.
+
+ // Check for the equivalent of
+ // ((AM.BaseType == X86ISelAddressMode::FrameIndexBase || AM.GV || AM.CP) &&
+ // AM.IndexReg.getNode() &&
+ // AM.Disp > 0)
+ // Note: X86AddressMode doesn't have a CP analogue
+ if ((AM.BaseType == X86AddressMode::FrameIndexBase || AM.GV) &&
+ ((AM.BaseType == X86AddressMode::RegBase && AM.Base.Reg) ||
+ AM.IndexReg) &&
+ AM.Disp > 0) {
+ ++NumFastIselNaClFailures;
+ return false;
+ }
+
+ // Check for the equivalent of
+ // ((AM.BaseType == X86ISelAddressMode::RegBase) &&
+ // AM.Base_Reg.getNode() &&
+ // AM.IndexReg.getNode())
+ if ((AM.BaseType == X86AddressMode::RegBase) &&
+ AM.Base.Reg &&
+ AM.IndexReg) {
+ ++NumFastIselNaClFailures;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// @LOCALMOD-END
/// X86SelectAddress - Attempt to fill in an address from the given value.
///
/// @LOCALMOD-BEGIN
@@ -870,7 +938,6 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
unsigned CopyTo = Subtarget->has64BitPointers() ? X86::RAX : X86::EAX;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
CopyTo).addReg(Reg);
- MRI.addLiveOut(CopyTo);
// @LOCALMOD-END
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 22a7b8d022..c2bb675235 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1695,20 +1695,21 @@ X86TargetLowering::LowerReturn(SDValue Chain,
"SRetReturnReg should have been set in LowerFormalArguments().");
SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy());
- // @LOCALMOD-START
+ unsigned RetValReg = Subtarget->isTarget64BitILP32() ? X86::EAX : X86::RAX;
+ // @LOCALMOD-BEGIN
if (Subtarget->isTargetNaCl()) {
// NaCl 64 uses 32-bit pointers, so there might be some zero-ext needed.
SDValue Zext = DAG.getZExtOrTrunc(Val, dl, MVT::i64);
Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Zext, Flag);
} else {
- Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag);
+ Chain = DAG.getCopyToReg(Chain, dl, RetValReg, Val, Flag);
}
// @LOCALMOD-END
Flag = Chain.getValue(1);
- // RAX now acts like a return value.
- MRI.addLiveOut(X86::RAX);
+ // RAX/EAX now acts like a return value.
+ RetOps.push_back(DAG.getRegister(RetValReg, MVT::i64));
}
RetOps[0] = Chain; // Update chain.
@@ -2068,9 +2069,8 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
unsigned Reg = FuncInfo->getSRetReturnReg();
if (!Reg) {
- // @LOCALMOD
- Reg = MF.getRegInfo().createVirtualRegister(
- getRegClassFor(getPointerTy()));
+ MVT PtrTy = getPointerTy();
+ Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(PtrTy));
FuncInfo->setSRetReturnReg(Reg);
}
SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]);
@@ -2684,8 +2684,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// This isn't right, although it's probably harmless on x86; liveouts
// should be computed from returns not tail calls. Consider a void
// function making a tail call to a function returning int.
- return DAG.getNode(X86ISD::TC_RETURN, dl,
- NodeTys, &Ops[0], Ops.size());
+ return DAG.getNode(X86ISD::TC_RETURN, dl, NodeTys, &Ops[0], Ops.size());
}
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
@@ -7634,8 +7633,8 @@ X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
static SDValue
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
SDValue *InFlag, const EVT PtrVT, unsigned ReturnReg,
- unsigned char OperandFlags,
- unsigned Opcode = X86ISD::TLSADDR) { // @LOCALMOD
+ unsigned char OperandFlags, bool LocalDynamic = false,
+ unsigned Opcode = ISD::DELETED_NODE) { // @LOCALMOD
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
DebugLoc dl = GA->getDebugLoc();
@@ -7644,15 +7643,22 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
GA->getOffset(),
OperandFlags);
- X86ISD::NodeType CallType = LocalDynamic ? X86ISD::TLSBASEADDR
- : X86ISD::TLSADDR;
+ // @LOCALMOD - changed type for casting
+ unsigned CallType = LocalDynamic ? X86ISD::TLSBASEADDR
+ : X86ISD::TLSADDR;
+
+ // @LOCALMOD-START
+ // If Opcode was explicitly overridden, use it as the call type.
+ if (Opcode != ISD::DELETED_NODE)
+ CallType = Opcode;
+ // @LOCALMOD-END
if (InFlag) {
SDValue Ops[] = { Chain, TGA, *InFlag };
- Chain = DAG.getNode(Opcode, dl, NodeTys, Ops, 3); // @LOCALMOD
+ Chain = DAG.getNode(CallType, dl, NodeTys, Ops, 3);
} else {
SDValue Ops[] = { Chain, TGA };
- Chain = DAG.getNode(Opcode, dl, NodeTys, Ops, 2); // @LOCALMOD
+ Chain = DAG.getNode(CallType, dl, NodeTys, Ops, 2);
}
// TLSADDR will be codegen'ed as call. Inform MFI that function has calls.
@@ -7704,7 +7710,7 @@ LowerToTLSExecCall(GlobalAddressSDNode *GA, SelectionDAG &DAG,
return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT,
X86::EAX, // PtrVT is 32-bit.
- TargetFlag, Opcode);
+ TargetFlag, false, Opcode);
}
// @LOCALMOD-START
@@ -7726,7 +7732,7 @@ LowerToTLSNaCl64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT,
X86::EAX, // PtrVT is 32-bit.
- TargetFlag, Opcode);
+ TargetFlag, false, Opcode);
}
// @LOCALMOD-END
@@ -7851,7 +7857,7 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
case TLSModel::InitialExec:
case TLSModel::LocalExec:
// @LOCALMOD-START
- if (llvm::TLSUseCall) {
+ if (llvm::TLSUseCall && Subtarget->isTargetNaCl()) {
return LowerToTLSExecCall(GA, DAG, getPointerTy(), model,
Subtarget->is64Bit());
} else {
diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td
index 01be39a338..d86a4065a7 100644
--- a/lib/Target/X86/X86InstrArithmetic.td
+++ b/lib/Target/X86/X86InstrArithmetic.td
@@ -32,7 +32,6 @@ def LEA64_32r : I<0x8D, MRMSrcMem,
[(set GR32:$dst, lea64_32addr:$src)], IIC_LEA>,
Requires<[In64BitMode]>;
-// @LOCALMOD (lea64mem)
let isReMaterializable = 1 in
def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
"lea{q}\t{$src|$dst}, {$dst|$src}",
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 31aa25e3f2..241d2cab2c 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -533,13 +533,6 @@ def i64i8imm : Operand<i64> {
let OperandType = "OPERAND_IMMEDIATE";
}
-// @LOCALMOD
-def lea64mem : Operand<i64> {
- let PrintMethod = "printi64mem";
- let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
- let ParserMatchClass = X86MemAsmOperand;
-}
-
def lea64_32mem : Operand<i32> {
let PrintMethod = "printi32mem";
let AsmOperandLowerMethod = "lower_lea64_32mem";
@@ -562,8 +555,7 @@ def lea64mem : Operand<i64> {
// Define X86 specific addressing mode.
def addr : ComplexPattern<iPTR, 5, "SelectAddr", [], [SDNPWantParent]>;
def lea32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
- [add, sub, mul, X86mul_imm, shl, or, frameindex,
- X86WrapperRIP], // @LOCALMOD
+ [add, sub, mul, X86mul_imm, shl, or, frameindex],
[]>;
// In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
def lea64_32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index a9a6579c47..dca129a3ea 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -45,8 +45,7 @@ X86_32TargetMachine::X86_32TargetMachine(const Target &T, StringRef TT,
"n8:16:32-S32" :
getSubtargetImpl()->isTargetNaCl() ? // @LOCALMOD
"e-p:32:32-s:32-f64:64:64-f32:32:32-f80:128:128-i64:64:64-n8:16:32-S128" :
- "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-f128:128:128-"
- "n8:16:32-S128"),
+ "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-f128:128:128-n8:16:32-S128"),
InstrInfo(*this),
TLInfo(*this),
TSInfo(*this),
@@ -63,9 +62,11 @@ X86_64TargetMachine::X86_64TargetMachine(const Target &T, StringRef TT,
: X86TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true),
DL(getSubtargetImpl()->isTargetNaCl() ? // @LOCALMOD
"e-p:32:32-s:64-f64:64:64-f32:32:32-f80:128:128-i64:64:64-"
- "n8:16:32:64-S128" :
- "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-f128:128:128-"
- "n8:16:32:64-S128"),
+ "n8:16:32:64-S128" : (getSubtargetImpl()->isTarget64BitILP32() ?
+ "e-p:32:32-s:64-f64:64:64-i64:64:64-f80:128:128-f128:128:128-"
+ "n8:16:32:64-S128" :
+ "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-f128:128:128-"
+ "n8:16:32:64-S128")),
InstrInfo(*this),
TLInfo(*this),
TSInfo(*this),
@@ -156,6 +157,7 @@ public:
}
virtual bool addInstSelector();
+ virtual bool addILPOpts();
virtual bool addPreRegAlloc();
virtual bool addPostRegAlloc();
virtual bool addPreEmitPass();
diff --git a/lib/Transforms/NaCl/ExpandTls.cpp b/lib/Transforms/NaCl/ExpandTls.cpp
index 065226fedd..929b2e0a15 100644
--- a/lib/Transforms/NaCl/ExpandTls.cpp
+++ b/lib/Transforms/NaCl/ExpandTls.cpp
@@ -239,9 +239,8 @@ static void rewriteTlsVars(Module &M, std::vector<VarInfo> *TlsVars,
AttrBuilder B;
B.addAttribute(Attribute::ReadOnly);
B.addAttribute(Attribute::NoUnwind);
- AttributeSet ReadTpAttrs = AttributeSet().addAttr(
- M.getContext(), AttributeSet::FunctionIndex,
- Attribute::get(M.getContext(), B));
+ AttributeSet ReadTpAttrs = AttributeSet::get(
+ M.getContext(), AttributeSet::FunctionIndex, B);
Constant *ReadTpFunc = M.getOrInsertTargetIntrinsic("llvm.nacl.read.tp",
ReadTpType,
ReadTpAttrs);
diff --git a/lib/Transforms/Scalar/NaClCcRewrite.cpp b/lib/Transforms/Scalar/NaClCcRewrite.cpp
deleted file mode 100644
index 72a8e7e358..0000000000
--- a/lib/Transforms/Scalar/NaClCcRewrite.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-//===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements calling convention rewrite for Native Client to ensure
-// compatibility between pnacl and gcc generated code when calling
-// ppapi interface functions.
-//===----------------------------------------------------------------------===//
-
-
-// Major TODOs:
-// * dealing with vararg
-// (We shoulf exclude all var arg functions and calls to them from rewrites)
-
-#define DEBUG_TYPE "naclcc"
-
-#include "llvm/Pass.h"
-#include "llvm/IR/Argument.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Function.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Target/TargetLibraryInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Transforms/Scalar.h"
-
-#include <vector>
-
-using namespace llvm;
-
-namespace llvm {
-
-cl::opt<bool> FlagEnableCcRewrite(
- "nacl-cc-rewrite",
- cl::desc("enable NaCl CC rewrite"));
-}
-
-namespace {
-
-// This represents a rule for rewiriting types
-struct TypeRewriteRule {
- const char* src; // type pattern we are trying to match
- const char* dst; // replacement type
- const char* name; // name of the rule for diagnosis
-};
-
-// Note: all rules must be well-formed
-// * parentheses must match
-// * TODO: add verification for this
-
-// Legend:
-// s(): struct (also used for unions)
-// c: char (= 8 bit int) (only allowed for src)
-// i: 32 bit int
-// l: 64 bit int
-// f: 32 bit float
-// d: 64 bit float (= double)
-// p: untyped pointer (only allowed for src)
-// P(): typed pointer (currently not used, only allowed for src)
-// F: generic function type (only allowed for src)
-
-// The X8664 Rewrite rules are also subject to
-// register constraints, c.f.: section 3.2.3
-// http://www.x86-64.org/documentation/abi.pdf
-// (roughly) for X8664: up to 2 regs per struct can be used for struct passsing
-// and up to 2 regs for struct returns
-// The rewrite rules are straight forward except for: s(iis(d)) => ll
-// which would be straight forward if the frontend had lowered the union inside
-// of PP_Var to s(l) instead of s(d), yielding: s(iis(l)) => ll
-TypeRewriteRule ByvalRulesX8664[] = {
- {"s(iis(d))", "ll", "PP_Var"},
- {"s(pp)", "l", "PP_ArrayOutput"},
- {"s(ppi)", "li", "PP_CompletionCallback"},
- {0, 0, 0},
-};
-
-TypeRewriteRule SretRulesX8664[] = {
- // Note: for srets, multireg returns are modeled as struct returns
- {"s(iis(d))", "s(ll)", "PP_Var"},
- {"s(ff)", "d", "PP_FloatPoint"},
- {"s(ii)", "l", "PP_Point" },
- {"s(pp)", "l", "PP_ArrayOutput"},
- {0, 0, 0},
-};
-
-// for ARM: up to 4 regs can be used for struct passsing
-// and up to 2 float regs for struct returns
-TypeRewriteRule ByvalRulesARM[] = {
- {"s(iis(d))", "ll", "PP_Var"},
- {"s(ppi)", "iii", "PP_CompletionCallback" },
- {"s(pp)", "ii", "PP_ArrayOutput"},
- {0, 0, 0},
-};
-
-TypeRewriteRule SretRulesARM[] = {
- // Note: for srets, multireg returns are modeled as struct returns
- {"s(ff)", "s(ff)", "PP_FloatPoint"},
- {0, 0, 0},
-};
-
-// Helper class to model Register Usage as required by
-// the x86-64 calling conventions
-class RegUse {
- uint32_t n_int_;
- uint32_t n_float_;
-
- public:
- RegUse(uint32_t n_int=0, uint32_t n_float=0) :
- n_int_(n_int), n_float_(n_float) {}
-
- static RegUse OneIntReg() { return RegUse(1, 0); }
- static RegUse OnePointerReg() { return RegUse(1, 0); }
- static RegUse OneFloatReg() { return RegUse(0, 1); }
-
- RegUse operator+(RegUse other) const {
- return RegUse(n_int_ + other.n_int_, n_float_ + other.n_float_); }
- RegUse operator-(RegUse other) const {
- return RegUse(n_int_ - other.n_int_, n_float_ - other.n_float_); }
- bool operator==(RegUse other) const {
- return n_int_ == other.n_int_ && n_float_ == other.n_float_; }
- bool operator!=(RegUse other) const {
- return n_int_ != other.n_int_ && n_float_ != other.n_float_; }
- bool operator<=(RegUse other) const {
- return n_int_ <= other.n_int_ && n_float_ <= other.n_float_; }
- bool operator<(RegUse other) const {
- return n_int_ < other.n_int_ && n_float_ < other.n_float_; }
- bool operator>=(RegUse other) const {
- return n_int_ >= other.n_int_ && n_float_ >= other.n_float_; }
- bool operator>(RegUse other) const {
- return n_int_ > other.n_int_ && n_float_ > other.n_float_; }
- RegUse& operator+=(const RegUse& other) {
- n_int_ += other.n_int_; n_float_ += other.n_float_; return *this;}
- RegUse& operator-=(const RegUse& other) {
- n_int_ -= other.n_int_; n_float_ -= other.n_float_; return *this;}
-
- friend raw_ostream& operator<<(raw_ostream &O, const RegUse& reg);
-};
-
-raw_ostream& operator<<(raw_ostream &O, const RegUse& reg) {
- O << "(" << reg.n_int_ << ", " << reg.n_float_ << ")";
- return O;
-}
-
-// TODO: Find a better way to determine the architecture
-const TypeRewriteRule* GetByvalRewriteRulesForTarget(
- const TargetLowering* tli) {
- if (!FlagEnableCcRewrite) return 0;
-
- const TargetMachine &m = tli->getTargetMachine();
- const StringRef triple = m.getTargetTriple();
-
- if (0 == triple.find("x86_64")) return ByvalRulesX8664;
- if (0 == triple.find("i686")) return 0;
- if (0 == triple.find("armv7a")) return ByvalRulesARM;
-
- llvm_unreachable("Unknown arch");
- return 0;
-}
-
-// TODO: Find a better way to determine the architecture
-const TypeRewriteRule* GetSretRewriteRulesForTarget(
- const TargetLowering* tli) {
- if (!FlagEnableCcRewrite) return 0;
-
- const TargetMachine &m = tli->getTargetMachine();
- const StringRef triple = m.getTargetTriple();
-
- if (0 == triple.find("x86_64")) return SretRulesX8664;
- if (0 == triple.find("i686")) return 0;
- if (0 == triple.find("armv7a")) return SretRulesARM;
-
- llvm_unreachable("Unknown arch");
- return 0;
-}
-
-// TODO: Find a better way to determine the architecture
-// Describes the number of registers available for function
-// argument passing which may affect rewrite decisions on
-// some platforms.
-RegUse GetAvailableRegsForTarget(
- const TargetLowering* tli) {
- if (!FlagEnableCcRewrite) return RegUse(0, 0);
-
- const TargetMachine &m = tli->getTargetMachine();
- const StringRef triple = m.getTargetTriple();
-
- // integer: RDI, RSI, RDX, RCX, R8, R9
- // float XMM0, ..., XMM7
- if (0 == triple.find("x86_64")) return RegUse(6, 8);
- // unused
- if (0 == triple.find("i686")) return RegUse(0, 0);
- // no constraints enforced here - the backend handles all the details
- uint32_t max = std::numeric_limits<uint32_t>::max();
- if (0 == triple.find("armv7a")) return RegUse(max, max);
-
- llvm_unreachable("Unknown arch");
- return 0;
-}
-
-// This class represents the a bitcode rewrite pass which ensures
-// that all ppapi interfaces are calling convention compatible
-// with gcc. This pass is archtitecture dependent.
-struct NaClCcRewrite : public FunctionPass {
- static char ID; // Pass identification, replacement for typeid
- const TypeRewriteRule* SretRewriteRules;
- const TypeRewriteRule* ByvalRewriteRules;
- const RegUse AvailableRegs;
-
- explicit NaClCcRewrite(const TargetLowering *tli = 0)
- : FunctionPass(ID),
- SretRewriteRules(GetSretRewriteRulesForTarget(tli)),
- ByvalRewriteRules(GetByvalRewriteRulesForTarget(tli)),
- AvailableRegs(GetAvailableRegsForTarget(tli)) {
- initializeNaClCcRewritePass(*PassRegistry::getPassRegistry());
- }
-
- // main pass entry point
- bool runOnFunction(Function &F);
-
- private:
- void RewriteCallsite(Instruction* call, LLVMContext& C);
- void RewriteFunctionPrologAndEpilog(Function& F);
-};
-
-char NaClCcRewrite::ID = 0;
-
-// This is only used for dst side of rules
-Type* GetElementaryType(char c, LLVMContext& C) {
- switch (c) {
- case 'i':
- return Type::getInt32Ty(C);
- case 'l':
- return Type::getInt64Ty(C);
- case 'd':
- return Type::getDoubleTy(C);
- case 'f':
- return Type::getFloatTy(C);
- default:
- dbgs() << c << "\n";
- llvm_unreachable("Unknown type specifier");
- return 0;
- }
-}
-
-// This is only used for the dst side of a rule
-int GetElementaryTypeWidth(char c) {
- switch (c) {
- case 'i':
- case 'f':
- return 4;
- case 'l':
- case 'd':
- return 8;
- default:
- llvm_unreachable("Unknown type specifier");
- return 0;
- }
-}
-
-// Check whether a type matches the *src* side pattern of a rewrite rule.
-// Note that the pattern parameter is updated during the recursion
-bool HasRewriteType(const Type* type, const char*& pattern) {
- switch (*pattern++) {
- case '\0':
- return false;
- case ')':
- return false;
- case 's': // struct and union are currently no distinguished
- {
- if (*pattern++ != '(') llvm_unreachable("malformed type pattern");
- if (!type->isStructTy()) return false;
- // check struct members
- const StructType* st = cast<StructType>(type);
- for (StructType::element_iterator it = st->element_begin(),
- end = st->element_end();
- it != end;
- ++it) {
- if (!HasRewriteType(*it, pattern)) return false;
- }
- // ensure we reached the end
- int c = *pattern++;
- return c == ')';
- }
- break;
- case 'c':
- return type->isIntegerTy(8);
- case 'i':
- return type->isIntegerTy(32);
- case 'l':
- return type->isIntegerTy(64);
- case 'd':
- return type->isDoubleTy();
- case 'f':
- return type->isFloatTy();
- case 'F':
- return type->isFunctionTy();
- case 'p': // untyped pointer
- return type->isPointerTy();
- case 'P': // typed pointer
- {
- if (*pattern++ != '(') llvm_unreachable("malformed type pattern");
- if (!type->isPointerTy()) return false;
- Type* pointee = dyn_cast<PointerType>(type)->getElementType();
- if (!HasRewriteType(pointee, pattern)) return false;
- int c = *pattern++;
- return c == ')';
- }
- default:
- llvm_unreachable("Unknown type specifier");
- return false;
- }
-}
-
-RegUse RegUseForRewriteRule(const TypeRewriteRule* rule) {
- const char* pattern = std::string("C") == rule->dst ? rule->src : rule->dst;
- RegUse result(0, 0);
- while (char c = *pattern++) {
- // Note, we only support a subset here, complex types (s, P)
- // would require more work
- switch (c) {
- case 'i':
- case 'l':
- result += RegUse::OneIntReg();
- break;
- case 'd':
- case 'f':
- result += RegUse::OneFloatReg();
- break;
- default:
- dbgs() << c << "\n";
- llvm_unreachable("unexpected return type");
- }
- }
- return result;
-}
-
-// Note, this only has to be accurate for x86-64 and is intentionally
-// quite strict so that we know when to add support for new types.
-// Ideally, unexpected types would be flagged by a bitcode checker.
-RegUse RegUseForType(const Type* t) {
- if (t->isPointerTy()) {
- return RegUse::OnePointerReg();
- } else if (t->isFloatTy() || t->isDoubleTy()) {
- return RegUse::OneFloatReg();
- } else if (t->isIntegerTy()) {
- const IntegerType* it = dyn_cast<const IntegerType>(t);
- unsigned width = it->getBitWidth();
- // x86-64 assumption here - use "register info" to make this better
- if (width <= 64) return RegUse::OneIntReg();
- }
-
- dbgs() << *const_cast<Type*>(t) << "\n";
- llvm_unreachable("unexpected type in RegUseForType");
-}
-
-// Match a type against a set of rewrite rules.
-// Return the matching rule, if any.
-const TypeRewriteRule* MatchRewriteRules(
- const Type* type, const TypeRewriteRule* rules) {
- if (rules == 0) return 0;
- for (; rules->name != 0; ++rules) {
- const char* pattern = rules->src;
- if (HasRewriteType(type, pattern)) return rules;
- }
- return 0;
-}
-
-// Same as MatchRewriteRules but "dereference" type first.
-const TypeRewriteRule* MatchRewriteRulesPointee(const Type* t,
- const TypeRewriteRule* Rules) {
- // sret and byval are both modelled as pointers
- const PointerType* pointer = dyn_cast<PointerType>(t);
- if (pointer == 0) return 0;
-
- return MatchRewriteRules(pointer->getElementType(), Rules);
-}
-
-// Note, the attributes are not part of the type but are stored
-// with the CallInst and/or the Function (if any)
-Type* CreateFunctionPointerType(Type* result_type,
- std::vector<Type*>& arguments) {
- FunctionType* ft = FunctionType::get(result_type,
- arguments,
- false);
- return PointerType::getUnqual(ft);
-}
-
-// Determines whether a function body needs a rewrite
-bool FunctionNeedsRewrite(const Function* fun,
- const TypeRewriteRule* ByvalRewriteRules,
- const TypeRewriteRule* SretRewriteRules,
- RegUse available) {
- // TODO: can this be detected on indirect callsites as well.
- // if we skip the rewrite for the function body
- // we also need to skip it at the callsites
- // if (F.isVarArg()) return false;
-
- // Vectors and Arrays are not supported for compatibility
- for (Function::const_arg_iterator AI = fun->arg_begin(), AE = fun->arg_end();
- AI != AE;
- ++AI) {
- const Type* t = AI->getType();
- if (isa<VectorType>(t) || isa<ArrayType>(t)) return false;
- }
-
- for (Function::const_arg_iterator AI = fun->arg_begin(), AE = fun->arg_end();
- AI != AE;
- ++AI) {
- const Argument& a = *AI;
- const Type* t = a.getType();
- // byval and srets are modelled as pointers (to structs)
- if (t->isPointerTy()) {
- Type* pointee = dyn_cast<PointerType>(t)->getElementType();
-
- if (ByvalRewriteRules && a.hasByValAttr()) {
- const TypeRewriteRule* rule =
- MatchRewriteRules(pointee, ByvalRewriteRules);
- if (rule != 0 && RegUseForRewriteRule(rule) <= available) {
- return true;
- }
- } else if (SretRewriteRules && a.hasStructRetAttr()) {
- if (0 != MatchRewriteRules(pointee, SretRewriteRules)) {
- return true;
- }
- }
- }
- available -= RegUseForType(t);
- }
- return false;
-}
-
-// Used for sret rewrites to determine the new function result type
-Type* GetNewReturnType(Type* type,
- const TypeRewriteRule* rule,
- LLVMContext& C) {
- if (std::string("l") == rule->dst ||
- std::string("d") == rule->dst) {
- return GetElementaryType(rule->dst[0], C);
- } else if (rule->dst[0] == 's') {
- const char* cp = rule->dst + 2; // skip 's('
- std::vector<Type*> fields;
- while (*cp != ')') {
- fields.push_back(GetElementaryType(*cp, C));
- ++cp;
- }
- return StructType::get(C, fields, false /* isPacked */);
- } else {
- dbgs() << *type << " " << rule->name << "\n";
- llvm_unreachable("unexpected return type");
- return 0;
- }
-}
-
-// Rewrite sret parameter while rewriting a function
-Type* RewriteFunctionSret(Function& F,
- Value* orig_val,
- const TypeRewriteRule* rule) {
- LLVMContext& C = F.getContext();
- BasicBlock& entry = F.getEntryBlock();
- Instruction* before = &(entry.front());
- Type* old_type = orig_val->getType();
- Type* old_pointee = dyn_cast<PointerType>(old_type)->getElementType();
- Type* new_type = GetNewReturnType(old_type, rule, C);
- // create a temporary to hold the return value as we no longer pass
- // in the pointer
- AllocaInst* tmp_ret = new AllocaInst(old_pointee, "result", before);
- orig_val->replaceAllUsesWith(tmp_ret);
- CastInst* cast_ret = CastInst::CreatePointerCast(
- tmp_ret,
- PointerType::getUnqual(new_type),
- "byval_cast",
- before);
- for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
- for (BasicBlock::iterator II = BI->begin(), IE = BI->end();
- II != IE;
- /* see below */) {
- Instruction* inst = II;
- // we do decontructive magic below, so advance the iterator here
- // (this is still a little iffy)
- ++II;
- ReturnInst* ret = dyn_cast<ReturnInst>(inst);
- if (ret) {
- if (ret->getReturnValue() != 0)
- llvm_unreachable("expected a void return");
- // load the return value from temporary
- Value *ret_val = new LoadInst(cast_ret, "load_result", ret);
- // return that loaded value and delete the return instruction
- ReturnInst::Create(C, ret_val, ret);
- ret->eraseFromParent();
- }
- }
- }
- return new_type;
-}
-
-// Rewrite one byval function parameter while rewriting a function
-void FixFunctionByvalsParameter(Function& F,
- std::vector<Argument*>& new_arguments,
- std::vector<Attribute>& new_attributes,
- Value* byval,
- const TypeRewriteRule* rule) {
- LLVMContext& C = F.getContext();
- BasicBlock& entry = F.getEntryBlock();
- Instruction* before = &(entry.front());
- Twine prefix = byval->getName() + "_split";
- Type* t = byval->getType();
- Type* pointee = dyn_cast<PointerType>(t)->getElementType();
- AllocaInst* tmp_param = new AllocaInst(pointee, prefix + "_param", before);
- byval->replaceAllUsesWith(tmp_param);
- // convert byval poiner to char pointer
- Value* base = CastInst::CreatePointerCast(
- tmp_param, PointerType::getInt8PtrTy(C), prefix + "_base", before);
-
- int width = 0;
- const char* pattern = rule->dst;
- for (int offset = 0; *pattern; ++pattern, offset += width) {
- width = GetElementaryTypeWidth(*pattern);
- Type* t = GetElementaryType(*pattern, C);
- Argument* arg = new Argument(t, prefix, &F);
- Type* pt = PointerType::getUnqual(t);
- // the code below generates something like:
- // <CHAR-PTR> = getelementptr i8* <BASE>, i32 <OFFSET-FROM-BASE>
- // <PTR> = bitcast i8* <CHAR-PTR> to <TYPE>*
- // store <ARG> <TYPE>* <ELEM-PTR>
- ConstantInt* baseOffset = ConstantInt::get(Type::getInt32Ty(C), offset);
- Value *v;
- v = GetElementPtrInst::Create(base, baseOffset, prefix + "_base_add", before);
- v = CastInst::CreatePointerCast(v, pt, prefix + "_cast", before);
- v = new StoreInst(arg, v, before);
-
- new_arguments.push_back(arg);
- new_attributes.push_back(Attribute());
- }
-}
-
-// Change function signature to reflect all the rewrites.
-// This includes function type/signature and attributes.
-void UpdateFunctionSignature(Function &F,
- Type* new_result_type,
- std::vector<Argument*>& new_arguments,
- std::vector<Attribute>& new_attributes) {
- DEBUG(dbgs() << "PHASE PROTOTYPE UPDATE\n");
- if (new_result_type) {
- DEBUG(dbgs() << "NEW RESULT TYPE: " << *new_result_type << "\n");
- }
- // Update function type
- FunctionType* old_fun_type = F.getFunctionType();
- std::vector<Type*> new_types;
- for (size_t i = 0; i < new_arguments.size(); ++i) {
- new_types.push_back(new_arguments[i]->getType());
- }
-
- FunctionType* new_fun_type = FunctionType::get(
- new_result_type ? new_result_type : old_fun_type->getReturnType(),
- new_types,
- false);
- F.setType(PointerType::getUnqual(new_fun_type));
-
- Function::ArgumentListType& args = F.getArgumentList();
- DEBUG(dbgs() << "PHASE ARGUMENT DEL " << args.size() << "\n");
- while (args.size()) {
- Argument* arg = args.begin();
- DEBUG(dbgs() << "DEL " << arg->getArgNo() << " " << arg->getName() << "\n");
- args.remove(args.begin());
- }
-
- DEBUG(dbgs() << "PHASE ARGUMENT ADD " << new_arguments.size() << "\n");
- for (size_t i = 0; i < new_arguments.size(); ++i) {
- Argument* arg = new_arguments[i];
- DEBUG(dbgs() << "ADD " << i << " " << arg->getName() << "\n");
- args.push_back(arg);
- }
-
- DEBUG(dbgs() << "PHASE ATTRIBUTES UPDATE\n");
- std::vector<AttributeWithIndex> new_attributes_vec;
- for (size_t i = 0; i < new_attributes.size(); ++i) {
- Attribute attr = new_attributes[i];
- if (attr.hasAttributes()) {
- new_attributes_vec.push_back(AttributeWithIndex::get(i + 1, attr));
- }
- }
- Attribute fattr = F.getAttributes().getFnAttributes();
- if (fattr.hasAttributes())
- new_attributes_vec.push_back(AttributeWithIndex::get(~0, fattr));
- F.setAttributes(AttributeSet::get(F.getContext(), new_attributes_vec));
-}
-
-
-void ExtractFunctionArgsAndAttributes(Function& F,
- std::vector<Argument*>& old_arguments,
- std::vector<Attribute>& old_attributes) {
- for (Function::arg_iterator ai = F.arg_begin(),
- end = F.arg_end();
- ai != end;
- ++ai) {
- old_arguments.push_back(ai);
- }
-
- for (size_t i = 0; i < old_arguments.size(); ++i) {
- // index zero is for return value attributes
- old_attributes.push_back(F.getAttributes().getParamAttributes(i + 1));
- }
-}
-
-// Apply byval or sret rewrites to function body.
-void NaClCcRewrite::RewriteFunctionPrologAndEpilog(Function& F) {
-
- DEBUG(dbgs() << "\nFUNCTION-REWRITE\n");
-
- DEBUG(dbgs() << "FUNCTION BEFORE ");
- DEBUG(dbgs() << F);
- DEBUG(dbgs() << "\n");
-
- std::vector<Argument*> new_arguments;
- std::vector<Attribute> new_attributes;
- std::vector<Argument*> old_arguments;
- std::vector<Attribute> old_attributes;
-
-
- // make a copy of everything first as create Argument adds them to the list
- ExtractFunctionArgsAndAttributes(F, old_arguments, old_attributes);
-
- // A non-zero new_result_type indicates an sret rewrite
- Type* new_result_type = 0;
-
- // only the first arg can be "sret"
- if (old_attributes.size() > 0 && old_attributes[0].hasAttribute(Attribute::StructRet)) {
- const TypeRewriteRule* sret_rule =
- MatchRewriteRulesPointee(old_arguments[0]->getType(), SretRewriteRules);
- if (sret_rule) {
- Argument* arg = old_arguments[0];
- DEBUG(dbgs() << "REWRITING SRET "
- << " arg " << arg->getName() << " " << sret_rule->name << "\n");
- new_result_type = RewriteFunctionSret(F, arg, sret_rule);
- old_arguments.erase(old_arguments.begin());
- old_attributes.erase(old_attributes.begin());
- }
- }
-
- // now deal with the byval arguments
- RegUse available = AvailableRegs;
- for (size_t i = 0; i < old_arguments.size(); ++i) {
- Argument* arg = old_arguments[i];
- Type* t = arg->getType();
- Attribute attr = old_attributes[i];
- if (attr.hasAttribute(Attribute::ByVal)) {
- const TypeRewriteRule* rule =
- MatchRewriteRulesPointee(t, ByvalRewriteRules);
- if (rule != 0 && RegUseForRewriteRule(rule) <= available) {
- DEBUG(dbgs() << "REWRITING BYVAL "
- << *t << " arg " << arg->getName() << " " << rule->name << "\n");
- FixFunctionByvalsParameter(F,
- new_arguments,
- new_attributes,
- arg,
- rule);
- available -= RegUseForRewriteRule(rule);
- continue;
- }
- }
-
- // fall through case - no rewrite is happening
- new_arguments.push_back(arg);
- new_attributes.push_back(attr);
- available -= RegUseForType(t);
- }
-
- UpdateFunctionSignature(F, new_result_type, new_arguments, new_attributes);
-
- DEBUG(dbgs() << "FUNCTION AFTER ");
- DEBUG(dbgs() << F);
- DEBUG(dbgs() << "\n");
-}
-
-// used for T in {CallInst, InvokeInst}
-// TODO(robertm): try unifying this code with FunctionNeedsRewrite()
-template<class T> bool CallNeedsRewrite(
- const Instruction* inst,
- const TypeRewriteRule* ByvalRewriteRules,
- const TypeRewriteRule* SretRewriteRules,
- RegUse available) {
-
- const T* call = cast<T>(inst);
- // skip non parameter operands at the end
- size_t num_params = call->getNumOperands() - (isa<CallInst>(inst) ? 1 : 3);
-
- // Vectors and Arrays are not supported for compatibility
- for (size_t i = 0; i < num_params; ++i) {
- Type* t = call->getOperand(i)->getType();
- if (isa<VectorType>(t) || isa<ArrayType>(t)) return false;
- }
-
- for (size_t i = 0; i < num_params; ++i) {
- Type* t = call->getOperand(i)->getType();
- // byval and srets are modelled as pointers (to structs)
- if (t->isPointerTy()) {
- Type* pointee = dyn_cast<PointerType>(t)->getElementType();
-
- // param zero is for the return value
- if (ByvalRewriteRules && call->paramHasAttr(i + 1, Attribute::ByVal)) {
- const TypeRewriteRule* rule =
- MatchRewriteRules(pointee, ByvalRewriteRules);
- if (rule != 0 && RegUseForRewriteRule(rule) <= available) {
- return true;
- }
- } else if (SretRewriteRules &&
- call->paramHasAttr(i + 1, Attribute::StructRet)) {
- if (0 != MatchRewriteRules(pointee, SretRewriteRules)) {
- return true;
- }
- }
- }
- available -= RegUseForType(t);
- }
- return false;
-}
-
-// This code will load the fields of the byval ptr into scalar variables
-// which will then be used as argument when we rewrite the actual call
-// instruction.
-void PrependCompensationForByvals(std::vector<Value*>& new_operands,
- std::vector<Attribute>& new_attributes,
- Instruction* call,
- Value* byval,
- const TypeRewriteRule* rule,
- LLVMContext& C) {
- // convert byval poiner to char pointer
- Value* base = CastInst::CreatePointerCast(
- byval, PointerType::getInt8PtrTy(C), "byval_base", call);
-
- int width = 0;
- const char* pattern = rule->dst;
- for (int offset = 0; *pattern; ++pattern, offset += width) {
- width = GetElementaryTypeWidth(*pattern);
- Type* t = GetElementaryType(*pattern, C);
- Type* pt = PointerType::getUnqual(t);
- // the code below generates something like:
- // <CHAR-PTR> = getelementptr i8* <BASE>, i32 <OFFSET-FROM-BASE>
- // <PTR> = bitcast i8* <CHAR-PTR> to i32*
- // <SCALAR> = load i32* <ELEM-PTR>
- ConstantInt* baseOffset = ConstantInt::get(Type::getInt32Ty(C), offset);
- Value* v;
- v = GetElementPtrInst::Create(base, baseOffset, "byval_base_add", call);
- v = CastInst::CreatePointerCast(v, pt, "byval_cast", call);
- v = new LoadInst(v, "byval_extract", call);
-
- new_operands.push_back(v);
- new_attributes.push_back(Attribute());
- }
-}
-
-// Note: this will only be called if we expect a rewrite to occur
-void CallsiteFixupSrets(Instruction* call,
- Value* sret,
- Type* new_type,
- const TypeRewriteRule* rule) {
- const char* pattern = rule->dst;
- Instruction* next;
- if (isa<CallInst>(call)) {
- next = call->getNextNode();
- } else if (isa<InvokeInst>(call)) {
- // if this scheme turns out to be too simplistic (i.e. asserts fire)
- // we need to introduce a new basic block for the compensation code.
- BasicBlock* normal = dyn_cast<InvokeInst>(call)->getNormalDest();
- if (!normal->getSinglePredecessor()) {
- llvm_unreachable("unexpected invoke normal bb");
- }
- next = normal->getFirstNonPHI();
- } else {
- llvm_unreachable("unexpected call instruction");
- }
-
- if (next == 0) {
- llvm_unreachable("unexpected missing next instruction");
- }
-
- if (pattern[0] == 's' ||
- std::string("l") == pattern ||
- std::string("d") == pattern) {
- Type* pt = PointerType::getUnqual(new_type);
- Value* cast = CastInst::CreatePointerCast(sret, pt, "cast", next);
- new StoreInst(call, cast, next);
- } else {
- dbgs() << rule->name << "\n";
- llvm_unreachable("unexpected return type at fix up");
- }
-}
-
-void ExtractOperandsAndAttributesFromCallInst(
- CallInst* call,
- std::vector<Value*>& operands,
- std::vector<Attribute>& attributes) {
-
- AttributeSet PAL = call->getAttributes();
- // last operand is: function
- for (size_t i = 0; i < call->getNumOperands() - 1; ++i) {
- operands.push_back(call->getArgOperand(i));
- // index zero is for return value attributes
- attributes.push_back(PAL.getParamAttributes(i + 1));
- }
-}
-
-// Note: this differs from the one above in the loop bounds
-void ExtractOperandsAndAttributesFromeInvokeInst(
- InvokeInst* call,
- std::vector<Value*>& operands,
- std::vector<Attribute>& attributes) {
- AttributeSet PAL = call->getAttributes();
- // last three operands are: function, bb-normal, bb-exception
- for (size_t i = 0; i < call->getNumOperands() - 3; ++i) {
- operands.push_back(call->getArgOperand(i));
- // index zero is for return value attributes
- attributes.push_back(PAL.getParamAttributes(i + 1));
- }
-}
-
-
-Instruction* ReplaceCallInst(CallInst* call,
- Type* function_pointer,
- std::vector<Value*>& new_operands,
- std::vector<Attribute>& new_attributes) {
- Value* v = CastInst::CreatePointerCast(
- call->getCalledValue(), function_pointer, "fp_cast", call);
- CallInst* new_call = CallInst::Create(v, new_operands, "", call);
- // NOTE: tail calls may be ruled out but byval/sret, should we assert this?
- // TODO: did wid forget to clone anything else?
- new_call->setTailCall(call->isTailCall());
- new_call->setCallingConv(call->getCallingConv());
- for (size_t i = 0; i < new_attributes.size(); ++i) {
- // index zero is for return value attributes
- new_call->addAttribute(i + 1, new_attributes[i]);
- }
- return new_call;
-}
-
-Instruction* ReplaceInvokeInst(InvokeInst* call,
- Type* function_pointer,
- std::vector<Value*>& new_operands,
- std::vector<Attribute>& new_attributes) {
- Value* v = CastInst::CreatePointerCast(
- call->getCalledValue(), function_pointer, "fp_cast", call);
- InvokeInst* new_call = InvokeInst::Create(v,
- call->getNormalDest(),
- call->getUnwindDest(),
- new_operands,
- "",
- call);
- for (size_t i = 0; i < new_attributes.size(); ++i) {
- // index zero is for return value attributes
- new_call->addAttribute(i + 1, new_attributes[i]);
- }
- return new_call;
-}
-
-
-void NaClCcRewrite::RewriteCallsite(Instruction* call, LLVMContext& C) {
- BasicBlock* BB = call->getParent();
-
- DEBUG(dbgs() << "\nCALLSITE-REWRITE\n");
- DEBUG(dbgs() << "CALLSITE BB BEFORE " << *BB);
- DEBUG(dbgs() << "\n");
- DEBUG(dbgs() << *call << "\n");
- if (isa<InvokeInst>(call)) {
- DEBUG(dbgs() << "\n" << *(dyn_cast<InvokeInst>(call)->getNormalDest()));
- }
-
- // new_result(_type) is only relevent if an sret is rewritten
- // whish is indicated by sret_rule != 0
- const TypeRewriteRule* sret_rule = 0;
- Type* new_result_type = call->getType();
- // This is the sret which was originally passed in as the first arg.
- // After the rewrite we simply copy the function result into it.
- Value* new_result = 0;
-
- std::vector<Value*> old_operands;
- std::vector<Attribute> old_attributes;
- if (isa<CallInst>(call)) {
- ExtractOperandsAndAttributesFromCallInst(
- cast<CallInst>(call), old_operands, old_attributes);
- } else if (isa<InvokeInst>(call)) {
- ExtractOperandsAndAttributesFromeInvokeInst(
- cast<InvokeInst>(call), old_operands, old_attributes);
- } else {
- llvm_unreachable("Unexpected instruction type");
- }
-
- // handle sret (just the book-keeping, 'new_result' is dealt with below)
- // only the first arg can be "sret"
- if (old_attributes[0].hasAttribute(Attribute::StructRet)) {
- sret_rule = MatchRewriteRulesPointee(
- old_operands[0]->getType(), SretRewriteRules);
- if (sret_rule) {
- new_result_type =
- GetNewReturnType(old_operands[0]->getType(), sret_rule, C);
- new_result = old_operands[0];
- old_operands.erase(old_operands.begin());
- old_attributes.erase(old_attributes.begin());
- }
- }
-
- // handle byval
- std::vector<Value*> new_operands;
- std::vector<Attribute> new_attributes;
- RegUse available = AvailableRegs;
-
- for (size_t i = 0; i < old_operands.size(); ++i) {
- Value *operand = old_operands[i];
- Type* t = operand->getType();
- Attribute attr = old_attributes[i];
-
- if (attr.hasAttribute(Attribute::ByVal)) {
- const TypeRewriteRule* rule =
- MatchRewriteRulesPointee(t, ByvalRewriteRules);
- if (rule != 0 && RegUseForRewriteRule(rule) <= available) {
- DEBUG(dbgs() << "REWRITING BYVAL "
- << *t << " arg " << i << " " << rule->name << "\n");
- PrependCompensationForByvals(new_operands,
- new_attributes,
- call,
- operand,
- rule,
- C);
- available -= RegUseForRewriteRule(rule);
- continue;
- }
- }
-
- // fall through case - no rewrite is happening
- new_operands.push_back(operand);
- new_attributes.push_back(attr);
- available -= RegUseForType(t);
- }
-
- // Note, this code is tricky.
- // Initially we used a much more elaborate scheme introducing
- // new function declarations for direct calls.
- // This simpler scheme, however, works for both direct and
- // indirect calls
- // We transform (here the direct case):
- // call void @result_PP_FloatPoint(%struct.PP_FloatPoint* sret %sret)
- // into
- // %fp_cast = bitcast void (%struct.PP_FloatPoint*)*
- // @result_PP_FloatPoint to %struct.PP_FloatPoint ()*
- // %result = call %struct.PP_FloatPoint %fp_cast()
- //
- std::vector<Type*> new_arg_types;
- for (size_t i = 0; i < new_operands.size(); ++i) {
- new_arg_types.push_back(new_operands[i]->getType());
- }
-
- DEBUG(dbgs() << "REWRITE CALL INSTRUCTION\n");
- Instruction* new_call = 0;
- if (isa<CallInst>(call)) {
- new_call = ReplaceCallInst(
- cast<CallInst>(call),
- CreateFunctionPointerType(new_result_type, new_arg_types),
- new_operands,
- new_attributes);
- } else if (isa<InvokeInst>(call)) {
- new_call = ReplaceInvokeInst(
- cast<InvokeInst>(call),
- CreateFunctionPointerType(new_result_type, new_arg_types),
- new_operands,
- new_attributes);
- } else {
- llvm_unreachable("Unexpected instruction type");
- }
-
- // We prepended the new call, now get rid of the old one.
- // If we did not change the return type, there may be consumers
- // of the result which must be redirected.
- if (!sret_rule) {
- call->replaceAllUsesWith(new_call);
- }
- call->eraseFromParent();
-
- // Add compensation codes for srets if necessary
- if (sret_rule) {
- DEBUG(dbgs() << "REWRITING SRET " << sret_rule->name << "\n");
- CallsiteFixupSrets(new_call, new_result, new_result_type, sret_rule);
- }
-
- DEBUG(dbgs() << "CALLSITE BB AFTER" << *BB);
- DEBUG(dbgs() << "\n");
- DEBUG(dbgs() << *new_call << "\n");
- if (isa<InvokeInst>(call)) {
- DEBUG(dbgs() << "\n" << *(dyn_cast<InvokeInst>(call)->getNormalDest()));
- }
-}
-
-bool NaClCcRewrite::runOnFunction(Function &F) {
- // No rules - no action
- if (ByvalRewriteRules == 0 && SretRewriteRules == 0) return false;
-
- bool Changed = false;
-
- if (FunctionNeedsRewrite(&F, ByvalRewriteRules, SretRewriteRules, AvailableRegs)) {
- DEBUG(dbgs() << "FUNCTION NEEDS REWRITE " << F.getName() << "\n");
- RewriteFunctionPrologAndEpilog(F);
- Changed = true;
- }
-
- // Find all the calls and invokes in F and rewrite them if necessary
- for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
- for (BasicBlock::iterator II = BI->begin(), IE = BI->end();
- II != IE;
- /* II updated below */) {
- Instruction* inst = II;
- // we do decontructive magic below, so advance the iterator here
- // (this is still a little iffy)
- ++II;
- if (isa<InvokeInst>(inst) || isa<CallInst>(inst)) {
- // skip calls to llvm.dbg.declare, etc.
- if (isa<IntrinsicInst>(inst)) continue;
-
- if (isa<CallInst>(inst) &&
- !CallNeedsRewrite<CallInst>
- (inst, ByvalRewriteRules, SretRewriteRules, AvailableRegs)) continue;
-
- if (isa<InvokeInst>(inst) &&
- !CallNeedsRewrite<InvokeInst>
- (inst, ByvalRewriteRules, SretRewriteRules, AvailableRegs)) continue;
-
- RewriteCallsite(inst, F.getContext());
- Changed = true;
- }
- }
- }
- return Changed;
-}
-
-} // end anonymous namespace
-
-
-INITIALIZE_PASS(NaClCcRewrite, "naclcc", "NaCl CC Rewriter", false, false)
-
-FunctionPass *llvm::createNaClCcRewritePass(const TargetLowering *tli) {
- return new NaClCcRewrite(tli);
-}
diff --git a/test/NaCl/ARM/neon-vld1-sandboxing.ll b/test/NaCl/ARM/neon-vld1-sandboxing.ll
index bf3dc253a6..9ae7990371 100644
--- a/test/NaCl/ARM/neon-vld1-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vld1-sandboxing.ll
@@ -4,7 +4,7 @@
define <8 x i8> @vld1i8(i8* %A) nounwind {
%tmp1 = call <8 x i8> @llvm.arm.neon.vld1.v8i8(i8* %A, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.8 {{{d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vld1.8 {{{d[0-9]+}}}, [r0:64]
ret <8 x i8> %tmp1
}
@@ -39,7 +39,7 @@ define <1 x i64> @vld1i64(i32 %foo, i32 %bar, i32 %baz,
define <16 x i8> @vld1Qi8(i8* %A) nounwind {
%tmp1 = call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %A, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.8 {{{d[0-9]+}}, {{d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vld1.8 {{{d[0-9]+}}, {{d[0-9]+}}}, [r0:64]
ret <16 x i8> %tmp1
}
@@ -47,7 +47,7 @@ define <8 x i16> @vld1Qi16(i16* %A) nounwind {
%tmp0 = bitcast i16* %A to i8*
%tmp1 = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %tmp0, i32 32)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.16 {{{d[0-9]+}}, {{d[0-9]+}}}, [r0, :128]
+; CHECK-NEXT: vld1.16 {{{d[0-9]+}}, {{d[0-9]+}}}, [r0:128]
ret <8 x i16> %tmp1
}
@@ -83,7 +83,7 @@ define <16 x i8> @vld1Qi8_update(i8** %ptr) nounwind {
%A = load i8** %ptr
%tmp1 = call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %A, i32 8)
; CHECK: bic r1, r1, #3221225472
-; CHECK-NEXT: vld1.8 {{{d[0-9]+}}, {{d[0-9]+}}}, [r1, :64]!
+; CHECK-NEXT: vld1.8 {{{d[0-9]+}}, {{d[0-9]+}}}, [r1:64]!
%tmp2 = getelementptr i8* %A, i32 16
store i8* %tmp2, i8** %ptr
ret <16 x i8> %tmp1
diff --git a/test/NaCl/ARM/neon-vld2-sandboxing.ll b/test/NaCl/ARM/neon-vld2-sandboxing.ll
index b67a9bf4d1..788fdb55da 100644
--- a/test/NaCl/ARM/neon-vld2-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vld2-sandboxing.ll
@@ -29,7 +29,7 @@ define <8 x i8> @vld2i8(i8* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x8x2_t %tmp1, 1
%tmp4 = add <8 x i8> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :64]
+; CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0:64]
ret <8 x i8> %tmp4
}
@@ -40,7 +40,7 @@ define <4 x i16> @vld2i16(i16* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int16x4x2_t %tmp1, 1
%tmp4 = add <4 x i16> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :128]
+; CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0:128]
ret <4 x i16> %tmp4
}
@@ -61,7 +61,7 @@ define <16 x i8> @vld2Qi8(i8* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x16x2_t %tmp1, 1
%tmp4 = add <16 x i8> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :64]
+; CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:64]
ret <16 x i8> %tmp4
}
@@ -72,7 +72,7 @@ define <8 x i16> @vld2Qi16(i16* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int16x8x2_t %tmp1, 1
%tmp4 = add <8 x i16> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :128]
+; CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:128]
ret <8 x i16> %tmp4
}
@@ -83,7 +83,7 @@ define <4 x i32> @vld2Qi32(i32* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int32x4x2_t %tmp1, 1
%tmp4 = add <4 x i32> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :256]
+; CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:256]
ret <4 x i32> %tmp4
}
@@ -94,7 +94,7 @@ define <16 x i8> @vld2Qi8_update(i8** %ptr, i32 %inc) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x16x2_t %tmp1, 1
%tmp4 = add <16 x i8> %tmp2, %tmp3
; CHECK: bic r2, r2, #3221225472
-; CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r2, :128], r1
+; CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r2:128], r1
%tmp5 = getelementptr i8* %A, i32 %inc
store i8* %tmp5, i8** %ptr
ret <16 x i8> %tmp4
diff --git a/test/NaCl/ARM/neon-vld3-sandboxing.ll b/test/NaCl/ARM/neon-vld3-sandboxing.ll
index 7fb8eb3077..5658b33d89 100644
--- a/test/NaCl/ARM/neon-vld3-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vld3-sandboxing.ll
@@ -29,7 +29,7 @@ define <8 x i8> @vld3i8(i32 %foobar, i32 %ba, i8* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x8x3_t %tmp1, 2
%tmp4 = add <8 x i8> %tmp2, %tmp3
; CHECK: bic r2, r2, #3221225472
-; CHECK-NEXT: vld3.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r2, :64]
+; CHECK-NEXT: vld3.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r2:64]
ret <8 x i8> %tmp4
}
@@ -62,7 +62,7 @@ define <1 x i64> @vld3i64(i64* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int64x1x3_t %tmp1, 2
%tmp4 = add <1 x i64> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.64 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vld1.64 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:64]
ret <1 x i64> %tmp4
}
@@ -72,7 +72,7 @@ define <16 x i8> @vld3Qi8(i8* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x16x3_t %tmp1, 2
%tmp4 = add <16 x i8> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld3.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :64]!
+; CHECK-NEXT: vld3.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:64]!
ret <16 x i8> %tmp4
}
diff --git a/test/NaCl/ARM/neon-vld4-sandboxing.ll b/test/NaCl/ARM/neon-vld4-sandboxing.ll
index 570a3ce24c..74b0aafc7e 100644
--- a/test/NaCl/ARM/neon-vld4-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vld4-sandboxing.ll
@@ -29,7 +29,7 @@ define <8 x i8> @vld4i8(i8* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x8x4_t %tmp1, 2
%tmp4 = add <8 x i8> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:64]
ret <8 x i8> %tmp4
}
@@ -40,7 +40,7 @@ define <4 x i16> @vld4i16(i16* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int16x4x4_t %tmp1, 2
%tmp4 = add <4 x i16> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.16 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :128]
+; CHECK-NEXT: vld4.16 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:128]
ret <4 x i16> %tmp4
}
@@ -51,7 +51,7 @@ define <2 x i32> @vld4i32(i32* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int32x2x4_t %tmp1, 2
%tmp4 = add <2 x i32> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.32 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :256]
+; CHECK-NEXT: vld4.32 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:256]
ret <2 x i32> %tmp4
}
@@ -62,7 +62,7 @@ define <1 x i64> @vld4i64(i64* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int64x1x4_t %tmp1, 2
%tmp4 = add <1 x i64> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.64 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :256]
+; CHECK-NEXT: vld1.64 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:256]
ret <1 x i64> %tmp4
}
@@ -72,9 +72,9 @@ define <16 x i8> @vld4Qi8(i8* %A) nounwind {
%tmp3 = extractvalue %struct.__neon_int8x16x4_t %tmp1, 2
%tmp4 = add <16 x i8> %tmp2, %tmp3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :256]!
+; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:256]!
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0, :256]
+; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r0:256]
ret <16 x i8> %tmp4
}
@@ -82,7 +82,7 @@ define <8 x i8> @vld4i8_update(i8** %ptr, i32 %inc) nounwind {
%A = load i8** %ptr
%tmp1 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4.v8i8(i8* %A, i32 16)
; CHECK: bic r2, r2, #3221225472
-; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r2, :128], r1
+; CHECK-NEXT: vld4.8 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r2:128], r1
%tmp2 = extractvalue %struct.__neon_int8x8x4_t %tmp1, 0
%tmp3 = extractvalue %struct.__neon_int8x8x4_t %tmp1, 2
%tmp4 = add <8 x i8> %tmp2, %tmp3
@@ -96,7 +96,7 @@ define <8 x i16> @vld4Qi16_update(i16** %ptr) nounwind {
%tmp0 = bitcast i16* %A to i8*
%tmp1 = call %struct.__neon_int16x8x4_t @llvm.arm.neon.vld4.v8i16(i8* %tmp0, i32 8)
; CHECK: bic r1, r1, #3221225472
-; CHECK-NEXT: vld4.16 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r1, :64]!
+; CHECK-NEXT: vld4.16 {{{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}}, [r1:64]!
%tmp2 = extractvalue %struct.__neon_int16x8x4_t %tmp1, 0
%tmp3 = extractvalue %struct.__neon_int16x8x4_t %tmp1, 2
%tmp4 = add <8 x i16> %tmp2, %tmp3
diff --git a/test/NaCl/ARM/neon-vlddup-sandboxing.ll b/test/NaCl/ARM/neon-vlddup-sandboxing.ll
index 18e1b41de1..0ce51ad8cc 100644
--- a/test/NaCl/ARM/neon-vlddup-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vlddup-sandboxing.ll
@@ -36,7 +36,7 @@ define <4 x i16> @vld1dupi16(i16* %A) nounwind {
%tmp2 = insertelement <4 x i16> undef, i16 %tmp1, i32 0
%tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> undef, <4 x i32> zeroinitializer
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.16 {{{d[0-9]+\[\]}}}, [r0, :16]
+; CHECK-NEXT: vld1.16 {{{d[0-9]+\[\]}}}, [r0:16]
ret <4 x i16> %tmp3
}
@@ -45,7 +45,7 @@ define <2 x i32> @vld1dupi32(i32* %A) nounwind {
%tmp2 = insertelement <2 x i32> undef, i32 %tmp1, i32 0
%tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> undef, <2 x i32> zeroinitializer
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.32 {{{d[0-9]+\[\]}}}, [r0, :32]
+; CHECK-NEXT: vld1.32 {{{d[0-9]+\[\]}}}, [r0:32]
ret <2 x i32> %tmp3
}
@@ -85,7 +85,7 @@ define <4 x i16> @vld2dupi16(i8* %A) nounwind {
define <2 x i32> @vld2dupi32(i8* %A) nounwind {
%tmp0 = tail call %struct.__neon_int2x32x2_t @llvm.arm.neon.vld2lane.v2i32(i8* %A, <2 x i32> undef, <2 x i32> undef, i32 0, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld2.32 {{{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}}, [r0, :64]
+; CHECK-NEXT: vld2.32 {{{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}}, [r0:64]
%tmp1 = extractvalue %struct.__neon_int2x32x2_t %tmp0, 0
%tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer
%tmp3 = extractvalue %struct.__neon_int2x32x2_t %tmp0, 1
@@ -112,7 +112,7 @@ define <4 x i16> @vld3dupi16(i8* %A) nounwind {
define <2 x i32> @vld4dupi32(i8* %A) nounwind {
%tmp0 = tail call %struct.__neon_int32x2x4_t @llvm.arm.neon.vld4lane.v2i32(i8* %A, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 0, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.32 {{{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}}, [r0, :64]
+; CHECK-NEXT: vld4.32 {{{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}, {{d[0-9]+\[\]}}}, [r0:64]
%tmp1 = extractvalue %struct.__neon_int32x2x4_t %tmp0, 0
%tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer
%tmp3 = extractvalue %struct.__neon_int32x2x4_t %tmp0, 1
diff --git a/test/NaCl/ARM/neon-vldlane-sandboxing.ll b/test/NaCl/ARM/neon-vldlane-sandboxing.ll
index fbcef81ac9..9c890c7a61 100644
--- a/test/NaCl/ARM/neon-vldlane-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vldlane-sandboxing.ll
@@ -69,7 +69,7 @@ define <4 x i16> @vld1lanei16(i16* %A, <4 x i16>* %B) nounwind {
%tmp2 = load i16* %A, align 8
%tmp3 = insertelement <4 x i16> %tmp1, i16 %tmp2, i32 2
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.16 {{{d[0-9]+\[[0-9]\]}}}, [r0, :16]
+; CHECK-NEXT: vld1.16 {{{d[0-9]+\[[0-9]\]}}}, [r0:16]
ret <4 x i16> %tmp3
}
@@ -78,7 +78,7 @@ define <2 x i32> @vld1lanei32(i32* %A, <2 x i32>* %B) nounwind {
%tmp2 = load i32* %A, align 8
%tmp3 = insertelement <2 x i32> %tmp1, i32 %tmp2, i32 1
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.32 {{{d[0-9]+\[[0-9]\]}}}, [r0, :32]
+; CHECK-NEXT: vld1.32 {{{d[0-9]+\[[0-9]\]}}}, [r0:32]
ret <2 x i32> %tmp3
}
@@ -96,7 +96,7 @@ define <8 x i16> @vld1laneQi16(i16* %A, <8 x i16>* %B) nounwind {
%tmp2 = load i16* %A, align 8
%tmp3 = insertelement <8 x i16> %tmp1, i16 %tmp2, i32 5
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.16 {{{d[0-9]+\[[0-9]\]}}}, [r0, :16]
+; CHECK-NEXT: vld1.16 {{{d[0-9]+\[[0-9]\]}}}, [r0:16]
ret <8 x i16> %tmp3
}
@@ -105,7 +105,7 @@ define <4 x i32> @vld1laneQi32(i32* %A, <4 x i32>* %B) nounwind {
%tmp2 = load i32* %A, align 8
%tmp3 = insertelement <4 x i32> %tmp1, i32 %tmp2, i32 3
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld1.32 {{{d[0-9]+\[[0-9]\]}}}, [r0, :32]
+; CHECK-NEXT: vld1.32 {{{d[0-9]+\[[0-9]\]}}}, [r0:32]
ret <4 x i32> %tmp3
}
@@ -116,7 +116,7 @@ define <8 x i8> @vld2lanei8(i8* %A, <8 x i8>* %B) nounwind {
%tmp4 = extractvalue %struct.__neon_int8x8x2_t %tmp2, 1
%tmp5 = add <8 x i8> %tmp3, %tmp4
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld2.8 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0, :16]
+; CHECK-NEXT: vld2.8 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0:16]
ret <8 x i8> %tmp5
}
@@ -128,7 +128,7 @@ define <4 x i16> @vld2lanei16(i16* %A, <4 x i16>* %B) nounwind {
%tmp4 = extractvalue %struct.__neon_int16x4x2_t %tmp2, 1
%tmp5 = add <4 x i16> %tmp3, %tmp4
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld2.16 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0, :32]
+; CHECK-NEXT: vld2.16 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0:32]
ret <4 x i16> %tmp5
}
@@ -165,7 +165,7 @@ define <4 x i32> @vld2laneQi32(i32* %A, <4 x i32>* %B) nounwind {
%tmp4 = extractvalue %struct.__neon_int32x4x2_t %tmp2, 1
%tmp5 = add <4 x i32> %tmp3, %tmp4
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld2.32 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0, :64]
+; CHECK-NEXT: vld2.32 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0:64]
ret <4 x i32> %tmp5
}
@@ -249,7 +249,7 @@ define <8 x i8> @vld4lanei8(i8* %A, <8 x i8>* %B) nounwind {
%tmp8 = add <8 x i8> %tmp5, %tmp6
%tmp9 = add <8 x i8> %tmp7, %tmp8
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.8 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0, :32]
+; CHECK-NEXT: vld4.8 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0:32]
ret <8 x i8> %tmp9
}
@@ -281,7 +281,7 @@ define <2 x i32> @vld4lanei32(i32* %A, <2 x i32>* %B) nounwind {
%tmp8 = add <2 x i32> %tmp5, %tmp6
%tmp9 = add <2 x i32> %tmp7, %tmp8
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.32 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0, :64]
+; CHECK-NEXT: vld4.32 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0:64]
ret <2 x i32> %tmp9
}
@@ -297,7 +297,7 @@ define <8 x i16> @vld4laneQi16(i16* %A, <8 x i16>* %B) nounwind {
%tmp8 = add <8 x i16> %tmp5, %tmp6
%tmp9 = add <8 x i16> %tmp7, %tmp8
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vld4.16 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0, :64]
+; CHECK-NEXT: vld4.16 {{{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}, {{d[0-9]+\[[0-9]\]}}}, [r0:64]
ret <8 x i16> %tmp9
}
diff --git a/test/NaCl/ARM/neon-vst1-sandboxing.ll b/test/NaCl/ARM/neon-vst1-sandboxing.ll
index 4c472aa216..361b8668a9 100644
--- a/test/NaCl/ARM/neon-vst1-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vst1-sandboxing.ll
@@ -5,7 +5,7 @@ define void @vst1i8(i8* %A, <8 x i8>* %B) nounwind {
%tmp1 = load <8 x i8>* %B
call void @llvm.arm.neon.vst1.v8i8(i8* %A, <8 x i8> %tmp1, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst1.8 {{{d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vst1.8 {{{d[0-9]+}}}, [r0:64]
ret void
}
@@ -51,7 +51,7 @@ define void @vst1Qi8(i8* %A, <16 x i8>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst1.v16i8(i8* %A, <16 x i8> %tmp1, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0:64]
ret void
}
@@ -62,7 +62,7 @@ define void @vst1Qi16(i16* %A, <8 x i16>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst1.v8i16(i8* %tmp0, <8 x i16> %tmp1, i32 32)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst1.16 {{{d[0-9]+, d[0-9]+}}}, [r0, :128]
+; CHECK-NEXT: vst1.16 {{{d[0-9]+, d[0-9]+}}}, [r0:128]
ret void
}
diff --git a/test/NaCl/ARM/neon-vst2-sandboxing.ll b/test/NaCl/ARM/neon-vst2-sandboxing.ll
index f01064f877..155994abf8 100644
--- a/test/NaCl/ARM/neon-vst2-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vst2-sandboxing.ll
@@ -5,7 +5,7 @@ define void @vst2i8(i8* %A, <8 x i8>* %B) nounwind {
%tmp1 = load <8 x i8>* %B
call void @llvm.arm.neon.vst2.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.8 {{{d[0-9]+, d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vst2.8 {{{d[0-9]+, d[0-9]+}}}, [r0:64]
ret void
}
@@ -14,7 +14,7 @@ define void @vst2i16(i16* %A, <4 x i16>* %B) nounwind {
%tmp1 = load <4 x i16>* %B
call void @llvm.arm.neon.vst2.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 32)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.16 {{{d[0-9]+, d[0-9]+}}}, [r0, :128]
+; CHECK-NEXT: vst2.16 {{{d[0-9]+, d[0-9]+}}}, [r0:128]
ret void
}
@@ -42,7 +42,7 @@ define void @vst2Qi8(i8* %A, <16 x i8>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst2.v16i8(i8* %A, <16 x i8> %tmp1, <16 x i8> %tmp1, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.8 {{{d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vst2.8 {{{d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}}}, [r0:64]
ret void
}
@@ -53,7 +53,7 @@ define void @vst2Qi16(i16* %A, <8 x i16>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst2.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.16 {{{d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}}}, [r0, :128]
+; CHECK-NEXT: vst2.16 {{{d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}}}, [r0:128]
ret void
}
@@ -64,7 +64,7 @@ define void @vst2Qi32(i32* %A, <4 x i32>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst2.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 64)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.32 {{{d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}}}, [r0, :256]
+; CHECK-NEXT: vst2.32 {{{d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}}}, [r0:256]
ret void
}
diff --git a/test/NaCl/ARM/neon-vst3-sandboxing.ll b/test/NaCl/ARM/neon-vst3-sandboxing.ll
index 856f728f16..1f6b641039 100644
--- a/test/NaCl/ARM/neon-vst3-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vst3-sandboxing.ll
@@ -5,7 +5,7 @@ define void @vst3i8(i8* %A, <8 x i8>* %B) nounwind {
%tmp1 = load <8 x i8>* %B
call void @llvm.arm.neon.vst3.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 32)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:64]
ret void
}
diff --git a/test/NaCl/ARM/neon-vst4-sandboxing.ll b/test/NaCl/ARM/neon-vst4-sandboxing.ll
index 550de7dd72..e672d6e09d 100644
--- a/test/NaCl/ARM/neon-vst4-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vst4-sandboxing.ll
@@ -5,7 +5,7 @@ define void @vst4i8(i8* %A, <8 x i8>* %B) nounwind {
%tmp1 = load <8 x i8>* %B
call void @llvm.arm.neon.vst4.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :64]
+; CHECK-NEXT: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:64]
ret void
}
@@ -14,7 +14,7 @@ define void @vst4i16(i16* %A, <4 x i16>* %B) nounwind {
%tmp1 = load <4 x i16>* %B
call void @llvm.arm.neon.vst4.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :128]
+; CHECK-NEXT: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:128]
ret void
}
@@ -23,7 +23,7 @@ define void @vst4i32(i32* %A, <2 x i32>* %B) nounwind {
%tmp1 = load <2 x i32>* %B
call void @llvm.arm.neon.vst4.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 32)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0, :256]
+; CHECK-NEXT: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r0:256]
ret void
}
diff --git a/test/NaCl/ARM/neon-vstlane-sandboxing.ll b/test/NaCl/ARM/neon-vstlane-sandboxing.ll
index 769a7c6712..d8a004b6af 100644
--- a/test/NaCl/ARM/neon-vstlane-sandboxing.ll
+++ b/test/NaCl/ARM/neon-vstlane-sandboxing.ll
@@ -15,7 +15,7 @@ define void @vst1lanei16(i16* %A, <4 x i16>* %B) nounwind {
%tmp2 = extractelement <4 x i16> %tmp1, i32 2
store i16 %tmp2, i16* %A, align 8
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst1.16 {d{{[0-9]+}}[2]}, [r0, :16]
+; CHECK-NEXT: vst1.16 {d{{[0-9]+}}[2]}, [r0:16]
ret void
}
@@ -24,7 +24,7 @@ define void @vst1lanei32(i32* %A, <2 x i32>* %B) nounwind {
%tmp2 = extractelement <2 x i32> %tmp1, i32 1
store i32 %tmp2, i32* %A, align 8
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst1.32 {d{{[0-9]+}}[1]}, [r0, :32]
+; CHECK-NEXT: vst1.32 {d{{[0-9]+}}[1]}, [r0:32]
ret void
}
@@ -46,7 +46,7 @@ define void @vst1laneQi16(i16* %A, <8 x i16>* %B) nounwind {
%tmp2 = extractelement <8 x i16> %tmp1, i32 5
store i16 %tmp2, i16* %A, align 8
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst1.16 {d{{[0-9]+}}[1]}, [r0, :16]
+; CHECK-NEXT: vst1.16 {d{{[0-9]+}}[1]}, [r0:16]
ret void
}
@@ -54,7 +54,7 @@ define void @vst2lanei8(i8* %A, <8 x i8>* %B) nounwind {
%tmp1 = load <8 x i8>* %B
call void @llvm.arm.neon.vst2lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 4)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.8 {d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0, :16]
+; CHECK-NEXT: vst2.8 {d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0:16]
ret void
}
@@ -63,7 +63,7 @@ define void @vst2lanei16(i16* %A, <4 x i16>* %B) nounwind {
%tmp1 = load <4 x i16>* %B
call void @llvm.arm.neon.vst2lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.16 {d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0, :32]
+; CHECK-NEXT: vst2.16 {d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0:32]
ret void
}
@@ -94,7 +94,7 @@ define void @vst2laneQi32(i32* %A, <4 x i32>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst2lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst2.32 {d{{[0-9]+}}[0], d{{[0-9]+}}[0]}, [r0, :64]
+; CHECK-NEXT: vst2.32 {d{{[0-9]+}}[0], d{{[0-9]+}}[0]}, [r0:64]
ret void
}
@@ -128,7 +128,7 @@ define void @vst4lanei8(i8* %A, <8 x i8>* %B) nounwind {
%tmp1 = load <8 x i8>* %B
call void @llvm.arm.neon.vst4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst4.8 {d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0, :32]
+; CHECK-NEXT: vst4.8 {d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0:32]
ret void
}
@@ -146,7 +146,7 @@ define void @vst4lanei32(i32* %A, <2 x i32>* %B) nounwind {
%tmp1 = load <2 x i32>* %B
call void @llvm.arm.neon.vst4lane.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst4.32 {d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0, :128]
+; CHECK-NEXT: vst4.32 {d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1], d{{[0-9]+}}[1]}, [r0:128]
ret void
}
@@ -157,7 +157,7 @@ define void @vst4laneQi16(i16* %A, <8 x i16>* %B) nounwind {
; CHECK-NEXT: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
call void @llvm.arm.neon.vst4lane.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 7, i32 16)
; CHECK: bic r0, r0, #3221225472
-; CHECK-NEXT: vst4.16 {d{{[0-9]+}}[3], d{{[0-9]+}}[3], d{{[0-9]+}}[3], d{{[0-9]+}}[3]}, [r0, :64]
+; CHECK-NEXT: vst4.16 {d{{[0-9]+}}[3], d{{[0-9]+}}[3], d{{[0-9]+}}[3], d{{[0-9]+}}[3]}, [r0:64]
ret void
}