Commit 2f6f8605 by Karl Schimpf

Create local config file for subzero reader tests.

Using lit.local.cfg, don't allow reader tests unless dumping of IR is allowed. This was suggested by Jan in: https://codereview.chromium.org/686913005 BUG=None R=jvoung@chromium.org Review URL: https://codereview.chromium.org/735513002
parent 5d2fa0cf
...@@ -161,6 +161,8 @@ void ExtendedType::dump(Ice::Ostream &Stream) const { ...@@ -161,6 +161,8 @@ void ExtendedType::dump(Ice::Ostream &Stream) const {
} }
} }
class BlockParserBaseClass;
// Top-level class to read PNaCl bitcode files, and translate to ICE. // Top-level class to read PNaCl bitcode files, and translate to ICE.
class TopLevelParser : public NaClBitcodeParser { class TopLevelParser : public NaClBitcodeParser {
TopLevelParser(const TopLevelParser &) = delete; TopLevelParser(const TopLevelParser &) = delete;
...@@ -176,7 +178,7 @@ public: ...@@ -176,7 +178,7 @@ public:
Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout), Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
Header(Header), TypeConverter(Mod->getContext()), Header(Header), TypeConverter(Mod->getContext()),
ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0), ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
NumFunctionBlocks(0) { NumFunctionBlocks(0), BlockParser(nullptr) {
Mod->setDataLayout(PNaClDataLayout); Mod->setDataLayout(PNaClDataLayout);
setErrStream(Translator.getContext()->getStrDump()); setErrStream(Translator.getContext()->getStrDump());
} }
...@@ -185,16 +187,16 @@ public: ...@@ -185,16 +187,16 @@ public:
Ice::Translator &getTranslator() { return Translator; } Ice::Translator &getTranslator() { return Translator; }
// Generates error with given Message. Always returns true. void setBlockParser(BlockParserBaseClass *NewBlockParser) {
bool Error(const std::string &Message) override { BlockParser = NewBlockParser;
ErrorStatus = true;
++NumErrors;
NaClBitcodeParser::Error(Message);
if (!AllowErrorRecovery)
report_fatal_error("Unable to continue");
return true;
} }
// Generates error with given Message. Always returns true.
bool Error(const std::string &Message) override;
// Generates error message with respect to the current block parser.
bool BlockError(const std::string &Message);
/// Returns the number of errors found while parsing the bitcode /// Returns the number of errors found while parsing the bitcode
/// file. /// file.
unsigned getNumErrors() const { return NumErrors; } unsigned getNumErrors() const { return NumErrors; }
...@@ -322,7 +324,7 @@ public: ...@@ -322,7 +324,7 @@ public:
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Reference to global not defined: " << ID; StrBuf << "Reference to global not defined: " << ID;
Error(StrBuf.str()); BlockError(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
Name = "??"; Name = "??";
SuppressMangling = false; SuppressMangling = false;
...@@ -432,6 +434,9 @@ private: ...@@ -432,6 +434,9 @@ private:
std::vector<unsigned> DefiningFunctionDeclarationsList; std::vector<unsigned> DefiningFunctionDeclarationsList;
// Error recovery value to use when getFuncSigTypeByID fails. // Error recovery value to use when getFuncSigTypeByID fails.
Ice::FuncSigType UndefinedFuncSigType; Ice::FuncSigType UndefinedFuncSigType;
// The block parser currently being applied. Used for error
// reporting.
BlockParserBaseClass *BlockParser;
bool ParseBlock(unsigned BlockID) override; bool ParseBlock(unsigned BlockID) override;
...@@ -469,6 +474,15 @@ private: ...@@ -469,6 +474,15 @@ private:
Ice::Type convertToIceTypeError(Type *LLVMTy); Ice::Type convertToIceTypeError(Type *LLVMTy);
}; };
bool TopLevelParser::Error(const std::string &Message) {
ErrorStatus = true;
++NumErrors;
NaClBitcodeParser::Error(Message);
if (!AllowErrorRecovery)
report_fatal_error("Unable to continue");
return true;
}
void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
ExtendedType::TypeKind WantedType) { ExtendedType::TypeKind WantedType) {
std::string Buffer; std::string Buffer;
...@@ -478,7 +492,7 @@ void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, ...@@ -478,7 +492,7 @@ void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
} else { } else {
StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
} }
Error(StrBuf.str()); BlockError(StrBuf.str());
} }
Ice::FunctionDeclaration * Ice::FunctionDeclaration *
...@@ -488,7 +502,7 @@ TopLevelParser::reportGetFunctionByIDError(unsigned ID) { ...@@ -488,7 +502,7 @@ TopLevelParser::reportGetFunctionByIDError(unsigned ID) {
StrBuf << "Function index " << ID StrBuf << "Function index " << ID
<< " not allowed. Out of range. Must be less than " << " not allowed. Out of range. Must be less than "
<< FunctionDeclarationList.size(); << FunctionDeclarationList.size();
Error(StrBuf.str()); BlockError(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
if (!FunctionDeclarationList.empty()) if (!FunctionDeclarationList.empty())
return FunctionDeclarationList[0]; return FunctionDeclarationList[0];
...@@ -502,7 +516,7 @@ TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) { ...@@ -502,7 +516,7 @@ TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) {
StrBuf << "Global index " << Index StrBuf << "Global index " << Index
<< " not allowed. Out of range. Must be less than " << " not allowed. Out of range. Must be less than "
<< VariableDeclarations.size(); << VariableDeclarations.size();
Error(StrBuf.str()); BlockError(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
if (!VariableDeclarations.empty()) if (!VariableDeclarations.empty())
return VariableDeclarations[0]; return VariableDeclarations[0];
...@@ -522,12 +536,26 @@ Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { ...@@ -522,12 +536,26 @@ Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
// messages if ParseBlock or ParseRecord is not overridden in derived // messages if ParseBlock or ParseRecord is not overridden in derived
// classes. // classes.
class BlockParserBaseClass : public NaClBitcodeParser { class BlockParserBaseClass : public NaClBitcodeParser {
BlockParserBaseClass(const BlockParserBaseClass &) = delete;
BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
public: public:
// Constructor for the top-level module block parser. // Constructor for the top-level module block parser.
BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
: NaClBitcodeParser(BlockID, Context), Context(Context) {} : NaClBitcodeParser(BlockID, Context), Context(Context) {
Context->setBlockParser(this);
}
~BlockParserBaseClass() override { Context->setBlockParser(nullptr); }
// Returns the printable name of the type of block being parsed.
virtual const char *getBlockName() const {
// If this class is used, it is parsing an unknown block.
return "unknown";
}
~BlockParserBaseClass() override {} // Generates an error Message with the bit address prefixed to it.
bool Error(const std::string &Message) override;
protected: protected:
// The context parser that contains the decoded state. // The context parser that contains the decoded state.
...@@ -548,22 +576,6 @@ protected: ...@@ -548,22 +576,6 @@ protected:
: false; : false;
} }
// Generates an error Message with the bit address prefixed to it.
bool Error(const std::string &Message) override {
uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8;
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "(" << format("%" PRIu64 ":%u", (Bit / 8),
static_cast<unsigned>(Bit % 8)) << ") ";
// Note: If dump routines have been turned off, the error messages
// will not be readable. Hence, replace with simple error.
if (ALLOW_DUMP)
StrBuf << Message;
else
StrBuf << "Invalid input record";
return Context->Error(StrBuf.str());
}
// Default implementation. Reports that block is unknown and skips // Default implementation. Reports that block is unknown and skips
// its contents. // its contents.
bool ParseBlock(unsigned BlockID) override; bool ParseBlock(unsigned BlockID) override;
...@@ -623,12 +635,43 @@ private: ...@@ -623,12 +635,43 @@ private:
const char *ContextMessage); const char *ContextMessage);
}; };
bool TopLevelParser::BlockError(const std::string &Message) {
if (BlockParser)
return BlockParser->Error(Message);
else
return Error(Message);
}
// Generates an error Message with the bit address prefixed to it.
bool BlockParserBaseClass::Error(const std::string &Message) {
uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8;
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "(" << format("%" PRIu64 ":%u", (Bit / 8),
static_cast<unsigned>(Bit % 8)) << ") ";
// Note: If dump routines have been turned off, the error messages
// will not be readable. Hence, replace with simple error.
if (ALLOW_DUMP)
StrBuf << Message;
else {
StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
for (const uint64_t Val : Record.GetValues()) {
StrBuf << " " << Val;
}
StrBuf << ">";
}
return Context->Error(StrBuf.str());
}
void BlockParserBaseClass::ReportRecordSizeError(unsigned ExpectedSize, void BlockParserBaseClass::ReportRecordSizeError(unsigned ExpectedSize,
const char *RecordName, const char *RecordName,
const char *ContextMessage) { const char *ContextMessage) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << RecordName << " record expects"; const char *BlockName = getBlockName();
const char FirstChar = toupper(*BlockName);
StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
<< " record expects";
if (ContextMessage) if (ContextMessage)
StrBuf << " " << ContextMessage; StrBuf << " " << ContextMessage;
StrBuf << " " << ExpectedSize << " argument"; StrBuf << " " << ExpectedSize << " argument";
...@@ -654,7 +697,8 @@ void BlockParserBaseClass::ProcessRecord() { ...@@ -654,7 +697,8 @@ void BlockParserBaseClass::ProcessRecord() {
// If called, derived class doesn't know how to handle. // If called, derived class doesn't know how to handle.
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Don't know how to process record: " << Record; StrBuf << "Don't know how to process " << getBlockName()
<< " record:" << Record;
Error(StrBuf.str()); Error(StrBuf.str());
} }
...@@ -676,6 +720,8 @@ private: ...@@ -676,6 +720,8 @@ private:
void ProcessRecord() override; void ProcessRecord() override;
const char *getBlockName() const override { return "type"; }
void setNextTypeIDAsSimpleType(Ice::Type Ty) { void setNextTypeIDAsSimpleType(Ice::Type Ty) {
Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
} }
...@@ -686,31 +732,31 @@ void TypesParser::ProcessRecord() { ...@@ -686,31 +732,31 @@ void TypesParser::ProcessRecord() {
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::TYPE_CODE_NUMENTRY: case naclbitc::TYPE_CODE_NUMENTRY:
// NUMENTRY: [numentries] // NUMENTRY: [numentries]
if (!isValidRecordSize(1, "Type count")) if (!isValidRecordSize(1, "count"))
return; return;
Context->resizeTypeIDValues(Values[0]); Context->resizeTypeIDValues(Values[0]);
return; return;
case naclbitc::TYPE_CODE_VOID: case naclbitc::TYPE_CODE_VOID:
// VOID // VOID
if (!isValidRecordSize(0, "Type void")) if (!isValidRecordSize(0, "void"))
return; return;
setNextTypeIDAsSimpleType(Ice::IceType_void); setNextTypeIDAsSimpleType(Ice::IceType_void);
return; return;
case naclbitc::TYPE_CODE_FLOAT: case naclbitc::TYPE_CODE_FLOAT:
// FLOAT // FLOAT
if (!isValidRecordSize(0, "Type float")) if (!isValidRecordSize(0, "float"))
return; return;
setNextTypeIDAsSimpleType(Ice::IceType_f32); setNextTypeIDAsSimpleType(Ice::IceType_f32);
return; return;
case naclbitc::TYPE_CODE_DOUBLE: case naclbitc::TYPE_CODE_DOUBLE:
// DOUBLE // DOUBLE
if (!isValidRecordSize(0, "Type double")) if (!isValidRecordSize(0, "double"))
return; return;
setNextTypeIDAsSimpleType(Ice::IceType_f64); setNextTypeIDAsSimpleType(Ice::IceType_f64);
return; return;
case naclbitc::TYPE_CODE_INTEGER: case naclbitc::TYPE_CODE_INTEGER:
// INTEGER: [width] // INTEGER: [width]
if (!isValidRecordSize(1, "Type integer")) if (!isValidRecordSize(1, "integer"))
return; return;
switch (Values[0]) { switch (Values[0]) {
case 1: case 1:
...@@ -740,7 +786,7 @@ void TypesParser::ProcessRecord() { ...@@ -740,7 +786,7 @@ void TypesParser::ProcessRecord() {
return; return;
case naclbitc::TYPE_CODE_VECTOR: { case naclbitc::TYPE_CODE_VECTOR: {
// VECTOR: [numelts, eltty] // VECTOR: [numelts, eltty]
if (!isValidRecordSize(2, "Type vector")) if (!isValidRecordSize(2, "vector"))
return; return;
Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]); Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
Ice::SizeT Size = Values[0]; Ice::SizeT Size = Values[0];
...@@ -798,7 +844,7 @@ void TypesParser::ProcessRecord() { ...@@ -798,7 +844,7 @@ void TypesParser::ProcessRecord() {
} }
case naclbitc::TYPE_CODE_FUNCTION: { case naclbitc::TYPE_CODE_FUNCTION: {
// FUNCTION: [vararg, retty, paramty x N] // FUNCTION: [vararg, retty, paramty x N]
if (!isValidRecordSizeAtLeast(2, "Type signature")) if (!isValidRecordSizeAtLeast(2, "signature"))
return; return;
if (Values[0]) if (Values[0])
Error("Function type can't define varargs"); Error("Function type can't define varargs");
...@@ -844,6 +890,8 @@ public: ...@@ -844,6 +890,8 @@ public:
~GlobalsParser() final {} ~GlobalsParser() final {}
const char *getBlockName() const override { return "globals"; }
private: private:
Ice::TimerMarker Timer; Ice::TimerMarker Timer;
// Keeps track of how many initializers are expected for the global variable // Keeps track of how many initializers are expected for the global variable
...@@ -867,7 +915,7 @@ private: ...@@ -867,7 +915,7 @@ private:
if (NextGlobalID < NumIDs) { if (NextGlobalID < NumIDs) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Globals block expects " << NumIDs StrBuf << getBlockName() << " block expects " << NumIDs
<< " global variable declarations. Found: " << NextGlobalID; << " global variable declarations. Found: " << NextGlobalID;
Error(StrBuf.str()); Error(StrBuf.str());
} }
...@@ -901,7 +949,7 @@ void GlobalsParser::ProcessRecord() { ...@@ -901,7 +949,7 @@ void GlobalsParser::ProcessRecord() {
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::GLOBALVAR_COUNT: case naclbitc::GLOBALVAR_COUNT:
// COUNT: [n] // COUNT: [n]
if (!isValidRecordSize(1, "Globals count")) if (!isValidRecordSize(1, "count"))
return; return;
if (NextGlobalID != Context->getNumGlobalVariables()) { if (NextGlobalID != Context->getNumGlobalVariables()) {
Error("Globals count record not first in block."); Error("Globals count record not first in block.");
...@@ -911,7 +959,7 @@ void GlobalsParser::ProcessRecord() { ...@@ -911,7 +959,7 @@ void GlobalsParser::ProcessRecord() {
return; return;
case naclbitc::GLOBALVAR_VAR: { case naclbitc::GLOBALVAR_VAR: {
// VAR: [align, isconst] // VAR: [align, isconst]
if (!isValidRecordSize(2, "Globals variable")) if (!isValidRecordSize(2, "variable"))
return; return;
verifyNoMissingInitializers(); verifyNoMissingInitializers();
if (!isIRGenerationDisabled()) { if (!isIRGenerationDisabled()) {
...@@ -925,7 +973,7 @@ void GlobalsParser::ProcessRecord() { ...@@ -925,7 +973,7 @@ void GlobalsParser::ProcessRecord() {
} }
case naclbitc::GLOBALVAR_COMPOUND: case naclbitc::GLOBALVAR_COMPOUND:
// COMPOUND: [size] // COMPOUND: [size]
if (!isValidRecordSize(1, "globals compound")) if (!isValidRecordSize(1, "compound"))
return; return;
if (!CurGlobalVar->getInitializers().empty()) { if (!CurGlobalVar->getInitializers().empty()) {
Error("Globals compound record not first initializer"); Error("Globals compound record not first initializer");
...@@ -934,7 +982,8 @@ void GlobalsParser::ProcessRecord() { ...@@ -934,7 +982,8 @@ void GlobalsParser::ProcessRecord() {
if (Values[0] < 2) { if (Values[0] < 2) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Globals compound record size invalid. Found: " << Values[0]; StrBuf << getBlockName()
<< " compound record size invalid. Found: " << Values[0];
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
...@@ -944,7 +993,7 @@ void GlobalsParser::ProcessRecord() { ...@@ -944,7 +993,7 @@ void GlobalsParser::ProcessRecord() {
return; return;
case naclbitc::GLOBALVAR_ZEROFILL: { case naclbitc::GLOBALVAR_ZEROFILL: {
// ZEROFILL: [size] // ZEROFILL: [size]
if (!isValidRecordSize(1, "Globals zerofill")) if (!isValidRecordSize(1, "zerofill"))
return; return;
if (isIRGenerationDisabled()) if (isIRGenerationDisabled())
return; return;
...@@ -954,7 +1003,7 @@ void GlobalsParser::ProcessRecord() { ...@@ -954,7 +1003,7 @@ void GlobalsParser::ProcessRecord() {
} }
case naclbitc::GLOBALVAR_DATA: { case naclbitc::GLOBALVAR_DATA: {
// DATA: [b0, b1, ...] // DATA: [b0, b1, ...]
if (!isValidRecordSizeAtLeast(1, "Globals data")) if (!isValidRecordSizeAtLeast(1, "data"))
return; return;
if (isIRGenerationDisabled()) if (isIRGenerationDisabled())
return; return;
...@@ -964,7 +1013,7 @@ void GlobalsParser::ProcessRecord() { ...@@ -964,7 +1013,7 @@ void GlobalsParser::ProcessRecord() {
} }
case naclbitc::GLOBALVAR_RELOC: { case naclbitc::GLOBALVAR_RELOC: {
// RELOC: [val, [addend]] // RELOC: [val, [addend]]
if (!isValidRecordSizeInRange(1, 2, "Globals reloc")) if (!isValidRecordSizeInRange(1, 2, "reloc"))
return; return;
if (isIRGenerationDisabled()) if (isIRGenerationDisabled())
return; return;
...@@ -993,6 +1042,8 @@ public: ...@@ -993,6 +1042,8 @@ public:
~ValuesymtabParser() override {} ~ValuesymtabParser() override {}
const char *getBlockName() const override { return "valuesymtab"; }
protected: protected:
typedef SmallString<128> StringType; typedef SmallString<128> StringType;
...@@ -1020,7 +1071,7 @@ void ValuesymtabParser::ProcessRecord() { ...@@ -1020,7 +1071,7 @@ void ValuesymtabParser::ProcessRecord() {
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::VST_CODE_ENTRY: { case naclbitc::VST_CODE_ENTRY: {
// VST_ENTRY: [ValueId, namechar x N] // VST_ENTRY: [ValueId, namechar x N]
if (!isValidRecordSizeAtLeast(2, "Valuesymtab value entry")) if (!isValidRecordSizeAtLeast(2, "value entry"))
return; return;
ConvertToString(ConvertedName); ConvertToString(ConvertedName);
setValueName(Values[0], ConvertedName); setValueName(Values[0], ConvertedName);
...@@ -1028,7 +1079,7 @@ void ValuesymtabParser::ProcessRecord() { ...@@ -1028,7 +1079,7 @@ void ValuesymtabParser::ProcessRecord() {
} }
case naclbitc::VST_CODE_BBENTRY: { case naclbitc::VST_CODE_BBENTRY: {
// VST_BBENTRY: [BbId, namechar x N] // VST_BBENTRY: [BbId, namechar x N]
if (!isValidRecordSizeAtLeast(2, "Valuesymtab basic block entry")) if (!isValidRecordSizeAtLeast(2, "basic block entry"))
return; return;
ConvertToString(ConvertedName); ConvertToString(ConvertedName);
setBbName(Values[0], ConvertedName); setBbName(Values[0], ConvertedName);
...@@ -1048,7 +1099,6 @@ class FunctionValuesymtabParser; ...@@ -1048,7 +1099,6 @@ class FunctionValuesymtabParser;
class FunctionParser : public BlockParserBaseClass { class FunctionParser : public BlockParserBaseClass {
FunctionParser(const FunctionParser &) = delete; FunctionParser(const FunctionParser &) = delete;
FunctionParser &operator=(const FunctionParser &) = delete; FunctionParser &operator=(const FunctionParser &) = delete;
friend class FunctionValuesymtabParser;
public: public:
FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
...@@ -1090,6 +1140,16 @@ public: ...@@ -1090,6 +1140,16 @@ public:
~FunctionParser() final {} ~FunctionParser() final {}
const char *getBlockName() const override { return "function"; }
Ice::Cfg *getFunc() const {
return Func;
}
uint32_t getNumGlobalIDs() const {
return CachedNumGlobalValueIDs;
}
void setNextLocalInstIndex(Ice::Operand *Op) { void setNextLocalInstIndex(Ice::Operand *Op) {
setOperand(NextLocalInstIndex++, Op); setOperand(NextLocalInstIndex++, Op);
} }
...@@ -1097,6 +1157,32 @@ public: ...@@ -1097,6 +1157,32 @@ public:
// Set the next constant ID to the given constant C. // Set the next constant ID to the given constant C.
void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
// Returns the value referenced by the given value Index.
Ice::Operand *getOperand(uint32_t Index) {
if (Index < CachedNumGlobalValueIDs) {
return Context->getOrCreateGlobalConstantByID(Index);
}
uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
if (LocalIndex >= LocalOperands.size()) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Value index " << Index << " not defined!";
Error(StrBuf.str());
report_fatal_error("Unable to continue");
}
Ice::Operand *Op = LocalOperands[LocalIndex];
if (Op == nullptr) {
if (isIRGenerationDisabled())
return nullptr;
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Value index " << Index << " not defined!";
Error(StrBuf.str());
report_fatal_error("Unable to continue");
}
return Op;
}
private: private:
Ice::TimerMarker Timer; Ice::TimerMarker Timer;
// The corresponding ICE function defined by the function block. // The corresponding ICE function defined by the function block.
...@@ -1247,32 +1333,6 @@ private: ...@@ -1247,32 +1333,6 @@ private:
return BaseIndex - Id; return BaseIndex - Id;
} }
// Returns the value referenced by the given value Index.
Ice::Operand *getOperand(uint32_t Index) {
if (Index < CachedNumGlobalValueIDs) {
return Context->getOrCreateGlobalConstantByID(Index);
}
uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
if (LocalIndex >= LocalOperands.size()) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Value index " << Index << " not defined!";
Error(StrBuf.str());
report_fatal_error("Unable to continue");
}
Ice::Operand *Op = LocalOperands[LocalIndex];
if (Op == nullptr) {
if (isIRGenerationDisabled())
return nullptr;
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Value index " << Index << " not defined!";
Error(StrBuf.str());
report_fatal_error("Unable to continue");
}
return Op;
}
// Sets element Index (in the local operands list) to Op. // Sets element Index (in the local operands list) to Op.
void setOperand(uint32_t Index, Ice::Operand *Op) { void setOperand(uint32_t Index, Ice::Operand *Op) {
assert(Op || isIRGenerationDisabled()); assert(Op || isIRGenerationDisabled());
...@@ -1761,7 +1821,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1761,7 +1821,7 @@ void FunctionParser::ProcessRecord() {
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::FUNC_CODE_DECLAREBLOCKS: { case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
// DECLAREBLOCKS: [n] // DECLAREBLOCKS: [n]
if (!isValidRecordSize(1, "function block count")) if (!isValidRecordSize(1, "count"))
return; return;
uint32_t NumBbs = Values[0]; uint32_t NumBbs = Values[0];
if (NumBbs == 0) { if (NumBbs == 0) {
...@@ -1783,7 +1843,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1783,7 +1843,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_BINOP: { case naclbitc::FUNC_CODE_INST_BINOP: {
// BINOP: [opval, opval, opcode] // BINOP: [opval, opval, opcode]
if (!isValidRecordSize(3, "function block binop")) if (!isValidRecordSize(3, "binop"))
return; return;
Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
...@@ -1812,7 +1872,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1812,7 +1872,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_CAST: { case naclbitc::FUNC_CODE_INST_CAST: {
// CAST: [opval, destty, castopc] // CAST: [opval, destty, castopc]
if (!isValidRecordSize(3, "function block cast")) if (!isValidRecordSize(3, "cast"))
return; return;
Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
...@@ -1849,7 +1909,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1849,7 +1909,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_VSELECT: { case naclbitc::FUNC_CODE_INST_VSELECT: {
// VSELECT: [opval, opval, pred] // VSELECT: [opval, opval, pred]
if (!isValidRecordSize(3, "function block select")) if (!isValidRecordSize(3, "select"))
return; return;
Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
...@@ -1898,7 +1958,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1898,7 +1958,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_EXTRACTELT: { case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
// EXTRACTELT: [opval, opval] // EXTRACTELT: [opval, opval]
if (!isValidRecordSize(2, "function block extract element")) if (!isValidRecordSize(2, "extract element"))
return; return;
Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
...@@ -1925,7 +1985,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1925,7 +1985,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_INSERTELT: { case naclbitc::FUNC_CODE_INST_INSERTELT: {
// INSERTELT: [opval, opval, opval] // INSERTELT: [opval, opval, opval]
if (!isValidRecordSize(3, "function block insert element")) if (!isValidRecordSize(3, "insert element"))
return; return;
Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
...@@ -1954,7 +2014,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1954,7 +2014,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_CMP2: { case naclbitc::FUNC_CODE_INST_CMP2: {
// CMP2: [opval, opval, pred] // CMP2: [opval, opval, pred]
if (!isValidRecordSize(3, "function block compare")) if (!isValidRecordSize(3, "compare"))
return; return;
Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
...@@ -2020,7 +2080,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2020,7 +2080,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_RET: { case naclbitc::FUNC_CODE_INST_RET: {
// RET: [opval?] // RET: [opval?]
if (!isValidRecordSizeInRange(0, 1, "function block ret")) if (!isValidRecordSizeInRange(0, 1, "return"))
return; return;
if (Values.empty()) { if (Values.empty()) {
if (isIRGenerationDisabled()) if (isIRGenerationDisabled())
...@@ -2048,7 +2108,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2048,7 +2108,7 @@ void FunctionParser::ProcessRecord() {
CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
} else { } else {
// BR: [bb#, bb#, opval] // BR: [bb#, bb#, opval]
if (!isValidRecordSize(3, "function block branch")) if (!isValidRecordSize(3, "branch"))
return; return;
Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
if (isIRGenerationDisabled()) { if (isIRGenerationDisabled()) {
...@@ -2082,7 +2142,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2082,7 +2142,7 @@ void FunctionParser::ProcessRecord() {
// unnecesary data fields (i.e. constants 1). These were not // unnecesary data fields (i.e. constants 1). These were not
// cleaned up in PNaCl bitcode because the bitcode format was // cleaned up in PNaCl bitcode because the bitcode format was
// already frozen when the problem was noticed. // already frozen when the problem was noticed.
if (!isValidRecordSizeAtLeast(4, "function block switch")) if (!isValidRecordSizeAtLeast(4, "switch"))
return; return;
Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
...@@ -2112,7 +2172,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2112,7 +2172,7 @@ void FunctionParser::ProcessRecord() {
unsigned NumCases = Values[3]; unsigned NumCases = Values[3];
// Now recognize each of the cases. // Now recognize each of the cases.
if (!isValidRecordSize(4 + NumCases * 4, "Function block switch")) if (!isValidRecordSize(4 + NumCases * 4, "switch"))
return; return;
Ice::InstSwitch *Switch = Ice::InstSwitch *Switch =
isIRGenDisabled ? nullptr : Ice::InstSwitch::create(Func, NumCases, isIRGenDisabled ? nullptr : Ice::InstSwitch::create(Func, NumCases,
...@@ -2144,7 +2204,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2144,7 +2204,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_UNREACHABLE: { case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
// UNREACHABLE: [] // UNREACHABLE: []
if (!isValidRecordSize(0, "function block unreachable")) if (!isValidRecordSize(0, "unreachable"))
return; return;
if (isIRGenerationDisabled()) if (isIRGenerationDisabled())
return; return;
...@@ -2155,7 +2215,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2155,7 +2215,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_PHI: { case naclbitc::FUNC_CODE_INST_PHI: {
// PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
if (!isValidRecordSizeAtLeast(3, "function block phi")) if (!isValidRecordSizeAtLeast(3, "phi"))
return; return;
Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
if ((Values.size() & 0x1) == 0) { if ((Values.size() & 0x1) == 0) {
...@@ -2201,7 +2261,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2201,7 +2261,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_ALLOCA: { case naclbitc::FUNC_CODE_INST_ALLOCA: {
// ALLOCA: [Size, align] // ALLOCA: [Size, align]
if (!isValidRecordSize(2, "function block alloca")) if (!isValidRecordSize(2, "alloca"))
return; return;
Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
unsigned Alignment; unsigned Alignment;
...@@ -2226,7 +2286,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2226,7 +2286,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_LOAD: { case naclbitc::FUNC_CODE_INST_LOAD: {
// LOAD: [address, align, ty] // LOAD: [address, align, ty]
if (!isValidRecordSize(3, "function block load")) if (!isValidRecordSize(3, "load"))
return; return;
Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
...@@ -2251,7 +2311,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2251,7 +2311,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_STORE: { case naclbitc::FUNC_CODE_INST_STORE: {
// STORE: [address, value, align] // STORE: [address, value, align]
if (!isValidRecordSize(3, "function block store")) if (!isValidRecordSize(3, "store"))
return; return;
Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
...@@ -2283,10 +2343,10 @@ void FunctionParser::ProcessRecord() { ...@@ -2283,10 +2343,10 @@ void FunctionParser::ProcessRecord() {
// corresponding return type stored in CALL_INDIRECT record. // corresponding return type stored in CALL_INDIRECT record.
Ice::SizeT ParamsStartIndex = 2; Ice::SizeT ParamsStartIndex = 2;
if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
if (!isValidRecordSizeAtLeast(2, "function block call")) if (!isValidRecordSizeAtLeast(2, "call"))
return; return;
} else { } else {
if (!isValidRecordSizeAtLeast(3, "function block call indirect")) if (!isValidRecordSizeAtLeast(3, "call indirect"))
return; return;
ParamsStartIndex = 3; ParamsStartIndex = 3;
} }
...@@ -2415,7 +2475,7 @@ void FunctionParser::ProcessRecord() { ...@@ -2415,7 +2475,7 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
// FORWARDTYPEREF: [opval, ty] // FORWARDTYPEREF: [opval, ty]
if (!isValidRecordSize(2, "function block forward type ref")) if (!isValidRecordSize(2, "forward type ref"))
return; return;
Ice::Type OpType = Context->getSimpleTypeByID(Values[1]); Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
setOperand(Values[0], setOperand(Values[0],
...@@ -2442,6 +2502,8 @@ public: ...@@ -2442,6 +2502,8 @@ public:
~ConstantsParser() override {} ~ConstantsParser() override {}
const char *getBlockName() const override { return "constants"; }
private: private:
Ice::TimerMarker Timer; Ice::TimerMarker Timer;
// The parser of the function block this constants block appears in. // The parser of the function block this constants block appears in.
...@@ -2468,7 +2530,7 @@ void ConstantsParser::ProcessRecord() { ...@@ -2468,7 +2530,7 @@ void ConstantsParser::ProcessRecord() {
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::CST_CODE_SETTYPE: { case naclbitc::CST_CODE_SETTYPE: {
// SETTYPE: [typeid] // SETTYPE: [typeid]
if (!isValidRecordSize(1, "constants block set type")) if (!isValidRecordSize(1, "set type"))
return; return;
NextConstantType = Context->getSimpleTypeByID(Values[0]); NextConstantType = Context->getSimpleTypeByID(Values[0]);
if (NextConstantType == Ice::IceType_void) if (NextConstantType == Ice::IceType_void)
...@@ -2477,7 +2539,7 @@ void ConstantsParser::ProcessRecord() { ...@@ -2477,7 +2539,7 @@ void ConstantsParser::ProcessRecord() {
} }
case naclbitc::CST_CODE_UNDEF: { case naclbitc::CST_CODE_UNDEF: {
// UNDEF // UNDEF
if (!isValidRecordSize(0, "constants block undef")) if (!isValidRecordSize(0, "undef"))
return; return;
if (!isValidNextConstantType()) if (!isValidNextConstantType())
return; return;
...@@ -2491,7 +2553,7 @@ void ConstantsParser::ProcessRecord() { ...@@ -2491,7 +2553,7 @@ void ConstantsParser::ProcessRecord() {
} }
case naclbitc::CST_CODE_INTEGER: { case naclbitc::CST_CODE_INTEGER: {
// INTEGER: [intval] // INTEGER: [intval]
if (!isValidRecordSize(1, "constants block integer")) if (!isValidRecordSize(1, "integer"))
return; return;
if (!isValidNextConstantType()) if (!isValidNextConstantType())
return; return;
...@@ -2517,7 +2579,7 @@ void ConstantsParser::ProcessRecord() { ...@@ -2517,7 +2579,7 @@ void ConstantsParser::ProcessRecord() {
} }
case naclbitc::CST_CODE_FLOAT: { case naclbitc::CST_CODE_FLOAT: {
// FLOAT: [fpval] // FLOAT: [fpval]
if (!isValidRecordSize(1, "constants block float")) if (!isValidRecordSize(1, "float"))
return; return;
if (!isValidNextConstantType()) if (!isValidNextConstantType())
return; return;
...@@ -2592,7 +2654,7 @@ private: ...@@ -2592,7 +2654,7 @@ private:
void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
// Note: We check when Index is too small, so that we can error recover // Note: We check when Index is too small, so that we can error recover
// (FP->getOperand will create fatal error). // (FP->getOperand will create fatal error).
if (Index < getFunctionParser()->CachedNumGlobalValueIDs) { if (Index < getFunctionParser()->getNumGlobalIDs()) {
reportUnableToAssign("instruction", Index, Name); reportUnableToAssign("instruction", Index, Name);
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
return; return;
...@@ -2611,12 +2673,12 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { ...@@ -2611,12 +2673,12 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) {
if (isIRGenerationDisabled()) if (isIRGenerationDisabled())
return; return;
if (Index >= getFunctionParser()->Func->getNumNodes()) { if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
reportUnableToAssign("block", Index, Name); reportUnableToAssign("block", Index, Name);
return; return;
} }
std::string Nm(Name.data(), Name.size()); std::string Nm(Name.data(), Name.size());
getFunctionParser()->Func->getNodes()[Index]->setName(Nm); getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
} }
bool FunctionParser::ParseBlock(unsigned BlockID) { bool FunctionParser::ParseBlock(unsigned BlockID) {
...@@ -2649,6 +2711,8 @@ public: ...@@ -2649,6 +2711,8 @@ public:
~ModuleParser() override {} ~ModuleParser() override {}
const char *getBlockName() const override { return "module"; }
private: private:
Ice::TimerMarker Timer; Ice::TimerMarker Timer;
// True if we have already installed names for unnamed global declarations, // True if we have already installed names for unnamed global declarations,
...@@ -2768,7 +2832,7 @@ void ModuleParser::ProcessRecord() { ...@@ -2768,7 +2832,7 @@ void ModuleParser::ProcessRecord() {
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::MODULE_CODE_VERSION: { case naclbitc::MODULE_CODE_VERSION: {
// VERSION: [version#] // VERSION: [version#]
if (!isValidRecordSize(1, "Module version")) if (!isValidRecordSize(1, "version"))
return; return;
unsigned Version = Values[0]; unsigned Version = Values[0];
if (Version != 1) { if (Version != 1) {
...@@ -2781,14 +2845,14 @@ void ModuleParser::ProcessRecord() { ...@@ -2781,14 +2845,14 @@ void ModuleParser::ProcessRecord() {
} }
case naclbitc::MODULE_CODE_FUNCTION: { case naclbitc::MODULE_CODE_FUNCTION: {
// FUNCTION: [type, callingconv, isproto, linkage] // FUNCTION: [type, callingconv, isproto, linkage]
if (!isValidRecordSize(4, "Function heading")) if (!isValidRecordSize(4, "address"))
return; return;
const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]); const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
CallingConv::ID CallingConv; CallingConv::ID CallingConv;
if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Function heading has unknown calling convention: " StrBuf << "Function address has unknown calling convention: "
<< Values[1]; << Values[1];
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
...@@ -2797,7 +2861,7 @@ void ModuleParser::ProcessRecord() { ...@@ -2797,7 +2861,7 @@ void ModuleParser::ProcessRecord() {
if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Function heading has unknown linkage. Found " << Values[3]; StrBuf << "Function address has unknown linkage. Found " << Values[3];
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
......
; Tests insertelement and extractelement vector instructions report ; Tests malformed insertelement and extractelement vector instructions.
; errors when malformed. Note: We can only test literal indexing since
; llvm-as will not allow other bad forms of these instructions.
; REQUIRES: allow_dump ; RUN: %if --need=allow_dump --command llvm-as < %s \
; RUN: llvm-as < %s | pnacl-freeze \ ; RUN: | %if --need=allow_dump --command pnacl-freeze \
; RUN: | not %llvm2ice -notranslate -build-on-read \ ; RUN: | %if --need=allow_dump --command not %llvm2ice -notranslate \
; RUN: -allow-pnacl-reader-error-recovery | FileCheck %s ; RUN: -build-on-read -allow-pnacl-reader-error-recovery \
; RUN: | %if --need=allow_dump --command FileCheck %s
; RUN: %if --need=no_dump --command llvm-as < %s \
; RUN: | %if --need=no_dump --command pnacl-freeze \
; RUN: | %if --need=no_dump --command not %llvm2ice -notranslate \
; RUN: -build-on-read -allow-pnacl-reader-error-recovery \
; RUN: | %if --need=no_dump --command FileCheck %s --check-prefix=MIN
define void @ExtractV4xi1(<4 x i1> %v, i32 %i) { define void @ExtractV4xi1(<4 x i1> %v, i32 %i) {
%e0 = extractelement <4 x i1> %v, i32 %i %e0 = extractelement <4 x i1> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 4 3>
%e1 = extractelement <4 x i1> %v, i32 4 %e1 = extractelement <4 x i1> %v, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
%e2 = extractelement <4 x i1> %v, i32 9 %e2 = extractelement <4 x i1> %v, i32 9
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 6 3>
ret void ret void
} }
define void @ExtractV8xi1(<8 x i1> %v, i32 %i) { define void @ExtractV8xi1(<8 x i1> %v, i32 %i) {
%e0 = extractelement <8 x i1> %v, i32 %i %e0 = extractelement <8 x i1> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 4 3>
%e1 = extractelement <8 x i1> %v, i32 8; %e1 = extractelement <8 x i1> %v, i32 8;
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
%e2 = extractelement <8 x i1> %v, i32 9; %e2 = extractelement <8 x i1> %v, i32 9;
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 6 3>
ret void ret void
} }
define void @ExtractV16xi1(<16 x i1> %v, i32 %i) { define void @ExtractV16xi1(<16 x i1> %v, i32 %i) {
%e0 = extractelement <16 x i1> %v, i32 %i %e0 = extractelement <16 x i1> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 4 3>
%e1 = extractelement <16 x i1> %v, i32 16 %e1 = extractelement <16 x i1> %v, i32 16
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
%e2 = extractelement <16 x i1> %v, i32 24 %e2 = extractelement <16 x i1> %v, i32 24
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 6 3>
ret void ret void
} }
define void @ExtractV16xi8(<16 x i8> %v, i32 %i) { define void @ExtractV16xi8(<16 x i8> %v, i32 %i) {
%e0 = extractelement <16 x i8> %v, i32 %i %e0 = extractelement <16 x i8> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 4 3>
%e1 = extractelement <16 x i8> %v, i32 16 %e1 = extractelement <16 x i8> %v, i32 16
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
%e2 = extractelement <16 x i8> %v, i32 71 %e2 = extractelement <16 x i8> %v, i32 71
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 6 3>
ret void ret void
} }
define void @ExtractV8xi16(<8 x i16> %v, i32 %i) { define void @ExtractV8xi16(<8 x i16> %v, i32 %i) {
%e0 = extractelement <8 x i16> %v, i32 %i %e0 = extractelement <8 x i16> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 4 3>
%e1 = extractelement <8 x i16> %v, i32 8 %e1 = extractelement <8 x i16> %v, i32 8
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
%e2 = extractelement <8 x i16> %v, i32 15 %e2 = extractelement <8 x i16> %v, i32 15
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 6 3>
ret void ret void
} }
define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) { define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) {
%e0 = extractelement <4 x i32> %v, i32 %i %e0 = extractelement <4 x i32> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 4 3>
%e1 = extractelement <4 x i32> %v, i32 4 %e1 = extractelement <4 x i32> %v, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
%e2 = extractelement <4 x i32> %v, i32 17 %e2 = extractelement <4 x i32> %v, i32 17
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 6 3>
ret i32 %e0 ret i32 %e0
} }
define float @ExtractV4xfloat(<4 x float> %v, i32 %i) { define float @ExtractV4xfloat(<4 x float> %v, i32 %i) {
%e0 = extractelement <4 x float> %v, i32 %i %e0 = extractelement <4 x float> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <6 3 2>
%e1 = extractelement <4 x float> %v, i32 4 %e1 = extractelement <4 x float> %v, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 4 2>
%e2 = extractelement <4 x float> %v, i32 4 %e2 = extractelement <4 x float> %v, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <6 5 3>
ret float %e2 ret float %e2
} }
define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %i) { define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %i) {
%r0 = insertelement <4 x i1> %v, i1 1, i32 %i %r0 = insertelement <4 x i1> %v, i1 1, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
%r1 = insertelement <4 x i1> %v, i1 1, i32 4 %r1 = insertelement <4 x i1> %v, i1 1, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
%r2 = insertelement <4 x i1> %v, i1 1, i32 7 %r2 = insertelement <4 x i1> %v, i1 1, i32 7
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
ret <4 x i1> %r2 ret <4 x i1> %r2
} }
define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %i) { define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %i) {
%r0 = insertelement <8 x i1> %v, i1 0, i32 %i %r0 = insertelement <8 x i1> %v, i1 0, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
%r1 = insertelement <8 x i1> %v, i1 0, i32 8 %r1 = insertelement <8 x i1> %v, i1 0, i32 8
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
%r2 = insertelement <8 x i1> %v, i1 0, i32 88 %r2 = insertelement <8 x i1> %v, i1 0, i32 88
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
ret <8 x i1> %r2 ret <8 x i1> %r2
} }
define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %i) { define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %i) {
%r = insertelement <16 x i1> %v, i1 1, i32 %i %r = insertelement <16 x i1> %v, i1 1, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
ret <16 x i1> %r ret <16 x i1> %r
%r1 = insertelement <16 x i1> %v, i1 1, i32 16 %r1 = insertelement <16 x i1> %v, i1 1, i32 16
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
%r2 = insertelement <16 x i1> %v, i1 1, i32 31 %r2 = insertelement <16 x i1> %v, i1 1, i32 31
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
ret <16 x i1> %r2 ret <16 x i1> %r2
} }
define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %i) { define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %i) {
%r0 = insertelement <16 x i8> %v, i8 34, i32 %i %r0 = insertelement <16 x i8> %v, i8 34, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
%r1 = insertelement <16 x i8> %v, i8 34, i32 16 %r1 = insertelement <16 x i8> %v, i8 34, i32 16
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
%r2 = insertelement <16 x i8> %v, i8 34, i32 19 %r2 = insertelement <16 x i8> %v, i8 34, i32 19
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
ret <16 x i8> %r0 ret <16 x i8> %r0
} }
define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %i) { define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %i) {
%r0 = insertelement <8 x i16> %v, i16 289, i32 %i %r0 = insertelement <8 x i16> %v, i16 289, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
%r1 = insertelement <8 x i16> %v, i16 289, i32 8 %r1 = insertelement <8 x i16> %v, i16 289, i32 8
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
%r2 = insertelement <8 x i16> %v, i16 289, i32 19 %r2 = insertelement <8 x i16> %v, i16 289, i32 19
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
ret <8 x i16> %r1 ret <8 x i16> %r1
} }
define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %i) { define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %i) {
%r0 = insertelement <4 x i32> %v, i32 54545454, i32 %i %r0 = insertelement <4 x i32> %v, i32 54545454, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 3 4>
%r1 = insertelement <4 x i32> %v, i32 54545454, i32 4 %r1 = insertelement <4 x i32> %v, i32 54545454, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 4 3>
%r2 = insertelement <4 x i32> %v, i32 54545454, i32 9 %r2 = insertelement <4 x i32> %v, i32 54545454, i32 9
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 5 3>
ret <4 x i32> %r2 ret <4 x i32> %r2
} }
define <4 x float> @InsertV4xfloat(<4 x float> %v, i32 %i) { define <4 x float> @InsertV4xfloat(<4 x float> %v, i32 %i) {
%r0 = insertelement <4 x float> %v, float 3.0, i32 %i %r0 = insertelement <4 x float> %v, float 3.0, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant ; CHECK: Error: {{.*}} not {{.*}} constant
; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
%r1 = insertelement <4 x float> %v, float 3.0, i32 4 %r1 = insertelement <4 x float> %v, float 3.0, i32 4
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
%r2 = insertelement <4 x float> %v, float 3.0, i32 44 %r2 = insertelement <4 x float> %v, float 3.0, i32 44
; CHECK: Error: {{.*}} not in range ; CHECK: Error: {{.*}} not in range
; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
ret <4 x float> %r2 ret <4 x float> %r2
} }
; Tests that we don't get fooled by a fake NaCl intrinsic.
; TODO(kschimpf) Find way to run this through p2i. Note: Can't do this
; currently because run-llvm2ice.py raises exception on error,
; and output is lost.
; RUN: %if --need=allow_dump --command llvm-as < %s \
; RUN: | %if --need=allow_dump --command pnacl-freeze \
; RUN -allow-local-symbol-tables \
; RUN: | %if --need=allow_dump --command not %llvm2ice -notranslate \
; RUN: -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: -allow-local-symbol-tables \
; RUN: | %if --need=allow_dump --command FileCheck %s
; RUN: %if --need=no_dump --command llvm-as < %s \
; RUN: | %if --need=no_dump --command pnacl-freeze \
; RUN -allow-local-symbol-tables \
; RUN: | %if --need=no_dump --command not %llvm2ice -notranslate \
; RUN: -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: -allow-local-symbol-tables \
; RUN: | %if --need=no_dump --command FileCheck %s --check-prefix=MIN
declare i32 @llvm.fake.i32(i32)
define i32 @testFake(i32 %v) {
%r = call i32 @llvm.fake.i32(i32 %v)
ret i32 %r
}
; CHECK: Error: ({{.*}}) Invalid PNaCl intrinsic call to llvm.fake.i32
; MIN: Error: ({{.*}}) Invalid function record: <34 0 3 1>
; Test if we can read alloca instructions. ; Test if we can read alloca instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Tests if we can read binary operators. ; Tests if we can read binary operators.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %l2i -i %s --insts | %ifl FileCheck %s ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
; RUN: %lc2i -i %s --insts | %iflc FileCheck %s ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
......
; Tests if we handle a branch instructions. ; Tests if we handle a branch instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test parsing indirect calls in Subzero. ; Test parsing indirect calls in Subzero.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test handling of call instructions. ; Test handling of call instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Tests if we can read cast operations. ; Tests if we can read cast operations.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts --no-local-syms | FileCheck %s ; RUN: %p2i -i %s --insts --no-local-syms | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test if we can read compare instructions. ; Test if we can read compare instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test handling of constants in function blocks. ; Test handling of constants in function blocks.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test use forward type references in function blocks. ; Test use forward type references in function blocks.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: llvm-as < %s | pnacl-freeze | pnacl-bcdis -no-records \ ; RUN: llvm-as < %s | pnacl-freeze | pnacl-bcdis -no-records \
; RUN: | FileCheck --check-prefix=DUMP %s ; RUN: | FileCheck --check-prefix=DUMP %s
......
; Test of global initializers. ; Test of global initializers.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %l2i -i %s --insts | %ifl FileCheck %s ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
; RUN: %lc2i -i %s --insts | %iflc FileCheck %s ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
......
; Tests if we handle global variables with relocation initializers. ; Tests if we handle global variables with relocation initializers.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %l2i -i %s --insts | %ifl FileCheck %s ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
; RUN: %lc2i -i %s --insts | %iflc FileCheck %s ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
......
; Tests insertelement and extractelement vector instructions. ; Tests insertelement and extractelement vector instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %l2i -i %s --insts | %ifl FileCheck %s ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
; RUN: %lc2i -i %s --insts | %iflc FileCheck %s ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
......
# -*- Python -*-
#
# This directory contains reader tests that require the ability to dump parsed
# IR.
if not 'allow_dump' in config.root.available_features:
config.unsupported = True
; Test if we can read load instructions. ; Test if we can read load instructions.
; REQUIRES: allow_dump
; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s ; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test parsing NaCl atomic instructions. ; Test parsing NaCl atomic instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Tests that we don't get fooled by a fake NaCl intrinsic.
; TODO(kschimpf) Find way to run this through p2i. Note: Can't do this
; currently because run-llvm2ice.py raises exception on error,
; and output is lost.
; RUN: %if --need=allow_dump --command \
; RUN: llvm-as < %s \
; RUN: | %if --need=allow_dump --command \
; RUN: pnacl-freeze -allow-local-symbol-tables \
; RUN: | %if --need=allow_dump --command \
; RUN: not %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: -allow-local-symbol-tables \
; RUN: | %if --need=allow_dump --command \
; RUN: FileCheck %s
; RUN: %if --need=no_dump --command \
; RUN: llvm-as < %s \
; RUN: | %if --need=no_dump --command \
; RUN: pnacl-freeze -allow-local-symbol-tables \
; RUN: | %if --need=no_dump --command \
; RUN: not %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery -allow-local-symbol-tables \
; RUN: | %if --need=no_dump --command \
; RUN: FileCheck --check-prefix=MIN %s
declare i32 @llvm.fake.i32(i32)
define i32 @testFake(i32 %v) {
%r = call i32 @llvm.fake.i32(i32 %v)
ret i32 %r
}
; CHECK: Error: ({{.*}}) Invalid PNaCl intrinsic call to llvm.fake.i32
; MIN: Error: ({{.*}}) Invalid input record
; This tests parsing NaCl intrinsics not related to atomic operations. ; This tests parsing NaCl intrinsics not related to atomic operations.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test reading phi instructions. ; Test reading phi instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Tests if we can read select instructions. ; Tests if we can read select instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test if we can read store instructions. ; Test if we can read store instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts --no-local-syms | FileCheck %s ; RUN: %p2i -i %s --insts --no-local-syms | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Test switch instructions. ; Test switch instructions.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
; Tests that we name unnamed global addresses. ; Tests that we name unnamed global addresses.
; REQUIRES: allow_dump
; Check that Subzero's bitcode reader handles renaming correctly. ; Check that Subzero's bitcode reader handles renaming correctly.
; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s ; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s
; RUN: %l2i --no-local-syms -i %s --insts | %ifl FileCheck %s ; RUN: %l2i --no-local-syms -i %s --insts | %ifl FileCheck %s
......
; Test parsing unreachable instruction. ; Test parsing unreachable instruction.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --insts | FileCheck %s ; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %if --need=allow_disable_ir_gen --command \ ; RUN: %if --need=allow_disable_ir_gen --command \
; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \ ; RUN: %p2i -i %s --args -notranslate -timing -no-ir-gen \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment