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
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index 9c1b65fd..3f14ae0 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -161,6 +161,8 @@
   }
 }
 
+class BlockParserBaseClass;
+
 // Top-level class to read PNaCl bitcode files, and translate to ICE.
 class TopLevelParser : public NaClBitcodeParser {
   TopLevelParser(const TopLevelParser &) = delete;
@@ -176,7 +178,7 @@
         Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
         Header(Header), TypeConverter(Mod->getContext()),
         ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
-        NumFunctionBlocks(0) {
+        NumFunctionBlocks(0), BlockParser(nullptr) {
     Mod->setDataLayout(PNaClDataLayout);
     setErrStream(Translator.getContext()->getStrDump());
   }
@@ -185,16 +187,16 @@
 
   Ice::Translator &getTranslator() { return Translator; }
 
-  // Generates error with given Message. Always returns true.
-  bool Error(const std::string &Message) override {
-    ErrorStatus = true;
-    ++NumErrors;
-    NaClBitcodeParser::Error(Message);
-    if (!AllowErrorRecovery)
-      report_fatal_error("Unable to continue");
-    return true;
+  void setBlockParser(BlockParserBaseClass *NewBlockParser) {
+    BlockParser = NewBlockParser;
   }
 
+  // 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
   /// file.
   unsigned getNumErrors() const { return NumErrors; }
@@ -322,7 +324,7 @@
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
       StrBuf << "Reference to global not defined: " << ID;
-      Error(StrBuf.str());
+      BlockError(StrBuf.str());
       // TODO(kschimpf) Remove error recovery once implementation complete.
       Name = "??";
       SuppressMangling = false;
@@ -432,6 +434,9 @@
   std::vector<unsigned> DefiningFunctionDeclarationsList;
   // Error recovery value to use when getFuncSigTypeByID fails.
   Ice::FuncSigType UndefinedFuncSigType;
+  // The block parser currently being applied. Used for error
+  // reporting.
+  BlockParserBaseClass *BlockParser;
 
   bool ParseBlock(unsigned BlockID) override;
 
@@ -469,6 +474,15 @@
   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,
                                        ExtendedType::TypeKind WantedType) {
   std::string Buffer;
@@ -478,7 +492,7 @@
   } else {
     StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
   }
-  Error(StrBuf.str());
+  BlockError(StrBuf.str());
 }
 
 Ice::FunctionDeclaration *
@@ -488,7 +502,7 @@
   StrBuf << "Function index " << ID
          << " not allowed. Out of range. Must be less than "
          << FunctionDeclarationList.size();
-  Error(StrBuf.str());
+  BlockError(StrBuf.str());
   // TODO(kschimpf) Remove error recovery once implementation complete.
   if (!FunctionDeclarationList.empty())
     return FunctionDeclarationList[0];
@@ -502,7 +516,7 @@
   StrBuf << "Global index " << Index
          << " not allowed. Out of range. Must be less than "
          << VariableDeclarations.size();
-  Error(StrBuf.str());
+  BlockError(StrBuf.str());
   // TODO(kschimpf) Remove error recovery once implementation complete.
   if (!VariableDeclarations.empty())
     return VariableDeclarations[0];
@@ -522,12 +536,26 @@
 // messages if ParseBlock or ParseRecord is not overridden in derived
 // classes.
 class BlockParserBaseClass : public NaClBitcodeParser {
+  BlockParserBaseClass(const BlockParserBaseClass &) = delete;
+  BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
+
 public:
   // Constructor for the top-level module block parser.
   BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
-      : NaClBitcodeParser(BlockID, Context), Context(Context) {}
+      : NaClBitcodeParser(BlockID, Context), Context(Context) {
+    Context->setBlockParser(this);
+  }
 
-  ~BlockParserBaseClass() override {}
+  ~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";
+  }
+
+  // Generates an error Message with the bit address prefixed to it.
+  bool Error(const std::string &Message) override;
 
 protected:
   // The context parser that contains the decoded state.
@@ -548,22 +576,6 @@
                                 : 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
   // its contents.
   bool ParseBlock(unsigned BlockID) override;
@@ -623,12 +635,43 @@
                              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,
                                                  const char *RecordName,
                                                  const char *ContextMessage) {
   std::string 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)
     StrBuf << " " << ContextMessage;
   StrBuf << " " << ExpectedSize << " argument";
@@ -654,7 +697,8 @@
   // If called, derived class doesn't know how to handle.
   std::string 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());
 }
 
@@ -676,6 +720,8 @@
 
   void ProcessRecord() override;
 
