OSDN Git Service

Add unreachable instruction to Subzero.
authorKarl Schimpf <kschimpf@google.com>
Tue, 16 Sep 2014 20:35:32 +0000 (13:35 -0700)
committerKarl Schimpf <kschimpf@google.com>
Tue, 16 Sep 2014 20:35:32 +0000 (13:35 -0700)
Also fixes error messages on instruction operands, to print
out the operand (rather than pointer to it), since we can
now print out operands.

BUG= https://code.google.com/p/nativeclient/issues/detail?id=389
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/577703002

src/IceOperand.h
src/PNaClTranslator.cpp
tests_lit/reader_tests/unreachable.ll [new file with mode: 0644]

index c46330d..cefdf9f 100644 (file)
@@ -84,6 +84,12 @@ private:
   Operand &operator=(const Operand &) LLVM_DELETED_FUNCTION;
 };
 
+template<class StreamType>
+inline StreamType &operator<<(StreamType &Str, const Operand &Op) {
+  Op.dump(Str);
+  return Str;
+}
+
 // Constant is the abstract base class for constants.  All
 // constants are allocated from a global arena and are pooled.
 class Constant : public Operand {
index fcebeac..df2989c 100644 (file)
@@ -1010,7 +1010,7 @@ private:
     std::string Buffer;
     raw_string_ostream StrBuf(Buffer);
     StrBuf << InstructionName << " address not " << PtrType
-           << ". Found: " << Op;
+           << ". Found: " << *Op;
     Error(StrBuf.str());
     return false;
   }
@@ -1423,7 +1423,7 @@ void FunctionParser::ProcessRecord() {
           typeNumElements(ThenType) != typeNumElements(CondType)) {
         std::string Buffer;
         raw_string_ostream StrBuf(Buffer);
-        StrBuf << "Select condition " << CondType
+        StrBuf << "Select condition type " << CondType
                << " not allowed for values of type " << ThenType;
         Error(StrBuf.str());
         return;
@@ -1431,7 +1431,8 @@ void FunctionParser::ProcessRecord() {
     } else if (CondVal->getType() != Ice::IceType_i1) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Select condition not type i1. Found: " << CondVal->getType();
+      StrBuf << "Select condition " << CondVal << " not type i1. Found: "
+             << CondVal->getType();
       Error(StrBuf.str());
       return;
     }
@@ -1448,14 +1449,15 @@ void FunctionParser::ProcessRecord() {
     if (!Ice::isVectorType(VecType)) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Extractelement not on vector. Found: " << Vec;
+      StrBuf << "Extractelement not on vector. Found: " << *Vec;
       Error(StrBuf.str());
     }
     Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
     if (Index->getType() != Ice::IceType_i32) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Extractelement index not i32. Found: " << Index;
+      StrBuf << "Extractelement index " << *Index << " not i32. Found: "
+             << Index->getType();
       Error(StrBuf.str());
     }
     // TODO(kschimpf): Restrict index to a legal constant index (once
@@ -1473,7 +1475,7 @@ void FunctionParser::ProcessRecord() {
     if (!Ice::isVectorType(VecType)) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Insertelement not on vector. Found: " << Vec;
+      StrBuf << "Insertelement not on vector. Found: " << *Vec;
       Error(StrBuf.str());
     }
     Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
@@ -1481,15 +1483,17 @@ void FunctionParser::ProcessRecord() {
     if (EltType != typeElementType(VecType)) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Insertelement element not " << typeElementType(VecType)
-             << ". Found: " << Elt;
+      StrBuf << "Insertelement element " << *Elt << " not type "
+             << typeElementType(VecType)
+             << ". Found: " << EltType;
       Error(StrBuf.str());
     }
     Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
     if (Index->getType() != Ice::IceType_i32) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Insertelement index not i32. Found: " << Index;
+      StrBuf << "Insertelement index " << *Index << " not i32. Found: "
+             << Index->getType();
       Error(StrBuf.str());
     }
     // TODO(kschimpf): Restrict index to a legal constant index (once