+  const char *getBlockName() const override { return "type"; }
+
   void setNextTypeIDAsSimpleType(Ice::Type Ty) {
     Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
   }
@@ -686,31 +732,31 @@
   switch (Record.GetCode()) {
   case naclbitc::TYPE_CODE_NUMENTRY:
     // NUMENTRY: [numentries]
-    if (!isValidRecordSize(1, "Type count"))
+    if (!isValidRecordSize(1, "count"))
       return;
     Context->resizeTypeIDValues(Values[0]);
     return;
   case naclbitc::TYPE_CODE_VOID:
     // VOID
-    if (!isValidRecordSize(0, "Type void"))
+    if (!isValidRecordSize(0, "void"))
       return;
     setNextTypeIDAsSimpleType(Ice::IceType_void);
     return;
   case naclbitc::TYPE_CODE_FLOAT:
     // FLOAT
-    if (!isValidRecordSize(0, "Type float"))
+    if (!isValidRecordSize(0, "float"))
       return;
     setNextTypeIDAsSimpleType(Ice::IceType_f32);
     return;
   case naclbitc::TYPE_CODE_DOUBLE:
     // DOUBLE
-    if (!isValidRecordSize(0, "Type double"))
+    if (!isValidRecordSize(0, "double"))
       return;
     setNextTypeIDAsSimpleType(Ice::IceType_f64);
     return;
   case naclbitc::TYPE_CODE_INTEGER:
     // INTEGER: [width]
-    if (!isValidRecordSize(1, "Type integer"))
+    if (!isValidRecordSize(1, "integer"))
       return;
     switch (Values[0]) {
     case 1:
@@ -740,7 +786,7 @@
     return;
   case naclbitc::TYPE_CODE_VECTOR: {
     // VECTOR: [numelts, eltty]
-    if (!isValidRecordSize(2, "Type vector"))
+    if (!isValidRecordSize(2, "vector"))
       return;
     Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
     Ice::SizeT Size = Values[0];
@@ -798,7 +844,7 @@
   }
   case naclbitc::TYPE_CODE_FUNCTION: {
     // FUNCTION: [vararg, retty, paramty x N]
-    if (!isValidRecordSizeAtLeast(2, "Type signature"))
+    if (!isValidRecordSizeAtLeast(2, "signature"))
       return;
     if (Values[0])
       Error("Function type can't define varargs");
@@ -844,6 +890,8 @@
 
   ~GlobalsParser() final {}
 
+  const char *getBlockName() const override { return "globals"; }
+
 private:
   Ice::TimerMarker Timer;
   // Keeps track of how many initializers are expected for the global variable
@@ -867,7 +915,7 @@
     if (NextGlobalID < NumIDs) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Globals block expects " << NumIDs
+      StrBuf << getBlockName() << " block expects " << NumIDs
              << " global variable declarations. Found: " << NextGlobalID;
       Error(StrBuf.str());
     }
@@ -901,7 +949,7 @@
   switch (Record.GetCode()) {
   case naclbitc::GLOBALVAR_COUNT:
     // COUNT: [n]
-    if (!isValidRecordSize(1, "Globals count"))
+    if (!isValidRecordSize(1, "count"))
       return;
     if (NextGlobalID != Context->getNumGlobalVariables()) {
       Error("Globals count record not first in block.");
@@ -911,7 +959,7 @@
     return;
   case naclbitc::GLOBALVAR_VAR: {
     // VAR: [align, isconst]
-    if (!isValidRecordSize(2, "Globals variable"))
+    if (!isValidRecordSize(2, "variable"))
       return;
     verifyNoMissingInitializers();
     if (!isIRGenerationDisabled()) {
@@ -925,7 +973,7 @@
   }
   case naclbitc::GLOBALVAR_COMPOUND:
     // COMPOUND: [size]
-    if (!isValidRecordSize(1, "globals compound"))
+    if (!isValidRecordSize(1, "compound"))
       return;
     if (!CurGlobalVar->getInitializers().empty()) {
       Error("Globals compound record not first initializer");
@@ -934,7 +982,8 @@
     if (Values[0] < 2) {
       std::string 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());
       return;
     }
@@ -944,7 +993,7 @@
     return;
   case naclbitc::GLOBALVAR_ZEROFILL: {
     // ZEROFILL: [size]
-    if (!isValidRecordSize(1, "Globals zerofill"))
+    if (!isValidRecordSize(1, "zerofill"))
       return;
     if (isIRGenerationDisabled())
       return;
@@ -954,7 +1003,7 @@
   }
   case naclbitc::GLOBALVAR_DATA: {
     // DATA: [b0, b1, ...]
-    if (!isValidRecordSizeAtLeast(1, "Globals data"))
+    if (!isValidRecordSizeAtLeast(1, "data"))
       return;
     if (isIRGenerationDisabled())
       return;
@@ -964,7 +1013,7 @@
   }
   case naclbitc::GLOBALVAR_RELOC: {
     // RELOC: [val, [addend]]
-    if (!isValidRecordSizeInRange(1, 2, "Globals reloc"))
+    if (!isValidRecordSizeInRange(1, 2, "reloc"))
       return;
     if (isIRGenerationDisabled())
       return;
@@ -993,6 +1042,8 @@
 
   ~ValuesymtabParser() override {}
 
+  const char *getBlockName() const override { return "valuesymtab"; }
+
 protected:
   typedef SmallString<128> StringType;
 
@@ -1020,7 +1071,7 @@
   switch (Record.GetCode()) {
   case naclbitc::VST_CODE_ENTRY: {
     // VST_ENTRY: [ValueId, namechar x N]
-    if (!isValidRecordSizeAtLeast(2, "Valuesymtab value entry"))
+    if (!isValidRecordSizeAtLeast(2, "value entry"))
       return;
     ConvertToString(ConvertedName);
     setValueName(Values[0], ConvertedName);
@@ -1028,7 +1079,7 @@
   }
   case naclbitc::VST_CODE_BBENTRY: {
     // VST_BBENTRY: [BbId, namechar x N]
-    if (!isValidRecordSizeAtLeast(2, "Valuesymtab basic block entry"))
+    if (!isValidRecordSizeAtLeast(2, "basic block entry"))
       return;
     ConvertToString(ConvertedName);
     setBbName(Values[0], ConvertedName);
@@ -1048,7 +1099,6 @@
 class FunctionParser : public BlockParserBaseClass {
   FunctionParser(const FunctionParser &) = delete;
   FunctionParser &operator=(const FunctionParser &) = delete;
-  friend class FunctionValuesymtabParser;
 
 public:
   FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
@@ -1090,6 +1140,16 @@
 
   ~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) {
     setOperand(NextLocalInstIndex++, Op);
   }
@@ -1097,6 +1157,32 @@
   // Set the next constant ID to the given constant 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:
   Ice::TimerMarker Timer;
   // The corresponding ICE function defined by the function block.
@@ -1247,32 +1333,6 @@
     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.
   void setOperand(uint32_t Index, Ice::Operand *Op) {
     assert(Op || isIRGenerationDisabled());
@@ -1761,7 +1821,7 @@
   switch (Record.GetCode()) {
   case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
     // DECLAREBLOCKS: [n]
-    if (!isValidRecordSize(1, "function block count"))
+    if (!isValidRecordSize(1, "count"))
       return;
     uint32_t NumBbs = Values[0];
     if (NumBbs == 0) {
@@ -1783,7 +1843,7 @@
   }
   case naclbitc::FUNC_CODE_INST_BINOP: {
     // BINOP: [opval, opval, opcode]
-    if (!isValidRecordSize(3, "function block binop"))
+    if (!isValidRecordSize(3, "binop"))
       return;
     Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
     Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
@@ -1812,7 +1872,7 @@
   }
   case naclbitc::FUNC_CODE_INST_CAST: {
     // CAST: [opval, destty, castopc]
-    if (!isValidRecordSize(3, "function block cast"))
+    if (!isValidRecordSize(3, "cast"))
       return;
     Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
     Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
@@ -1849,7 +1909,7 @@
   }
   case naclbitc::FUNC_CODE_INST_VSELECT: {
     // VSELECT: [opval, opval, pred]
-    if (!isValidRecordSize(3, "function block select"))
+    if (!isValidRecordSize(3, "select"))
       return;
     Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
     Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
@@ -1898,7 +1958,7 @@
   }
   case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
     // EXTRACTELT: [opval, opval]
-    if (!isValidRecordSize(2, "function block extract element"))
+    if (!isValidRecordSize(2, "extract element"))
       return;
     Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
     Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
@@ -1925,7 +1985,7 @@
   }
   case naclbitc::FUNC_CODE_INST_INSERTELT: {
     // INSERTELT: [opval, opval, opval]
-    if (!isValidRecordSize(3, "function block insert element"))
+    if (!isValidRecordSize(3, "insert element"))
       return;
     Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
     Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
@@ -1954,7 +2014,7 @@
   }
   case naclbitc::FUNC_CODE_INST_CMP2: {
     // CMP2: [opval, opval, pred]
-    if (!isValidRecordSize(3, "function block compare"))
+    if (!isValidRecordSize(3, "compare"))
       return;
     Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
     Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
@@ -2020,7 +2080,7 @@
   }
   case naclbitc::FUNC_CODE_INST_RET: {
     // RET: [opval?]
-    if (!isValidRecordSizeInRange(0, 1, "function block ret"))
+    if (!isValidRecordSizeInRange(0, 1, "return"))
       return;
     if (Values.empty()) {
       if (isIRGenerationDisabled())
@@ -2048,7 +2108,7 @@
       CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
     } else {
       // BR: [bb#, bb#, opval]
-      if (!isValidRecordSize(3, "function block branch"))
+      if (!isValidRecordSize(3, "branch"))
         return;
       Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
       if (isIRGenerationDisabled()) {
@@ -2082,7 +2142,7 @@
     // unnecesary data fields (i.e. constants 1).  These were not
     // cleaned up in PNaCl bitcode because the bitcode format was
     // already frozen when the problem was noticed.
-    if (!isValidRecordSizeAtLeast(4, "function block switch"))
+    if (!isValidRecordSizeAtLeast(4, "switch"))
       return;
 
     Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
@@ -2112,7 +2172,7 @@
     unsigned NumCases = Values[3];
 
     // Now recognize each of the cases.
-    if (!isValidRecordSize(4 + NumCases * 4, "Function block switch"))
+    if (!isValidRecordSize(4 + NumCases * 4, "switch"))
       return;
     Ice::InstSwitch *Switch =
         isIRGenDisabled ? nullptr : Ice::InstSwitch::create(Func, NumCases,
@@ -2144,7 +2204,7 @@
   }
   case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
     // UNREACHABLE: []
-    if (!isValidRecordSize(0, "function block unreachable"))
+    if (!isValidRecordSize(0, "unreachable"))
       return;
     if (isIRGenerationDisabled())
       return;
@@ -2155,7 +2215,7 @@
   }
   case naclbitc::FUNC_CODE_INST_PHI: {
     // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
-    if (!isValidRecordSizeAtLeast(3, "function block phi"))
+    if (!isValidRecordSizeAtLeast(3, "phi"))
       return;
     Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
     if ((Values.size() & 0x1) == 0) {
@@ -2201,7 +2261,7 @@
   }
   case naclbitc::FUNC_CODE_INST_ALLOCA: {
     // ALLOCA: [Size, align]
-    if (!isValidRecordSize(2, "function block alloca"))
+    if (!isValidRecordSize(2, "alloca"))
       return;
     Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
     unsigned Alignment;
@@ -2226,7 +2286,7 @@
   }
   case naclbitc::FUNC_CODE_INST_LOAD: {
     // LOAD: [address, align, ty]
-    if (!isValidRecordSize(3, "function block load"))
+    if (!isValidRecordSize(3, "load"))
       return;
     Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
     Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
@@ -2251,7 +2311,7 @@
   }
   case naclbitc::FUNC_CODE_INST_STORE: {
     // STORE: [address, value, align]
-    if (!isValidRecordSize(3, "function block store"))
+    if (!isValidRecordSize(3, "store"))
       return;
     Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
     Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
@@ -2283,10 +2343,10 @@
     // corresponding return type stored in CALL_INDIRECT record.
     Ice::SizeT ParamsStartIndex = 2;
     if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
-      if (!isValidRecordSizeAtLeast(2, "function block call"))
+      if (!isValidRecordSizeAtLeast(2, "call"))
         return;
     } else {
-      if (!isValidRecordSizeAtLeast(3, "function block call indirect"))
+      if (!isValidRecordSizeAtLeast(3, "call indirect"))
         return;
       ParamsStartIndex = 3;
     }
@@ -2415,7 +2475,7 @@
   }
   case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
     // FORWARDTYPEREF: [opval, ty]
-    if (!isValidRecordSize(2, "function block forward type ref"))
+    if (!isValidRecordSize(2, "forward type ref"))
       return;
     Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
     setOperand(Values[0],
@@ -2442,6 +2502,8 @@
 
   ~ConstantsParser() override {}
 
+  const char *getBlockName() const override { return "constants"; }
+
 private:
   Ice::TimerMarker Timer;
   // The parser of the function block this constants block appears in.
@@ -2468,7 +2530,7 @@
   switch (Record.GetCode()) {
   case naclbitc::CST_CODE_SETTYPE: {
     // SETTYPE: [typeid]
-    if (!isValidRecordSize(1, "constants block set type"))
+    if (!isValidRecordSize(1, "set type"))
       return;
     NextConstantType = Context->getSimpleTypeByID(Values[0]);
     if (NextConstantType == Ice::IceType_void)
@@ -2477,7 +2539,7 @@
   }
   case naclbitc::CST_CODE_UNDEF: {
     // UNDEF
-    if (!isValidRecordSize(0, "constants block undef"))
+    if (!isValidRecordSize(0, "undef"))
       return;
     if (!isValidNextConstantType())
       return;
@@ -2491,7 +2553,7 @@
   }
   case naclbitc::CST_CODE_INTEGER: {
     // INTEGER: [intval]
-    if (!isValidRecordSize(1, "constants block integer"))
+    if (!isValidRecordSize(1, "integer"))
       return;
     if (!isValidNextConstantType())
       return;
@@ -2517,7 +2579,7 @@
   }
   case naclbitc::CST_CODE_FLOAT: {
     // FLOAT: [fpval]
-    if (!isValidRecordSize(1, "constants block float"))
+    if (!isValidRecordSize(1, "float"))
       return;
     if (!isValidNextConstantType())
       return;
@@ -2592,7 +2654,7 @@
 void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
   // Note: We check when Index is too small, so that we can error recover
   // (FP->getOperand will create fatal error).
-  if (Index < getFunctionParser()->CachedNumGlobalValueIDs) {
+  if (Index < getFunctionParser()->getNumGlobalIDs()) {
     reportUnableToAssign("instruction", Index, Name);
     // TODO(kschimpf) Remove error recovery once implementation complete.
     return;
@@ -2611,12 +2673,12 @@
 void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) {
   if (isIRGenerationDisabled())
     return;
-  if (Index >= getFunctionParser()->Func->getNumNodes()) {
+  if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
     reportUnableToAssign("block", Index, Name);
     return;
   }
   std::string Nm(Name.data(), Name.size());
-  getFunctionParser()->Func->getNodes()[Index]->setName(Nm);
+  getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
 }
 
 bool FunctionParser::ParseBlock(unsigned BlockID) {
@@ -2649,6 +2711,8 @@
 
   ~ModuleParser() override {}
 
+  const char *getBlockName() const override { return "module"; }
+
 private:
   Ice::TimerMarker Timer;
   // True if we have already installed names for unnamed global declarations,
@@ -2768,7 +2832,7 @@
   switch (Record.GetCode()) {
   case naclbitc::MODULE_CODE_VERSION: {
     // VERSION: [version#]
-    if (!isValidRecordSize(1, "Module version"))
+    if (!isValidRecordSize(1, "version"))
       return;
     unsigned Version = Values[0];
     if (Version != 1) {
@@ -2781,14 +2845,14 @@
   }
   case naclbitc::MODULE_CODE_FUNCTION: {
     // FUNCTION:  [type, callingconv, isproto, linkage]
-    if (!isValidRecordSize(4, "Function heading"))
+    if (!isValidRecordSize(4, "address"))
       return;
     const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
     CallingConv::ID CallingConv;
     if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Function heading has unknown calling convention: "
+      StrBuf << "Function address has unknown calling convention: "
              << Values[1];
       Error(StrBuf.str());
       return;
@@ -2797,7 +2861,7 @@
     if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
       std::string 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());
       return;
     }
diff --git a/tests_lit/reader_tests/insertextract-err.ll b/tests_lit/parse_errs/insertextract-err.ll
similarity index 60%
rename from tests_lit/reader_tests/insertextract-err.ll
rename to tests_lit/parse_errs/insertextract-err.ll
index e3f9b72..e20e114 100644
--- a/tests_lit/reader_tests/insertextract-err.ll
+++ b/tests_lit/parse_errs/insertextract-err.ll
@@ -1,149 +1,196 @@
-; Tests insertelement and extractelement vector instructions report
-; errors when malformed. Note: We can only test literal indexing since
-; llvm-as will not allow other bad forms of these instructions.
+; Tests malformed insertelement and extractelement vector instructions.
 
-; REQUIRES: allow_dump
-; RUN: llvm-as < %s | pnacl-freeze \
-; RUN:   | not %llvm2ice -notranslate -build-on-read \
-; RUN:     -allow-pnacl-reader-error-recovery | FileCheck %s
+; RUN: %if --need=allow_dump --command llvm-as < %s \
+; RUN:   | %if --need=allow_dump --command pnacl-freeze \
+; RUN:   | %if --need=allow_dump --command not %llvm2ice -notranslate \
+; 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) {
   %e0 = extractelement <4 x i1> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 4 3>
   %e1 = extractelement <4 x i1> %v, i32 4
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   %e2 = extractelement <4 x i1> %v, i32 9
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record:  <6 6 3>
   ret void
 }
 
 define void @ExtractV8xi1(<8 x i1> %v, i32 %i) {
   %e0 = extractelement <8 x i1> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 4 3>
   %e1 = extractelement <8 x i1> %v, i32 8;
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   %e2 = extractelement <8 x i1> %v, i32 9;
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 6 3>
   ret void
 }
 
 define void @ExtractV16xi1(<16 x i1> %v, i32 %i) {
   %e0 = extractelement <16 x i1> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 4 3>
   %e1 = extractelement <16 x i1> %v, i32 16
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   %e2 = extractelement <16 x i1> %v, i32 24
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 6 3>
   ret void
 }
 
 define void @ExtractV16xi8(<16 x i8> %v, i32 %i) {
   %e0 = extractelement <16 x i8> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 4 3>
   %e1 = extractelement <16 x i8> %v, i32 16
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   %e2 = extractelement <16 x i8> %v, i32 71
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 6 3>
   ret void
 }
 
 define void @ExtractV8xi16(<8 x i16> %v, i32 %i) {
   %e0 = extractelement <8 x i16> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 4 3>
   %e1 = extractelement <8 x i16> %v, i32 8
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   %e2 = extractelement <8 x i16> %v, i32 15
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 6 3>
   ret void
 }
 
 define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) {
   %e0 = extractelement <4 x i32> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 4 3>
   %e1 = extractelement <4 x i32> %v, i32 4
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   %e2 = extractelement <4 x i32> %v, i32 17
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 6 3>
   ret i32 %e0
 }
 
 define float @ExtractV4xfloat(<4 x float> %v, i32 %i) {
   %e0 = extractelement <4 x float> %v, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <6 3 2>
   %e1 = extractelement <4 x float> %v, i32 4
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 4 2>
   %e2 = extractelement <4 x float> %v, i32 4
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <6 5 3>
   ret float %e2
 }
 
 define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %i) {
   %r0 = insertelement <4 x i1> %v, i1 1, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
   %r1 = insertelement <4 x i1> %v, i1 1, i32 4
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
   %r2 = insertelement <4 x i1> %v, i1 1, i32 7
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
   ret <4 x i1> %r2
 }
 
 define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %i) {
   %r0 = insertelement <8 x i1> %v, i1 0, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
   %r1 = insertelement <8 x i1> %v, i1 0, i32 8
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
   %r2 = insertelement <8 x i1> %v, i1 0, i32 88
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
   ret <8 x i1> %r2
 }
 
 define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %i) {
   %r = insertelement <16 x i1> %v, i1 1, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
   ret <16 x i1> %r
   %r1 = insertelement <16 x i1> %v, i1 1, i32 16
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
   %r2 = insertelement <16 x i1> %v, i1 1, i32 31
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
   ret <16 x i1> %r2
 }
 
 define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %i) {
   %r0 = insertelement <16 x i8> %v, i8 34, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
   %r1 = insertelement <16 x i8> %v, i8 34, i32 16
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
   %r2 = insertelement <16 x i8> %v, i8 34, i32 19
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
   ret <16 x i8> %r0
 }
 
 define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %i) {
   %r0 = insertelement <8 x i16> %v, i16 289, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
   %r1 = insertelement <8 x i16> %v, i16 289, i32 8
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 6 2 4>
   %r2 = insertelement <8 x i16> %v, i16 289, i32 19
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
   ret <8 x i16> %r1
 }
 
 define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %i) {
   %r0 = insertelement <4 x i32> %v, i32 54545454, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 3 4>
   %r1 = insertelement <4 x i32> %v, i32 54545454, i32 4
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 6 4 3>
   %r2 = insertelement <4 x i32> %v, i32 54545454, i32 9
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 5 3>
   ret <4 x i32> %r2
 }
 
 define <4 x float> @InsertV4xfloat(<4 x float> %v, i32 %i) {
   %r0 = insertelement <4 x float> %v, float 3.0, i32 %i
 ; CHECK: Error: {{.*}} not {{.*}} constant
+; MIN: Error: {{.*}} Invalid function record: <7 5 1 4>
   %r1 = insertelement <4 x float> %v, float 3.0, i32 4
 ; 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
 ; CHECK: Error: {{.*}} not in range
+; MIN: Error: {{.*}} Invalid function record: <7 7 3 4>
   ret <4 x float> %r2
 }
diff --git a/tests_lit/parse_errs/nacl-fake-intrinsic.ll b/tests_lit/parse_errs/nacl-fake-intrinsic.ll
new file mode 100644
index 0000000..eabb149
--- /dev/null
+++ b/tests_lit/parse_errs/nacl-fake-intrinsic.ll
@@ -0,0 +1,32 @@
+; 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>
diff --git a/tests_lit/reader_tests/alloca.ll b/tests_lit/reader_tests/alloca.ll
index 9ed7b81..0a314e0 100644
--- a/tests_lit/reader_tests/alloca.ll
+++ b/tests_lit/reader_tests/alloca.ll
@@ -1,7 +1,5 @@
 ; Test if we can read alloca instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/binops.ll b/tests_lit/reader_tests/binops.ll
index e1e8ecc..65ed55e 100644
--- a/tests_lit/reader_tests/binops.ll
+++ b/tests_lit/reader_tests/binops.ll
@@ -1,7 +1,5 @@
 ; Tests if we can read binary operators.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
 ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
diff --git a/tests_lit/reader_tests/branch.ll b/tests_lit/reader_tests/branch.ll
index a11e708..b68a016 100644
--- a/tests_lit/reader_tests/branch.ll
+++ b/tests_lit/reader_tests/branch.ll
@@ -1,7 +1,5 @@
 ; Tests if we handle a branch instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/call-indirect.ll b/tests_lit/reader_tests/call-indirect.ll
index 711bf41..3da87dd 100644
--- a/tests_lit/reader_tests/call-indirect.ll
+++ b/tests_lit/reader_tests/call-indirect.ll
@@ -1,7 +1,5 @@
 ; Test parsing indirect calls in Subzero.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/call.ll b/tests_lit/reader_tests/call.ll
index c1bc0b7..95227a6 100644
--- a/tests_lit/reader_tests/call.ll
+++ b/tests_lit/reader_tests/call.ll
@@ -1,7 +1,5 @@
 ; Test handling of call instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/casts.ll b/tests_lit/reader_tests/casts.ll
index c399db8..2bf76eb 100644
--- a/tests_lit/reader_tests/casts.ll
+++ b/tests_lit/reader_tests/casts.ll
@@ -1,7 +1,5 @@
 ; Tests if we can read cast operations.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts --no-local-syms | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/compare.ll b/tests_lit/reader_tests/compare.ll
index 311d94b..7c92f51 100644
--- a/tests_lit/reader_tests/compare.ll
+++ b/tests_lit/reader_tests/compare.ll
@@ -1,7 +1,5 @@
 ; Test if we can read compare instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/constants.ll b/tests_lit/reader_tests/constants.ll
index e022aaa..d8127e6 100644
--- a/tests_lit/reader_tests/constants.ll
+++ b/tests_lit/reader_tests/constants.ll
@@ -1,7 +1,5 @@
 ; Test handling of constants in function blocks.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/forwardref.ll b/tests_lit/reader_tests/forwardref.ll
index c1c94ec..86b41b7 100644
--- a/tests_lit/reader_tests/forwardref.ll
+++ b/tests_lit/reader_tests/forwardref.ll
@@ -1,7 +1,5 @@
 ; Test use forward type references in function blocks.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: llvm-as < %s | pnacl-freeze | pnacl-bcdis -no-records \
 ; RUN:              | FileCheck --check-prefix=DUMP %s
diff --git a/tests_lit/reader_tests/globalinit.pnacl.ll b/tests_lit/reader_tests/globalinit.pnacl.ll
index 7f807e6..0d92351 100644
--- a/tests_lit/reader_tests/globalinit.pnacl.ll
+++ b/tests_lit/reader_tests/globalinit.pnacl.ll
@@ -1,7 +1,5 @@
 ; Test of global initializers.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
 ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
diff --git a/tests_lit/reader_tests/globalrelocs.ll b/tests_lit/reader_tests/globalrelocs.ll
index 055d423..a6a44f7 100644
--- a/tests_lit/reader_tests/globalrelocs.ll
+++ b/tests_lit/reader_tests/globalrelocs.ll
@@ -1,7 +1,5 @@
 ; Tests if we handle global variables with relocation initializers.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
 ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
diff --git a/tests_lit/reader_tests/insertextract.ll b/tests_lit/reader_tests/insertextract.ll
index 8d4106e..ca01469 100644
--- a/tests_lit/reader_tests/insertextract.ll
+++ b/tests_lit/reader_tests/insertextract.ll
@@ -1,7 +1,5 @@
 ; Tests insertelement and extractelement vector instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %l2i -i %s --insts | %ifl FileCheck %s
 ; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
diff --git a/tests_lit/reader_tests/lit.local.cfg b/tests_lit/reader_tests/lit.local.cfg
new file mode 100644
index 0000000..7781f86
--- /dev/null
+++ b/tests_lit/reader_tests/lit.local.cfg
@@ -0,0 +1,7 @@
+# -*- 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
diff --git a/tests_lit/reader_tests/load.ll b/tests_lit/reader_tests/load.ll
index b7682b6..75591ae 100644
--- a/tests_lit/reader_tests/load.ll
+++ b/tests_lit/reader_tests/load.ll
@@ -1,7 +1,5 @@
 ; Test if we can read load instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/nacl-atomic-intrinsics.ll b/tests_lit/reader_tests/nacl-atomic-intrinsics.ll
index 01dfb27..b59b380 100644
--- a/tests_lit/reader_tests/nacl-atomic-intrinsics.ll
+++ b/tests_lit/reader_tests/nacl-atomic-intrinsics.ll
@@ -1,7 +1,5 @@
 ; Test parsing NaCl atomic instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/nacl-fake-intrinsic.ll b/tests_lit/reader_tests/nacl-fake-intrinsic.ll
deleted file mode 100644
index c827fe8..0000000
--- a/tests_lit/reader_tests/nacl-fake-intrinsic.ll
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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
-
diff --git a/tests_lit/reader_tests/nacl-other-intrinsics.ll b/tests_lit/reader_tests/nacl-other-intrinsics.ll
index c4e5465..aac2c25 100644
--- a/tests_lit/reader_tests/nacl-other-intrinsics.ll
+++ b/tests_lit/reader_tests/nacl-other-intrinsics.ll
@@ -1,7 +1,5 @@
 ; This tests parsing NaCl intrinsics not related to atomic operations.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/phi.ll b/tests_lit/reader_tests/phi.ll
index 032082b..a90bc4c 100644
--- a/tests_lit/reader_tests/phi.ll
+++ b/tests_lit/reader_tests/phi.ll
@@ -1,7 +1,5 @@
 ; Test reading phi instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/select.ll b/tests_lit/reader_tests/select.ll
index b8b116d..8421084 100644
--- a/tests_lit/reader_tests/select.ll
+++ b/tests_lit/reader_tests/select.ll
@@ -1,7 +1,5 @@
 ; Tests if we can read select instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/store.ll b/tests_lit/reader_tests/store.ll
index 60cb5ec..091e763 100644
--- a/tests_lit/reader_tests/store.ll
+++ b/tests_lit/reader_tests/store.ll
@@ -1,7 +1,5 @@
 ; Test if we can read store instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts --no-local-syms | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/switch.ll b/tests_lit/reader_tests/switch.ll
index 827f9b9..0bbbf88 100644
--- a/tests_lit/reader_tests/switch.ll
+++ b/tests_lit/reader_tests/switch.ll
@@ -1,7 +1,5 @@
 ; Test switch instructions.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \
diff --git a/tests_lit/reader_tests/unnamed.ll b/tests_lit/reader_tests/unnamed.ll
index 38d74bb..3f84b01 100644
--- a/tests_lit/reader_tests/unnamed.ll
+++ b/tests_lit/reader_tests/unnamed.ll
@@ -1,7 +1,5 @@
 ; Tests that we name unnamed global addresses.
 
-; REQUIRES: allow_dump
-
 ; Check that Subzero's bitcode reader handles renaming correctly.
 ; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s
 ; RUN: %l2i --no-local-syms -i %s --insts | %ifl FileCheck %s
diff --git a/tests_lit/reader_tests/unreachable.ll b/tests_lit/reader_tests/unreachable.ll
index 02d3a01..7f12187 100644
--- a/tests_lit/reader_tests/unreachable.ll
+++ b/tests_lit/reader_tests/unreachable.ll
@@ -1,7 +1,5 @@
 ; Test parsing unreachable instruction.
 
-; REQUIRES: allow_dump
-
 ; RUN: %p2i -i %s --insts | FileCheck %s
 ; RUN: %if --need=allow_disable_ir_gen --command \
 ; RUN:   %p2i -i %s --args -notranslate -timing -no-ir-gen \