@@ -1588,7 +1592,8 @@ void FunctionParser::ProcessRecord() {
       if (Cond->getType() != Ice::IceType_i1) {
         std::string Buffer;
         raw_string_ostream StrBuf(Buffer);
-        StrBuf << "Branch condition not i1";
+        StrBuf << "Branch condition " << *Cond << " not i1. Found: "
+               << Cond->getType();
         Error(StrBuf.str());
         return;
       }
@@ -1602,6 +1607,15 @@ void FunctionParser::ProcessRecord() {
     InstIsTerminating = true;
     break;
   }
+  case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
+    // UNREACHABLE: []
+    if (!isValidRecordSize(0, "function block unreachable"))
+      return;
+    CurrentNode->appendInst(
+        Ice::InstUnreachable::create(Func));
+    InstIsTerminating = true;
+    break;
+  }
   case naclbitc::FUNC_CODE_INST_PHI: {
     // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
     if (!isValidRecordSizeAtLeast(3, "function block phi"))
@@ -1627,7 +1641,8 @@ void FunctionParser::ProcessRecord() {
       if (Op->getType() != Ty) {
         std::string Buffer;
         raw_string_ostream StrBuf(Buffer);
-        StrBuf << "Phi instruction expects type " << Ty << " but found: " << Op;
+        StrBuf << "Value " << *Op << " not type " << Ty
+               << " in phi instruction. Found: " << Op->getType();
         Error(StrBuf.str());
         return;
       }
@@ -1644,7 +1659,7 @@ void FunctionParser::ProcessRecord() {
     if (ByteCount->getType() != Ice::IceType_i32) {
       std::string Buffer;
       raw_string_ostream StrBuf(Buffer);
-      StrBuf << "Alloca on non-i32 value. Found: " << ByteCount;
+      StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
       Error(StrBuf.str());
       return;
     }
@@ -1687,6 +1702,10 @@ void FunctionParser::ProcessRecord() {
         Ice::InstStore::create(Func, Value, Address, Alignment));
     break;
   }
+  case naclbitc::FUNC_CODE_INST_SWITCH:
+  case naclbitc::FUNC_CODE_INST_CALL:
+  case naclbitc::FUNC_CODE_INST_CALL_INDIRECT:
+  case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF:
   default:
     // Generate error message!
     BlockParserBaseClass::ProcessRecord();
diff --git a/tests_lit/reader_tests/unreachable.ll b/tests_lit/reader_tests/unreachable.ll
new file mode 100644 (file)
index 0000000..954c8f8
--- /dev/null
@@ -0,0 +1,31 @@
+; Test parsing unreachable instruction.
+
+; RUN: llvm-as < %s | pnacl-freeze -allow-local-symbol-tables \
+; RUN:              | %llvm2ice -notranslate -verbose=inst -build-on-read \
+; RUN:                -allow-pnacl-reader-error-recovery \
+; RUN:                -allow-local-symbol-tables \
+; RUN:              | FileCheck %s
+
+define internal i32 @divide(i32 %num, i32 %den) {
+entry:
+  %cmp = icmp ne i32 %den, 0
+  br i1 %cmp, label %return, label %abort
+
+abort:                                            ; preds = %entry
+  unreachable
+
+return:                                           ; preds = %entry
+  %div = sdiv i32 %num, %den
+  ret i32 %div
+}
+
+; CHECK:      define internal i32 @divide(i32 %num, i32 %den) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT:   %cmp = icmp ne i32 %den, 0
+; CHECK-NEXT:   br i1 %cmp, label %return, label %abort
+; CHECK-NEXT: abort:
+; CHECK-NEXT:   unreachable
+; CHECK-NEXT: return:
+; CHECK-NEXT:   %div = sdiv i32 %num, %den
+; CHECK-NEXT:   ret i32 %div
+; CHECK-NEXT: }