Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update grammar to LLVM 9.0 #101

Closed
11 of 16 tasks
mewmew opened this issue Oct 28, 2019 · 6 comments
Closed
11 of 16 tasks

update grammar to LLVM 9.0 #101

mewmew opened this issue Oct 28, 2019 · 6 comments

Comments

@mewmew
Copy link
Member

mewmew commented Oct 28, 2019

With LLVM 9.0 released, we should sync the grammar and the IR with the latest version.

Some of the changes will be very simple, e.g.

Other changes are also quite easy, e.g.

Other changes are slightly more involved, e.g.

And some changes have dependencies, e.g.

To get a feel for what changes to the LLVM IR assembly that were introduced between LLVM 8.0 and 9.0, we run diff between the source releases of these respective versions.

$ diff -r -u llvm-8.0.0.src/lib/AsmParser/ llvm-9.0.0.src/lib/AsmParser/
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/LLLexer.cpp llvm-9.0.0.src/lib/AsmParser/LLLexer.cpp
--- llvm-8.0.0.src/lib/AsmParser/LLLexer.cpp	2019-10-24 23:46:14.551184617 +0200
+++ llvm-9.0.0.src/lib/AsmParser/LLLexer.cpp	2019-07-15 22:02:23.000000000 +0200
@@ -1,9 +1,8 @@
 //===- LLLexer.cpp - Lexer for .ll Files ----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -571,6 +570,7 @@
   KEYWORD(align);
   KEYWORD(addrspace);
   KEYWORD(section);
+  KEYWORD(partition);
   KEYWORD(alias);
   KEYWORD(ifunc);
   KEYWORD(module);
@@ -650,6 +650,7 @@
   KEYWORD(nobuiltin);
   KEYWORD(nocapture);
   KEYWORD(noduplicate);
+  KEYWORD(nofree);
   KEYWORD(noimplicitfloat);
   KEYWORD(noinline);
   KEYWORD(norecurse);
@@ -657,6 +658,7 @@
   KEYWORD(nonnull);
   KEYWORD(noredzone);
   KEYWORD(noreturn);
+  KEYWORD(nosync);
   KEYWORD(nocf_check);
   KEYWORD(nounwind);
   KEYWORD(optforfuzzing);
@@ -677,14 +679,17 @@
   KEYWORD(shadowcallstack);
   KEYWORD(sanitize_address);
   KEYWORD(sanitize_hwaddress);
+  KEYWORD(sanitize_memtag);
   KEYWORD(sanitize_thread);
   KEYWORD(sanitize_memory);
   KEYWORD(speculative_load_hardening);
   KEYWORD(swifterror);
   KEYWORD(swiftself);
   KEYWORD(uwtable);
+  KEYWORD(willreturn);
   KEYWORD(writeonly);
   KEYWORD(zeroext);
+  KEYWORD(immarg);
 
   KEYWORD(type);
   KEYWORD(opaque);
@@ -706,6 +711,7 @@
   KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);
   KEYWORD(umin);
 
+  KEYWORD(vscale);
   KEYWORD(x);
   KEYWORD(blockaddress);
 
@@ -733,6 +739,7 @@
   KEYWORD(notEligibleToImport);
   KEYWORD(live);
   KEYWORD(dsoLocal);
+  KEYWORD(canAutoHide);
   KEYWORD(function);
   KEYWORD(insts);
   KEYWORD(funcFlags);
@@ -749,6 +756,8 @@
   KEYWORD(critical);
   KEYWORD(relbf);
   KEYWORD(variable);
+  KEYWORD(vTableFuncs);
+  KEYWORD(virtFunc);
   KEYWORD(aliasee);
   KEYWORD(refs);
   KEYWORD(typeIdInfo);
@@ -761,6 +770,7 @@
   KEYWORD(offset);
   KEYWORD(args);
   KEYWORD(typeid);
+  KEYWORD(typeidCompatibleVTable);
   KEYWORD(summary);
   KEYWORD(typeTestRes);
   KEYWORD(kind);
@@ -859,6 +869,7 @@
   INSTKEYWORD(invoke,      Invoke);
   INSTKEYWORD(resume,      Resume);
   INSTKEYWORD(unreachable, Unreachable);
+  INSTKEYWORD(callbr,      CallBr);
 
   INSTKEYWORD(alloca,      Alloca);
   INSTKEYWORD(load,        Load);
@@ -1047,7 +1058,17 @@
   for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
     /*empty*/;
 
-  // Check to see if this really is a label afterall, e.g. "-1:".
+  // Check if this is a fully-numeric label:
+  if (isdigit(TokStart[0]) && CurPtr[0] == ':') {
+    uint64_t Val = atoull(TokStart, CurPtr);
+    ++CurPtr; // Skip the colon.
+    if ((unsigned)Val != Val)
+      Error("invalid value number (too large)!");
+    UIntVal = unsigned(Val);
+    return lltok::LabelID;
+  }
+
+  // Check to see if this really is a string label, e.g. "-1:".
   if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {
     if (const char *End = isLabelTail(CurPtr)) {
       StrVal.assign(TokStart, End-1);
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/LLLexer.h llvm-9.0.0.src/lib/AsmParser/LLLexer.h
--- llvm-8.0.0.src/lib/AsmParser/LLLexer.h	2019-10-24 23:46:14.554517951 +0200
+++ llvm-9.0.0.src/lib/AsmParser/LLLexer.h	2019-01-19 09:50:56.000000000 +0100
@@ -1,9 +1,8 @@
 //===- LLLexer.h - Lexer for LLVM Assembly Files ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/LLParser.cpp llvm-9.0.0.src/lib/AsmParser/LLParser.cpp
--- llvm-8.0.0.src/lib/AsmParser/LLParser.cpp	2019-10-24 23:46:14.584517952 +0200
+++ llvm-9.0.0.src/lib/AsmParser/LLParser.cpp	2019-07-15 22:02:23.000000000 +0200
@@ -1,9 +1,8 @@
 //===-- LLParser.cpp - Parser Class ---------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -164,6 +163,14 @@
       AS = AS.addAttributes(Context, AttributeList::FunctionIndex,
                             AttributeSet::get(Context, FnAttrs));
       II->setAttributes(AS);
+    } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(V)) {
+      AttributeList AS = CBI->getAttributes();
+      AttrBuilder FnAttrs(AS.getFnAttributes());
+      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
+      FnAttrs.merge(B);
+      AS = AS.addAttributes(Context, AttributeList::FunctionIndex,
+                            AttributeSet::get(Context, FnAttrs));
+      CBI->setAttributes(AS);
     } else if (auto *GV = dyn_cast<GlobalVariable>(V)) {
       AttrBuilder Attrs(GV->getAttributes());
       Attrs.merge(B);
@@ -814,19 +821,26 @@
   if (!Index)
     return SkipModuleSummaryEntry();
 
+  bool result = false;
   switch (Lex.getKind()) {
   case lltok::kw_gv:
-    return ParseGVEntry(SummaryID);
+    result = ParseGVEntry(SummaryID);
+    break;
   case lltok::kw_module:
-    return ParseModuleEntry(SummaryID);
+    result = ParseModuleEntry(SummaryID);
+    break;
   case lltok::kw_typeid:
-    return ParseTypeIdEntry(SummaryID);
+    result = ParseTypeIdEntry(SummaryID);
+    break;
+  case lltok::kw_typeidCompatibleVTable:
+    result = ParseTypeIdCompatibleVtableEntry(SummaryID);
     break;
   default:
-    return Error(Lex.getLoc(), "unexpected summary kind");
+    result = Error(Lex.getLoc(), "unexpected summary kind");
+    break;
   }
   Lex.setIgnoreColonInIdentifiers(false);
-  return false;
+  return result;
 }
 
 static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
@@ -845,11 +859,14 @@
 ///   ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
 ///                     OptionalVisibility OptionalDLLStorageClass
 ///                     OptionalThreadLocal OptionalUnnamedAddr
-//                      'alias|ifunc' IndirectSymbol
+///                     'alias|ifunc' IndirectSymbol IndirectSymbolAttr*
 ///
 /// IndirectSymbol
 ///   ::= TypeAndValue
 ///
+/// IndirectSymbolAttr
+///   ::= ',' 'partition' StringConstant
+///
 /// Everything through OptionalUnnamedAddr has already been parsed.
 ///
 bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
@@ -949,6 +966,21 @@
   GA->setUnnamedAddr(UnnamedAddr);
   maybeSetDSOLocal(DSOLocal, *GA);
 
+  // At this point we've parsed everything except for the IndirectSymbolAttrs.
+  // Now parse them if there are any.
+  while (Lex.getKind() == lltok::comma) {
+    Lex.Lex();
+
+    if (Lex.getKind() == lltok::kw_partition) {
+      Lex.Lex();
+      GA->setPartition(Lex.getStrVal());
+      if (ParseToken(lltok::StringConstant, "expected partition string"))
+        return true;
+    } else {
+      return TokError("unknown alias or ifunc property!");
+    }
+  }
+
   if (Name.empty())
     NumberedVals.push_back(GA.get());
 
@@ -1084,6 +1116,11 @@
       GV->setSection(Lex.getStrVal());
       if (ParseToken(lltok::StringConstant, "expected global section string"))
         return true;
+    } else if (Lex.getKind() == lltok::kw_partition) {
+      Lex.Lex();
+      GV->setPartition(Lex.getStrVal());
+      if (ParseToken(lltok::StringConstant, "expected partition string"))
+        return true;
     } else if (Lex.getKind() == lltok::kw_align) {
       unsigned Alignment;
       if (ParseOptionalAlignment(Alignment)) return true;
@@ -1243,12 +1280,14 @@
     case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
     case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
     case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+    case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); break;
     case lltok::kw_noimplicitfloat:
       B.addAttribute(Attribute::NoImplicitFloat); break;
     case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
     case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
     case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
     case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
+    case lltok::kw_nosync: B.addAttribute(Attribute::NoSync); break;
     case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break;
     case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
     case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
@@ -1272,6 +1311,8 @@
       B.addAttribute(Attribute::SanitizeAddress); break;
     case lltok::kw_sanitize_hwaddress:
       B.addAttribute(Attribute::SanitizeHWAddress); break;
+    case lltok::kw_sanitize_memtag:
+      B.addAttribute(Attribute::SanitizeMemTag); break;
     case lltok::kw_sanitize_thread:
       B.addAttribute(Attribute::SanitizeThread); break;
     case lltok::kw_sanitize_memory:
@@ -1281,6 +1322,7 @@
       break;
     case lltok::kw_strictfp: B.addAttribute(Attribute::StrictFP); break;
     case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
+    case lltok::kw_willreturn: B.addAttribute(Attribute::WillReturn); break;
     case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
 
     // Error handling.
@@ -1303,6 +1345,7 @@
     case lltok::kw_sret:
     case lltok::kw_swifterror:
     case lltok::kw_swiftself:
+    case lltok::kw_immarg:
       HaveError |=
         Error(Lex.getLoc(),
               "invalid use of parameter-only attribute on a function");
@@ -1566,7 +1609,13 @@
       B.addAlignmentAttr(Alignment);
       continue;
     }
-    case lltok::kw_byval:           B.addAttribute(Attribute::ByVal); break;
+    case lltok::kw_byval: {
+      Type *Ty;
+      if (ParseByValWithOptionalType(Ty))
+        return true;
+      B.addByValAttr(Ty);
+      continue;
+    }
     case lltok::kw_dereferenceable: {
       uint64_t Bytes;
       if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
@@ -1596,6 +1645,7 @@
     case lltok::kw_swiftself:       B.addAttribute(Attribute::SwiftSelf); break;
     case lltok::kw_writeonly:       B.addAttribute(Attribute::WriteOnly); break;
     case lltok::kw_zeroext:         B.addAttribute(Attribute::ZExt); break;
+    case lltok::kw_immarg:          B.addAttribute(Attribute::ImmArg); break;
 
     case lltok::kw_alignstack:
     case lltok::kw_alwaysinline:
@@ -1620,6 +1670,7 @@
     case lltok::kw_returns_twice:
     case lltok::kw_sanitize_address:
     case lltok::kw_sanitize_hwaddress:
+    case lltok::kw_sanitize_memtag:
     case lltok::kw_sanitize_memory:
     case lltok::kw_sanitize_thread:
     case lltok::kw_speculative_load_hardening:
@@ -1690,6 +1741,7 @@
     case lltok::kw_sret:
     case lltok::kw_swifterror:
     case lltok::kw_swiftself:
+    case lltok::kw_immarg:
       HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
       break;
 
@@ -1717,6 +1769,7 @@
     case lltok::kw_returns_twice:
     case lltok::kw_sanitize_address:
     case lltok::kw_sanitize_hwaddress:
+    case lltok::kw_sanitize_memtag:
     case lltok::kw_sanitize_memory:
     case lltok::kw_sanitize_thread:
     case lltok::kw_speculative_load_hardening:
@@ -2417,6 +2470,22 @@
   return false;
 }
 
+/// ParseByValWithOptionalType
+///   ::= byval
+///   ::= byval(<ty>)
+bool LLParser::ParseByValWithOptionalType(Type *&Result) {
+  Result = nullptr;
+  if (!EatIfPresent(lltok::kw_byval))
+    return true;
+  if (!EatIfPresent(lltok::lparen))
+    return false;
+  if (ParseType(Result))
+    return true;
+  if (!EatIfPresent(lltok::rparen))
+    return Error(Lex.getLoc(), "expected ')'");
+  return false;
+}
+
 /// ParseOptionalOperandBundles
 ///    ::= /*empty*/
 ///    ::= '[' OperandBundle [, OperandBundle ]* ']'
@@ -2684,7 +2753,18 @@
 ///   Type
 ///     ::= '[' APSINTVAL 'x' Types ']'
 ///     ::= '<' APSINTVAL 'x' Types '>'
+///     ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>'
 bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) {
+  bool Scalable = false;
+
+  if (isVector && Lex.getKind() == lltok::kw_vscale) {
+    Lex.Lex(); // consume the 'vscale'
+    if (ParseToken(lltok::kw_x, "expected 'x' after vscale"))
+      return true;
+
+    Scalable = true;
+  }
+
   if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
       Lex.getAPSIntVal().getBitWidth() > 64)
     return TokError("expected number in address space");
@@ -2711,7 +2791,7 @@
       return Error(SizeLoc, "size too large for vector");
     if (!VectorType::isValidElementType(EltTy))
       return Error(TypeLoc, "invalid vector element type");
-    Result = VectorType::get(EltTy, unsigned(Size));
+    Result = VectorType::get(EltTy, unsigned(Size), Scalable);
   } else {
     if (!ArrayType::isValidElementType(EltTy))
       return Error(TypeLoc, "invalid array element type");
@@ -2916,13 +2996,27 @@
 /// unnamed.  If there is an error, this returns null otherwise it returns
 /// the block being defined.
 BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name,
-                                                 LocTy Loc) {
+                                                 int NameID, LocTy Loc) {
   BasicBlock *BB;
-  if (Name.empty())
+  if (Name.empty()) {
+    if (NameID != -1 && unsigned(NameID) != NumberedVals.size()) {
+      P.Error(Loc, "label expected to be numbered '" +
+                       Twine(NumberedVals.size()) + "'");
+      return nullptr;
+    }
     BB = GetBB(NumberedVals.size(), Loc);
-  else
+    if (!BB) {
+      P.Error(Loc, "unable to create block numbered '" +
+                       Twine(NumberedVals.size()) + "'");
+      return nullptr;
+    }
+  } else {
     BB = GetBB(Name, Loc);
-  if (!BB) return nullptr; // Already diagnosed error.
+    if (!BB) {
+      P.Error(Loc, "unable to create block named '" + Name + "'");
+      return nullptr;
+    }
+  }
 
   // Move the block to the end of the function.  Forward ref'd blocks are
   // inserted wherever they happen to be referenced.
@@ -3342,7 +3436,6 @@
     unsigned Opc = Lex.getUIntVal();
     Constant *Val0, *Val1;
     Lex.Lex();
-    LocTy ModifierLoc = Lex.getLoc();
     if (Opc == Instruction::Add || Opc == Instruction::Sub ||
         Opc == Instruction::Mul || Opc == Instruction::Shl) {
       if (EatIfPresent(lltok::kw_nuw))
@@ -3365,12 +3458,6 @@
       return true;
     if (Val0->getType() != Val1->getType())
       return Error(ID.Loc, "operands of constexpr must have same type");
-    if (!Val0->getType()->isIntOrIntVectorTy()) {
-      if (NUW)
-        return Error(ModifierLoc, "nuw only applies to integer operations");
-      if (NSW)
-        return Error(ModifierLoc, "nsw only applies to integer operations");
-    }
     // Check that the type is valid for the operator.
     switch (Opc) {
     case Instruction::Add:
@@ -4640,6 +4727,24 @@
   return false;
 }
 
+/// ParseDICommonBlock:
+///   ::= !DICommonBlock(scope: !0, file: !2, name: "COMMON name", line: 9)
+bool LLParser::ParseDICommonBlock(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
+  REQUIRED(scope, MDField, );                                                  \
+  OPTIONAL(declaration, MDField, );                                            \
+  OPTIONAL(name, MDStringField, );                                             \
+  OPTIONAL(file, MDField, );                                                   \
+  OPTIONAL(line, LineField, );						       
+  PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+  Result = GET_OR_DISTINCT(DICommonBlock,
+                           (Context, scope.Val, declaration.Val, name.Val,
+                            file.Val, line.Val));
+  return false;
+}
+
 /// ParseDINamespace:
 ///   ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9)
 bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) {
@@ -4828,6 +4933,15 @@
         return TokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
       }
 
+      if (Lex.getKind() == lltok::DwarfAttEncoding) {
+        if (unsigned Op = dwarf::getAttributeEncoding(Lex.getStrVal())) {
+          Lex.Lex();
+          Elements.push_back(Op);
+          continue;
+        }
+        return TokError(Twine("invalid DWARF attribute encoding '") + Lex.getStrVal() + "'");
+      }
+
       if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
         return TokError("expected unsigned integer");
 
@@ -5239,6 +5353,7 @@
   std::vector<unsigned> FwdRefAttrGrps;
   LocTy BuiltinLoc;
   std::string Section;
+  std::string Partition;
   unsigned Alignment;
   std::string GC;
   GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
@@ -5255,6 +5370,8 @@
                                  BuiltinLoc) ||
       (EatIfPresent(lltok::kw_section) &&
        ParseStringConstant(Section)) ||
+      (EatIfPresent(lltok::kw_partition) &&
+       ParseStringConstant(Partition)) ||
       parseOptionalComdat(FunctionName, C) ||
       ParseOptionalAlignment(Alignment) ||
       (EatIfPresent(lltok::kw_gc) &&
@@ -5356,6 +5473,7 @@
   Fn->setUnnamedAddr(UnnamedAddr);
   Fn->setAlignment(Alignment);
   Fn->setSection(Section);
+  Fn->setPartition(Partition);
   Fn->setComdat(C);
   Fn->setPersonalityFn(PersonalityFn);
   if (!GC.empty()) Fn->setGC(GC);
@@ -5470,20 +5588,23 @@
 }
 
 /// ParseBasicBlock
-///   ::= LabelStr? Instruction*
+///   ::= (LabelStr|LabelID)? Instruction*
 bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
   // If this basic block starts out with a name, remember it.
   std::string Name;
+  int NameID = -1;
   LocTy NameLoc = Lex.getLoc();
   if (Lex.getKind() == lltok::LabelStr) {
     Name = Lex.getStrVal();
     Lex.Lex();
+  } else if (Lex.getKind() == lltok::LabelID) {
+    NameID = Lex.getUIntVal();
+    Lex.Lex();
   }
 
-  BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
+  BasicBlock *BB = PFS.DefineBB(Name, NameID, NameLoc);
   if (!BB)
-    return Error(NameLoc,
-                 "unable to create block named '" + Name + "'");
+    return true;
 
   std::string NameStr;
 
@@ -5567,10 +5688,11 @@
   case lltok::kw_catchswitch: return ParseCatchSwitch(Inst, PFS);
   case lltok::kw_catchpad:    return ParseCatchPad(Inst, PFS);
   case lltok::kw_cleanuppad:  return ParseCleanupPad(Inst, PFS);
+  case lltok::kw_callbr:      return ParseCallBr(Inst, PFS);
   // Unary Operators.
   case lltok::kw_fneg: {
     FastMathFlags FMF = EatFastMathFlagsIfPresent();
-    int Res = ParseUnaryOp(Inst, PFS, KeywordVal, 2);
+    int Res = ParseUnaryOp(Inst, PFS, KeywordVal, /*IsFP*/true);
     if (Res != 0)
       return Res;
     if (FMF.any())
@@ -5586,7 +5708,7 @@
     bool NSW = EatIfPresent(lltok::kw_nsw);
     if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
 
-    if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
+    if (ParseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/false)) return true;
 
     if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
     if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
@@ -5598,7 +5720,7 @@
   case lltok::kw_fdiv:
   case lltok::kw_frem: {
     FastMathFlags FMF = EatFastMathFlagsIfPresent();
-    int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2);
+    int Res = ParseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/true);
     if (Res != 0)
       return Res;
     if (FMF.any())
@@ -5612,13 +5734,14 @@
   case lltok::kw_ashr: {
     bool Exact = EatIfPresent(lltok::kw_exact);
 
-    if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
+    if (ParseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/false)) return true;
     if (Exact) cast<BinaryOperator>(Inst)->setIsExact(true);
     return false;
   }
 
   case lltok::kw_urem:
-  case lltok::kw_srem:   return ParseArithmetic(Inst, PFS, KeywordVal, 1);
+  case lltok::kw_srem:   return ParseArithmetic(Inst, PFS, KeywordVal,
+                                                /*IsFP*/false);
   case lltok::kw_and:
   case lltok::kw_or:
   case lltok::kw_xor:    return ParseLogical(Inst, PFS, KeywordVal);
@@ -5648,7 +5771,19 @@
   case lltok::kw_inttoptr:
   case lltok::kw_ptrtoint:       return ParseCast(Inst, PFS, KeywordVal);
   // Other.
-  case lltok::kw_select:         return ParseSelect(Inst, PFS);
+  case lltok::kw_select: {
+    FastMathFlags FMF = EatFastMathFlagsIfPresent();
+    int Res = ParseSelect(Inst, PFS);
+    if (Res != 0)
+      return Res;
+    if (FMF.any()) {
+      if (!Inst->getType()->isFPOrFPVectorTy())
+        return Error(Loc, "fast-math-flags specified for select without "
+                          "floating-point scalar or vector return type");
+      Inst->setFastMathFlags(FMF);
+    }
+    return 0;
+  }
   case lltok::kw_va_arg:         return ParseVA_Arg(Inst, PFS);
   case lltok::kw_extractelement: return ParseExtractElement(Inst, PFS);
   case lltok::kw_insertelement:  return ParseInsertElement(Inst, PFS);
@@ -6155,28 +6290,16 @@
 /// ParseUnaryOp
 ///  ::= UnaryOp TypeAndValue ',' Value
 ///
-/// If OperandType is 0, then any FP or integer operand is allowed.  If it is 1,
-/// then any integer operand is allowed, if it is 2, any fp operand is allowed.
+/// If IsFP is false, then any integer operand is allowed, if it is true, any fp
+/// operand is allowed.
 bool LLParser::ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS,
-                            unsigned Opc, unsigned OperandType) {
+                            unsigned Opc, bool IsFP) {
   LocTy Loc; Value *LHS;
   if (ParseTypeAndValue(LHS, Loc, PFS))
     return true;
 
-  bool Valid;
-  switch (OperandType) {
-  default: llvm_unreachable("Unknown operand type!");
-  case 0: // int or FP.
-    Valid = LHS->getType()->isIntOrIntVectorTy() ||
-            LHS->getType()->isFPOrFPVectorTy();
-    break;
-  case 1: 
-    Valid = LHS->getType()->isIntOrIntVectorTy(); 
-    break;
-  case 2: 
-    Valid = LHS->getType()->isFPOrFPVectorTy(); 
-    break;
-  }
+  bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy()
+                    : LHS->getType()->isIntOrIntVectorTy();
 
   if (!Valid)
     return Error(Loc, "invalid operand type for instruction");
@@ -6185,6 +6308,124 @@
   return false;
 }
 
+/// ParseCallBr
+///   ::= 'callbr' OptionalCallingConv OptionalAttrs Type Value ParamList
+///       OptionalAttrs OptionalOperandBundles 'to' TypeAndValue
+///       '[' LabelList ']'
+bool LLParser::ParseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
+  LocTy CallLoc = Lex.getLoc();
+  AttrBuilder RetAttrs, FnAttrs;
+  std::vector<unsigned> FwdRefAttrGrps;
+  LocTy NoBuiltinLoc;
+  unsigned CC;
+  Type *RetType = nullptr;
+  LocTy RetTypeLoc;
+  ValID CalleeID;
+  SmallVector<ParamInfo, 16> ArgList;
+  SmallVector<OperandBundleDef, 2> BundleList;
+
+  BasicBlock *DefaultDest;
+  if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) ||
+      ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
+      ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) ||
+      ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+                                 NoBuiltinLoc) ||
+      ParseOptionalOperandBundles(BundleList, PFS) ||
+      ParseToken(lltok::kw_to, "expected 'to' in callbr") ||
+      ParseTypeAndBasicBlock(DefaultDest, PFS) ||
+      ParseToken(lltok::lsquare, "expected '[' in callbr"))
+    return true;
+
+  // Parse the destination list.
+  SmallVector<BasicBlock *, 16> IndirectDests;
+
+  if (Lex.getKind() != lltok::rsquare) {
+    BasicBlock *DestBB;
+    if (ParseTypeAndBasicBlock(DestBB, PFS))
+      return true;
+    IndirectDests.push_back(DestBB);
+
+    while (EatIfPresent(lltok::comma)) {
+      if (ParseTypeAndBasicBlock(DestBB, PFS))
+        return true;
+      IndirectDests.push_back(DestBB);
+    }
+  }
+
+  if (ParseToken(lltok::rsquare, "expected ']' at end of block list"))
+    return true;
+
+  // If RetType is a non-function pointer type, then this is the short syntax
+  // for the call, which means that RetType is just the return type.  Infer the
+  // rest of the function argument types from the arguments that are present.
+  FunctionType *Ty = dyn_cast<FunctionType>(RetType);
+  if (!Ty) {
+    // Pull out the types of all of the arguments...
+    std::vector<Type *> ParamTypes;
+    for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
+      ParamTypes.push_back(ArgList[i].V->getType());
+
+    if (!FunctionType::isValidReturnType(RetType))
+      return Error(RetTypeLoc, "Invalid result type for LLVM function");
+
+    Ty = FunctionType::get(RetType, ParamTypes, false);
+  }
+
+  CalleeID.FTy = Ty;
+
+  // Look up the callee.
+  Value *Callee;
+  if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS,
+                          /*IsCall=*/true))
+    return true;
+
+  if (isa<InlineAsm>(Callee) && !Ty->getReturnType()->isVoidTy())
+    return Error(RetTypeLoc, "asm-goto outputs not supported");
+
+  // Set up the Attribute for the function.
+  SmallVector<Value *, 8> Args;
+  SmallVector<AttributeSet, 8> ArgAttrs;
+
+  // Loop through FunctionType's arguments and ensure they are specified
+  // correctly.  Also, gather any parameter attributes.
+  FunctionType::param_iterator I = Ty->param_begin();
+  FunctionType::param_iterator E = Ty->param_end();
+  for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
+    Type *ExpectedTy = nullptr;
+    if (I != E) {
+      ExpectedTy = *I++;
+    } else if (!Ty->isVarArg()) {
+      return Error(ArgList[i].Loc, "too many arguments specified");
+    }
+
+    if (ExpectedTy && ExpectedTy != ArgList[i].V->getType())
+      return Error(ArgList[i].Loc, "argument is not of expected type '" +
+                                       getTypeString(ExpectedTy) + "'");
+    Args.push_back(ArgList[i].V);
+    ArgAttrs.push_back(ArgList[i].Attrs);
+  }
+
+  if (I != E)
+    return Error(CallLoc, "not enough parameters specified for call");
+
+  if (FnAttrs.hasAlignmentAttr())
+    return Error(CallLoc, "callbr instructions may not have an alignment");
+
+  // Finish off the Attribute and check them
+  AttributeList PAL =
+      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs),
+                         AttributeSet::get(Context, RetAttrs), ArgAttrs);
+
+  CallBrInst *CBI =
+      CallBrInst::Create(Ty, Callee, DefaultDest, IndirectDests, Args,
+                         BundleList);
+  CBI->setCallingConv(CC);
+  CBI->setAttributes(PAL);
+  ForwardRefAttrGroups[CBI] = FwdRefAttrGrps;
+  Inst = CBI;
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // Binary Operators.
 //===----------------------------------------------------------------------===//
@@ -6192,26 +6433,18 @@
 /// ParseArithmetic
 ///  ::= ArithmeticOps TypeAndValue ',' Value
 ///
-/// If OperandType is 0, then any FP or integer operand is allowed.  If it is 1,
-/// then any integer operand is allowed, if it is 2, any fp operand is allowed.
+/// If IsFP is false, then any integer operand is allowed, if it is true, any fp
+/// operand is allowed.
 bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
-                               unsigned Opc, unsigned OperandType) {
+                               unsigned Opc, bool IsFP) {
   LocTy Loc; Value *LHS, *RHS;
   if (ParseTypeAndValue(LHS, Loc, PFS) ||
       ParseToken(lltok::comma, "expected ',' in arithmetic operation") ||
       ParseValue(LHS->getType(), RHS, PFS))
     return true;
 
-  bool Valid;
-  switch (OperandType) {
-  default: llvm_unreachable("Unknown operand type!");
-  case 0: // int or FP.
-    Valid = LHS->getType()->isIntOrIntVectorTy() ||
-            LHS->getType()->isFPOrFPVectorTy();
-    break;
-  case 1: Valid = LHS->getType()->isIntOrIntVectorTy(); break;
-  case 2: Valid = LHS->getType()->isFPOrFPVectorTy(); break;
-  }
+  bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy()
+                    : LHS->getType()->isIntOrIntVectorTy();
 
   if (!Valid)
     return Error(Loc, "invalid operand type for instruction");
@@ -6816,6 +7049,7 @@
   AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
   SyncScope::ID SSID = SyncScope::System;
   bool isVolatile = false;
+  bool IsFP = false;
   AtomicRMWInst::BinOp Operation;
 
   if (EatIfPresent(lltok::kw_volatile))
@@ -6834,6 +7068,14 @@
   case lltok::kw_min: Operation = AtomicRMWInst::Min; break;
   case lltok::kw_umax: Operation = AtomicRMWInst::UMax; break;
   case lltok::kw_umin: Operation = AtomicRMWInst::UMin; break;
+  case lltok::kw_fadd:
+    Operation = AtomicRMWInst::FAdd;
+    IsFP = true;
+    break;
+  case lltok::kw_fsub:
+    Operation = AtomicRMWInst::FSub;
+    IsFP = true;
+    break;
   }
   Lex.Lex();  // Eat the operation.
 
@@ -6850,10 +7092,25 @@
   if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
     return Error(ValLoc, "atomicrmw value and pointer type do not match");
 
-  if (!Val->getType()->isIntegerTy()) {
-    return Error(ValLoc, "atomicrmw " +
-                 AtomicRMWInst::getOperationName(Operation) +
-                 " operand must be an integer");
+  if (Operation == AtomicRMWInst::Xchg) {
+    if (!Val->getType()->isIntegerTy() &&
+        !Val->getType()->isFloatingPointTy()) {
+      return Error(ValLoc, "atomicrmw " +
+                   AtomicRMWInst::getOperationName(Operation) +
+                   " operand must be an integer or floating point type");
+    }
+  } else if (IsFP) {
+    if (!Val->getType()->isFloatingPointTy()) {
+      return Error(ValLoc, "atomicrmw " +
+                   AtomicRMWInst::getOperationName(Operation) +
+                   " operand must be a floating point type");
+    }
+  } else {
+    if (!Val->getType()->isIntegerTy()) {
+      return Error(ValLoc, "atomicrmw " +
+                   AtomicRMWInst::getOperationName(Operation) +
+                   " operand must be an integer");
+    }
   }
 
   unsigned Size = Val->getType()->getPrimitiveSizeInBits();
@@ -7249,6 +7506,92 @@
   return false;
 }
 
+static ValueInfo EmptyVI =
+    ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8);
+
+/// TypeIdCompatibleVtableEntry
+///   ::= 'typeidCompatibleVTable' ':' '(' 'name' ':' STRINGCONSTANT ','
+///   TypeIdCompatibleVtableInfo
+///   ')'
+bool LLParser::ParseTypeIdCompatibleVtableEntry(unsigned ID) {
+  assert(Lex.getKind() == lltok::kw_typeidCompatibleVTable);
+  Lex.Lex();
+
+  std::string Name;
+  if (ParseToken(lltok::colon, "expected ':' here") ||
+      ParseToken(lltok::lparen, "expected '(' here") ||
+      ParseToken(lltok::kw_name, "expected 'name' here") ||
+      ParseToken(lltok::colon, "expected ':' here") ||
+      ParseStringConstant(Name))
+    return true;
+
+  TypeIdCompatibleVtableInfo &TI =
+      Index->getOrInsertTypeIdCompatibleVtableSummary(Name);
+  if (ParseToken(lltok::comma, "expected ',' here") ||
+      ParseToken(lltok::kw_summary, "expected 'summary' here") ||
+      ParseToken(lltok::colon, "expected ':' here") ||
+      ParseToken(lltok::lparen, "expected '(' here"))
+    return true;
+
+  IdToIndexMapType IdToIndexMap;
+  // Parse each call edge
+  do {
+    uint64_t Offset;
+    if (ParseToken(lltok::lparen, "expected '(' here") ||
+        ParseToken(lltok::kw_offset, "expected 'offset' here") ||
+        ParseToken(lltok::colon, "expected ':' here") || ParseUInt64(Offset) ||
+        ParseToken(lltok::comma, "expected ',' here"))
+      return true;
+
+    LocTy Loc = Lex.getLoc();
+    unsigned GVId;
+    ValueInfo VI;
+    if (ParseGVReference(VI, GVId))
+      return true;
+
+    // Keep track of the TypeIdCompatibleVtableInfo array index needing a
+    // forward reference. We will save the location of the ValueInfo needing an
+    // update, but can only do so once the std::vector is finalized.
+    if (VI == EmptyVI)
+      IdToIndexMap[GVId].push_back(std::make_pair(TI.size(), Loc));
+    TI.push_back({Offset, VI});
+
+    if (ParseToken(lltok::rparen, "expected ')' in call"))
+      return true;
+  } while (EatIfPresent(lltok::comma));
+
+  // Now that the TI vector is finalized, it is safe to save the locations
+  // of any forward GV references that need updating later.
+  for (auto I : IdToIndexMap) {
+    for (auto P : I.second) {
+      assert(TI[P.first].VTableVI == EmptyVI &&
+             "Forward referenced ValueInfo expected to be empty");
+      auto FwdRef = ForwardRefValueInfos.insert(std::make_pair(
+          I.first, std::vector<std::pair<ValueInfo *, LocTy>>()));
+      FwdRef.first->second.push_back(
+          std::make_pair(&TI[P.first].VTableVI, P.second));
+    }
+  }
+
+  if (ParseToken(lltok::rparen, "expected ')' here") ||
+      ParseToken(lltok::rparen, "expected ')' here"))
+    return true;
+
+  // Check if this ID was forward referenced, and if so, update the
+  // corresponding GUIDs.
+  auto FwdRefTIDs = ForwardRefTypeIds.find(ID);
+  if (FwdRefTIDs != ForwardRefTypeIds.end()) {
+    for (auto TIDRef : FwdRefTIDs->second) {
+      assert(!*TIDRef.first &&
+             "Forward referenced type id GUID expected to be 0");
+      *TIDRef.first = GlobalValue::getGUID(Name);
+    }
+    ForwardRefTypeIds.erase(FwdRefTIDs);
+  }
+
+  return false;
+}
+
 /// TypeTestResolution
 ///   ::= 'typeTestRes' ':' '(' 'kind' ':'
 ///         ( 'unsat' | 'byteArray' | 'inline' | 'single' | 'allOnes' ) ','
@@ -7523,9 +7866,13 @@
 
 static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) {
   bool ReadOnly = Fwd->isReadOnly();
+  bool WriteOnly = Fwd->isWriteOnly();
+  assert(!(ReadOnly && WriteOnly));
   *Fwd = Resolved;
   if (ReadOnly)
     Fwd->setReadOnly();
+  if (WriteOnly)
+    Fwd->setWriteOnly();
 }
 
 /// Stores the given Name/GUID and associated summary into the Index.
@@ -7554,10 +7901,6 @@
     }
   }
 
-  // Add the summary if one was provided.
-  if (Summary)
-    Index->addGlobalValueSummary(VI, std::move(Summary));
-
   // Resolve forward references from calls/refs
   auto FwdRefVIs = ForwardRefValueInfos.find(ID);
   if (FwdRefVIs != ForwardRefValueInfos.end()) {
@@ -7575,11 +7918,16 @@
     for (auto AliaseeRef : FwdRefAliasees->second) {
       assert(!AliaseeRef.first->hasAliasee() &&
              "Forward referencing alias already has aliasee");
-      AliaseeRef.first->setAliasee(VI.getSummaryList().front().get());
+      assert(Summary && "Aliasee must be a definition");
+      AliaseeRef.first->setAliasee(VI, Summary.get());
     }
     ForwardRefAliasees.erase(FwdRefAliasees);
   }
 
+  // Add the summary if one was provided.
+  if (Summary)
+    Index->addGlobalValueSummary(VI, std::move(Summary));
+
   // Save the associated ValueInfo for use in later references by ID.
   if (ID == NumberedValueInfos.size())
     NumberedValueInfos.push_back(VI);
@@ -7683,7 +8031,7 @@
   StringRef ModulePath;
   GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
       /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
-      /*Live=*/false, /*IsLocal=*/false);
+      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
   unsigned InstCount;
   std::vector<FunctionSummary::EdgeTy> Calls;
   FunctionSummary::TypeIdInfo TypeIdInfo;
@@ -7753,9 +8101,11 @@
   StringRef ModulePath;
   GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
       /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
-      /*Live=*/false, /*IsLocal=*/false);
-  GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false);
+      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
+  GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
+                                        /* WriteOnly */ false);
   std::vector<ValueInfo> Refs;
+  VTableFuncList VTableFuncs;
   if (ParseToken(lltok::colon, "expected ':' here") ||
       ParseToken(lltok::lparen, "expected '(' here") ||
       ParseModuleReference(ModulePath) ||
@@ -7764,10 +8114,20 @@
       ParseGVarFlags(GVarFlags))
     return true;
 
-  // Parse optional refs field
-  if (EatIfPresent(lltok::comma)) {
-    if (ParseOptionalRefs(Refs))
-      return true;
+  // Parse optional fields
+  while (EatIfPresent(lltok::comma)) {
+    switch (Lex.getKind()) {
+    case lltok::kw_vTableFuncs:
+      if (ParseOptionalVTableFuncs(VTableFuncs))
+        return true;
+      break;
+    case lltok::kw_refs:
+      if (ParseOptionalRefs(Refs))
+        return true;
+      break;
+    default:
+      return Error(Lex.getLoc(), "expected optional variable summary field");
+    }
   }
 
   if (ParseToken(lltok::rparen, "expected ')' here"))
@@ -7777,6 +8137,7 @@
       llvm::make_unique<GlobalVarSummary>(GVFlags, GVarFlags, std::move(Refs));
 
   GS->setModulePath(ModulePath);
+  GS->setVTableFuncs(std::move(VTableFuncs));
 
   AddGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
                         ID, std::move(GS));
@@ -7796,7 +8157,7 @@
   StringRef ModulePath;
   GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
       /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
-      /*Live=*/false, /*IsLocal=*/false);
+      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
   if (ParseToken(lltok::colon, "expected ':' here") ||
       ParseToken(lltok::lparen, "expected '(' here") ||
       ParseModuleReference(ModulePath) ||
@@ -7823,8 +8184,11 @@
     auto FwdRef = ForwardRefAliasees.insert(
         std::make_pair(GVId, std::vector<std::pair<AliasSummary *, LocTy>>()));
     FwdRef.first->second.push_back(std::make_pair(AS.get(), Loc));
-  } else
-    AS->setAliasee(AliaseeVI.getSummaryList().front().get());
+  } else {
+    auto Summary = Index->findSummaryInModule(AliaseeVI, ModulePath);
+    assert(Summary && "Aliasee must be a definition");
+    AS->setAliasee(AliaseeVI, Summary);
+  }
 
   AddGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
                         ID, std::move(AS));
@@ -7856,7 +8220,7 @@
     return true;
 
   do {
-    unsigned Val;
+    unsigned Val = 0;
     switch (Lex.getKind()) {
     case lltok::kw_readNone:
       Lex.Lex();
@@ -7994,6 +8358,67 @@
   return false;
 }
 
+/// OptionalVTableFuncs
+///   := 'vTableFuncs' ':' '(' VTableFunc [',' VTableFunc]* ')'
+/// VTableFunc ::= '(' 'virtFunc' ':' GVReference ',' 'offset' ':' UInt64 ')'
+bool LLParser::ParseOptionalVTableFuncs(VTableFuncList &VTableFuncs) {
+  assert(Lex.getKind() == lltok::kw_vTableFuncs);
+  Lex.Lex();
+
+  if (ParseToken(lltok::colon, "expected ':' in vTableFuncs") |
+      ParseToken(lltok::lparen, "expected '(' in vTableFuncs"))
+    return true;
+
+  IdToIndexMapType IdToIndexMap;
+  // Parse each virtual function pair
+  do {
+    ValueInfo VI;
+    if (ParseToken(lltok::lparen, "expected '(' in vTableFunc") ||
+        ParseToken(lltok::kw_virtFunc, "expected 'callee' in vTableFunc") ||
+        ParseToken(lltok::colon, "expected ':'"))
+      return true;
+
+    LocTy Loc = Lex.getLoc();
+    unsigned GVId;
+    if (ParseGVReference(VI, GVId))
+      return true;
+
+    uint64_t Offset;
+    if (ParseToken(lltok::comma, "expected comma") ||
+        ParseToken(lltok::kw_offset, "expected offset") ||
+        ParseToken(lltok::colon, "expected ':'") || ParseUInt64(Offset))
+      return true;
+
+    // Keep track of the VTableFuncs array index needing a forward reference.
+    // We will save the location of the ValueInfo needing an update, but
+    // can only do so once the std::vector is finalized.
+    if (VI == EmptyVI)
+      IdToIndexMap[GVId].push_back(std::make_pair(VTableFuncs.size(), Loc));
+    VTableFuncs.push_back({VI, Offset});
+
+    if (ParseToken(lltok::rparen, "expected ')' in vTableFunc"))
+      return true;
+  } while (EatIfPresent(lltok::comma));
+
+  // Now that the VTableFuncs vector is finalized, it is safe to save the
+  // locations of any forward GV references that need updating later.
+  for (auto I : IdToIndexMap) {
+    for (auto P : I.second) {
+      assert(VTableFuncs[P.first].FuncVI == EmptyVI &&
+             "Forward referenced ValueInfo expected to be empty");
+      auto FwdRef = ForwardRefValueInfos.insert(std::make_pair(
+          I.first, std::vector<std::pair<ValueInfo *, LocTy>>()));
+      FwdRef.first->second.push_back(
+          std::make_pair(&VTableFuncs[P.first].FuncVI, P.second));
+    }
+  }
+
+  if (ParseToken(lltok::rparen, "expected ')' in vTableFuncs"))
+    return true;
+
+  return false;
+}
+
 /// OptionalRefs
 ///   := 'refs' ':' '(' GVReference [',' GVReference]* ')'
 bool LLParser::ParseOptionalRefs(std::vector<ValueInfo> &Refs) {
@@ -8019,10 +8444,11 @@
     VContexts.push_back(VC);
   } while (EatIfPresent(lltok::comma));
 
-  // Sort value contexts so that ones with readonly ValueInfo are at the end
-  // of VContexts vector. This is needed to match immutableRefCount() behavior.
+  // Sort value contexts so that ones with writeonly
+  // and readonly ValueInfo  are at the end of VContexts vector.
+  // See FunctionSummary::specialRefCounts()
   llvm::sort(VContexts, [](const ValueContext &VC1, const ValueContext &VC2) {
-    return VC1.VI.isReadOnly() < VC2.VI.isReadOnly();
+    return VC1.VI.getAccessSpecifier() < VC2.VI.getAccessSpecifier();
   });
 
   IdToIndexMapType IdToIndexMap;
@@ -8283,41 +8709,55 @@
 /// GVFlags
 ///   ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ','
 ///         'notEligibleToImport' ':' Flag ',' 'live' ':' Flag ','
-///         'dsoLocal' ':' Flag ')'
+///         'dsoLocal' ':' Flag ',' 'canAutoHide' ':' Flag ')'
 bool LLParser::ParseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
   assert(Lex.getKind() == lltok::kw_flags);
   Lex.Lex();
 
-  bool HasLinkage;
   if (ParseToken(lltok::colon, "expected ':' here") ||
-      ParseToken(lltok::lparen, "expected '(' here") ||
-      ParseToken(lltok::kw_linkage, "expected 'linkage' here") ||
-      ParseToken(lltok::colon, "expected ':' here"))
-    return true;
-
-  GVFlags.Linkage = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
-  assert(HasLinkage && "Linkage not optional in summary entry");
-  Lex.Lex();
-
-  unsigned Flag;
-  if (ParseToken(lltok::comma, "expected ',' here") ||
-      ParseToken(lltok::kw_notEligibleToImport,
-                 "expected 'notEligibleToImport' here") ||
-      ParseToken(lltok::colon, "expected ':' here") || ParseFlag(Flag))
-    return true;
-  GVFlags.NotEligibleToImport = Flag;
-
-  if (ParseToken(lltok::comma, "expected ',' here") ||
-      ParseToken(lltok::kw_live, "expected 'live' here") ||
-      ParseToken(lltok::colon, "expected ':' here") || ParseFlag(Flag))
+      ParseToken(lltok::lparen, "expected '(' here"))
     return true;
-  GVFlags.Live = Flag;
 
-  if (ParseToken(lltok::comma, "expected ',' here") ||
-      ParseToken(lltok::kw_dsoLocal, "expected 'dsoLocal' here") ||
-      ParseToken(lltok::colon, "expected ':' here") || ParseFlag(Flag))
-    return true;
-  GVFlags.DSOLocal = Flag;
+  do {
+    unsigned Flag = 0;
+    switch (Lex.getKind()) {
+    case lltok::kw_linkage:
+      Lex.Lex();
+      if (ParseToken(lltok::colon, "expected ':'"))
+        return true;
+      bool HasLinkage;
+      GVFlags.Linkage = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
+      assert(HasLinkage && "Linkage not optional in summary entry");
+      Lex.Lex();
+      break;
+    case lltok::kw_notEligibleToImport:
+      Lex.Lex();
+      if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag))
+        return true;
+      GVFlags.NotEligibleToImport = Flag;
+      break;
+    case lltok::kw_live:
+      Lex.Lex();
+      if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag))
+        return true;
+      GVFlags.Live = Flag;
+      break;
+    case lltok::kw_dsoLocal:
+      Lex.Lex();
+      if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag))
+        return true;
+      GVFlags.DSOLocal = Flag;
+      break;
+    case lltok::kw_canAutoHide:
+      Lex.Lex();
+      if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag))
+        return true;
+      GVFlags.CanAutoHide = Flag;
+      break;
+    default:
+      return Error(Lex.getLoc(), "expected gv flag type");
+    }
+  } while (EatIfPresent(lltok::comma));
 
   if (ParseToken(lltok::rparen, "expected ')' here"))
     return true;
@@ -8326,24 +8766,41 @@
 }
 
 /// GVarFlags
-///   ::= 'varFlags' ':' '(' 'readonly' ':' Flag ')'
+///   ::= 'varFlags' ':' '(' 'readonly' ':' Flag
+///                      ',' 'writeonly' ':' Flag ')'
 bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
   assert(Lex.getKind() == lltok::kw_varFlags);
   Lex.Lex();
 
-  unsigned Flag;
   if (ParseToken(lltok::colon, "expected ':' here") ||
-      ParseToken(lltok::lparen, "expected '(' here") ||
-      ParseToken(lltok::kw_readonly, "expected 'readonly' here") ||
-      ParseToken(lltok::colon, "expected ':' here"))
+      ParseToken(lltok::lparen, "expected '(' here"))
     return true;
 
-  ParseFlag(Flag);
-  GVarFlags.ReadOnly = Flag;
+  auto ParseRest = [this](unsigned int &Val) {
+    Lex.Lex();
+    if (ParseToken(lltok::colon, "expected ':'"))
+      return true;
+    return ParseFlag(Val);
+  };
 
-  if (ParseToken(lltok::rparen, "expected ')' here"))
-    return true;
-  return false;
+  do {
+    unsigned Flag = 0;
+    switch (Lex.getKind()) {
+    case lltok::kw_readonly:
+      if (ParseRest(Flag))
+        return true;
+      GVarFlags.MaybeReadOnly = Flag;
+      break;
+    case lltok::kw_writeonly:
+      if (ParseRest(Flag))
+        return true;
+      GVarFlags.MaybeWriteOnly = Flag;
+      break;
+    default:
+      return Error(Lex.getLoc(), "expected gvar flag type");
+    }
+  } while (EatIfPresent(lltok::comma));
+  return ParseToken(lltok::rparen, "expected ')' here");
 }
 
 /// ModuleReference
@@ -8366,7 +8823,9 @@
 /// GVReference
 ///   ::= SummaryID
 bool LLParser::ParseGVReference(ValueInfo &VI, unsigned &GVId) {
-  bool ReadOnly = EatIfPresent(lltok::kw_readonly);
+  bool WriteOnly = false, ReadOnly = EatIfPresent(lltok::kw_readonly);
+  if (!ReadOnly)
+    WriteOnly = EatIfPresent(lltok::kw_writeonly);
   if (ParseToken(lltok::SummaryID, "expected GV ID"))
     return true;
 
@@ -8381,5 +8840,7 @@
 
   if (ReadOnly)
     VI.setReadOnly();
+  if (WriteOnly)
+    VI.setWriteOnly();
   return false;
 }
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/LLParser.h llvm-9.0.0.src/lib/AsmParser/LLParser.h
--- llvm-8.0.0.src/lib/AsmParser/LLParser.h	2019-10-24 23:46:14.587851285 +0200
+++ llvm-9.0.0.src/lib/AsmParser/LLParser.h	2019-07-02 21:38:02.000000000 +0200
@@ -1,9 +1,8 @@
 //===-- LLParser.h - Parser Class -------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -340,6 +339,7 @@
     bool ParseFnAttributeValuePairs(AttrBuilder &B,
                                     std::vector<unsigned> &FwdRefAttrGrps,
                                     bool inAttrGrp, LocTy &BuiltinLoc);
+    bool ParseByValWithOptionalType(Type *&Result);
 
     // Module Summary Index Parsing.
     bool SkipModuleSummaryEntry();
@@ -369,9 +369,11 @@
                          IdToIndexMapType &IdToIndexMap, unsigned Index);
     bool ParseVFuncId(FunctionSummary::VFuncId &VFuncId,
                       IdToIndexMapType &IdToIndexMap, unsigned Index);
+    bool ParseOptionalVTableFuncs(VTableFuncList &VTableFuncs);
     bool ParseOptionalRefs(std::vector<ValueInfo> &Refs);
     bool ParseTypeIdEntry(unsigned ID);
     bool ParseTypeIdSummary(TypeIdSummary &TIS);
+    bool ParseTypeIdCompatibleVtableEntry(unsigned ID);
     bool ParseTypeTestResolution(TypeTestResolution &TTRes);
     bool ParseOptionalWpdResolutions(
         std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap);
@@ -446,7 +448,7 @@
       /// DefineBB - Define the specified basic block, which is either named or
       /// unnamed.  If there is an error, this returns null otherwise it returns
       /// the block being defined.
-      BasicBlock *DefineBB(const std::string &Name, LocTy Loc);
+      BasicBlock *DefineBB(const std::string &Name, int NameID, LocTy Loc);
 
       bool resolveForwardRefBlockAddresses();
     };
@@ -571,11 +573,12 @@
     bool ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS);
     bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS);
     bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS);
+    bool ParseCallBr(Instruction *&Inst, PerFunctionState &PFS);
 
     bool ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
-                      unsigned OperandType);
+                      bool IsFP);
     bool ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
-                         unsigned OperandType);
+                         bool IsFP);
     bool ParseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
     bool ParseCompare(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
     bool ParseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/LLToken.h llvm-9.0.0.src/lib/AsmParser/LLToken.h
--- llvm-8.0.0.src/lib/AsmParser/LLToken.h	2019-10-24 23:46:14.587851285 +0200
+++ llvm-9.0.0.src/lib/AsmParser/LLToken.h	2019-07-15 22:02:23.000000000 +0200
@@ -1,9 +1,8 @@
 //===- LLToken.h - Token Codes for LLVM Assembly Files ----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -38,6 +37,7 @@
   bar,     // |
   colon,   // :
 
+  kw_vscale,
   kw_x,
   kw_true,
   kw_false,
@@ -114,6 +114,7 @@
   kw_align,
   kw_addrspace,
   kw_section,
+  kw_partition,
   kw_alias,
   kw_ifunc,
   kw_module,
@@ -175,6 +176,7 @@
   kw_argmemonly,
   kw_sanitize_address,
   kw_sanitize_hwaddress,
+  kw_sanitize_memtag,
   kw_builtin,
   kw_byval,
   kw_inalloca,
@@ -194,6 +196,7 @@
   kw_nobuiltin,
   kw_nocapture,
   kw_noduplicate,
+  kw_nofree,
   kw_noimplicitfloat,
   kw_noinline,
   kw_norecurse,
@@ -201,6 +204,7 @@
   kw_nonnull,
   kw_noredzone,
   kw_noreturn,
+  kw_nosync,
   kw_nocf_check,
   kw_nounwind,
   kw_optforfuzzing,
@@ -225,8 +229,10 @@
   kw_swifterror,
   kw_swiftself,
   kw_uwtable,
+  kw_willreturn,
   kw_writeonly,
   kw_zeroext,
+  kw_immarg,
 
   kw_type,
   kw_opaque,
@@ -328,6 +334,7 @@
   kw_catchret,
   kw_catchpad,
   kw_cleanuppad,
+  kw_callbr,
 
   kw_alloca,
   kw_load,
@@ -363,6 +370,7 @@
   kw_notEligibleToImport,
   kw_live,
   kw_dsoLocal,
+  kw_canAutoHide,
   kw_function,
   kw_insts,
   kw_funcFlags,
@@ -379,6 +387,8 @@
   kw_critical,
   kw_relbf,
   kw_variable,
+  kw_vTableFuncs,
+  kw_virtFunc,
   kw_aliasee,
   kw_refs,
   kw_typeIdInfo,
@@ -391,6 +401,7 @@
   kw_offset,
   kw_args,
   kw_typeid,
+  kw_typeidCompatibleVTable,
   kw_summary,
   kw_typeTestRes,
   kw_kind,
@@ -421,6 +432,7 @@
   kw_varFlags,
 
   // Unsigned Valued tokens (UIntVal).
+  LabelID,    // 42:
   GlobalID,   // @42
   LocalVarID, // %42
   AttrGrpID,  // #42
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/LLVMBuild.txt llvm-9.0.0.src/lib/AsmParser/LLVMBuild.txt
--- llvm-8.0.0.src/lib/AsmParser/LLVMBuild.txt	2019-10-24 23:46:14.587851285 +0200
+++ llvm-9.0.0.src/lib/AsmParser/LLVMBuild.txt	2019-01-19 09:50:56.000000000 +0100
@@ -1,9 +1,8 @@
 ;===- ./lib/AsmParser/LLVMBuild.txt ----------------------------*- Conf -*--===;
 ;
-;                     The LLVM Compiler Infrastructure
-;
-; This file is distributed under the University of Illinois Open Source
-; License. See LICENSE.TXT for details.
+; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+; See https://llvm.org/LICENSE.txt for license information.
+; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 ;
 ;===------------------------------------------------------------------------===;
 ;
diff -u -r -u llvm-8.0.0.src/lib/AsmParser/Parser.cpp llvm-9.0.0.src/lib/AsmParser/Parser.cpp
--- llvm-8.0.0.src/lib/AsmParser/Parser.cpp	2019-10-24 23:46:14.591184619 +0200
+++ llvm-9.0.0.src/lib/AsmParser/Parser.cpp	2019-01-19 09:50:56.000000000 +0100
@@ -1,9 +1,8 @@
 //===- Parser.cpp - Main dispatch module for the Parser library -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //

New keywords:

  • partition
  • nofree
  • nosync
  • sanitize_memtag
  • willreturn
  • immarg
  • vscale

Part of issue #43.

  • canAutoHide
  • vTableFuncs
  • virtFunc
  • typeidCompatibleVTable
mewmew added a commit to llir/grammar that referenced this issue Oct 28, 2019
mewmew added a commit to llir/ll that referenced this issue Oct 28, 2019
mewmew added a commit that referenced this issue Oct 28, 2019
Introduced in LLVM 9.0.

Also, remove byval from ir/enum and regeneate asm/enum.

Updates #101.
@mewmew
Copy link
Member Author

mewmew commented Nov 1, 2019

The test cases have been updated to LLVM 9.0.

Any unable to parse "foo.ll" into AST; syntax error at line NN error denotes a test cases for which the LLVM IR grammar has changed. For these we need to update the llir/grammar/ll.tm grammar.

The currently failing test cases are reported below:

u@x220 ~/D/g/s/g/l/llvm> go test ./...
2019/10/31 19:47:52 === [ testdata/hexfloat.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_aggregate.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_binary.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_bitwise.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_conversion.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_memory.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_other.ll ] ===
2019/10/31 19:47:52 === [ testdata/inst_vector.ll ] ===
2019/10/31 19:47:52 === [ testdata/terminator.ll ] ===
2019/10/31 19:47:52 === [ testdata/diexpression.ll ] ===
2019/10/31 19:47:52 === [ testdata/multiple_named_metadata_defs.ll ] ===
2019/10/31 19:47:52 === [ testdata/expr_frem.ll ] ===
2019/10/31 19:47:52 === [ testdata/param_attrs.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Bitcode/compatibility.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Analysis/ScalarEvolution/2008-02-15-UMax.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Analysis/CostModel/AMDGPU/fdiv.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Analysis/BasicAA/pr18573.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Analysis/DominanceFrontier/new_pm_test.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Assembler/aggregate-constant-values.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Assembler/ConstantExprFold.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Assembler/getelementptr.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Assembler/ditype-large-values.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/DebugInfo/ARM/selectiondag-deadcode.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Transforms/InstCombine/fma.ll ] ===
--- FAIL: TestParseFile (0.01s)
    asm_test.go:533: unable to parse "../testdata/llvm/test/Bitcode/compatibility.ll" into AST; syntax error at line 164
        unable to parse "../testdata/llvm/test/Bitcode/compatibility.ll" into an AST
        github.com/llir/llvm/asm.ParseString
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:58
        github.com/llir/llvm/asm.ParseBytes
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:48
        github.com/llir/llvm/asm.ParseFile
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:29
        github.com/llir/llvm/asm.TestParseFile
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm_test.go:531
        testing.tRunner
        	/home/u/go/src/testing/testing.go:916
        runtime.goexit
        	/home/u/go/src/runtime/asm_amd64.s:1375
panic: support for AST value instruction type *ast.FNegInst not yet implemented [recovered]
	panic: support for AST value instruction type *ast.FNegInst not yet implemented

goroutine 7 [running]:
testing.tRunner.func1(0xc0000b2100)
	/home/u/go/src/testing/testing.go:881 +0x3a3
panic(0x663720, 0xc00024d7a0)
	/home/u/go/src/runtime/panic.go:909 +0x155
github.com/llir/llvm/asm.(*funcGen).newValueInst(0xc0000cbf30, 0xc000273152, 0x6, 0x0, 0x7f806c8119d8, 0xc000247ad0, 0x0, 0x2, 0x0, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/inst.go:148 +0x22db
github.com/llir/llvm/asm.(*funcGen).newInst(0xc0000cbf30, 0x74c160, 0xc000247ac0, 0xc0002a1700, 0xc0000cbd78, 0x9bf040, 0x7f806ea6f008)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/inst.go:20 +0x311
github.com/llir/llvm/asm.(*funcGen).newLocals(0xc0000cbf30, 0xc000247aa8, 0x1, 0x1, 0x0, 0x30)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/local.go:116 +0x31e
github.com/llir/llvm/asm.(*funcGen).createLocals(0xc0000cbf30, 0xc000247aa8, 0x1, 0x1, 0xc0000cbe50, 0x40c688)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/local.go:87 +0x50
github.com/llir/llvm/asm.(*funcGen).resolveLocals(0xc0000cbf30, 0xc000283180, 0xc000283180, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/local.go:56 +0x61
github.com/llir/llvm/asm.(*generator).irFuncDef(0xc000223380, 0xc0001f7900, 0xc000247020, 0xc00029adf8, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/global.go:409 +0x22a
github.com/llir/llvm/asm.(*generator).translateGlobalEntities(0xc000223380, 0x17dd5d8700502a1a, 0x5dbb2c58)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/global.go:200 +0x1ba
github.com/llir/llvm/asm.(*generator).translateTopLevelEntities(0xc000223380, 0xa60131, 0x9be600)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/module.go:271 +0x2f
github.com/llir/llvm/asm.translate(0xc000246fa8, 0x744ec0, 0xc000246fa8, 0x2)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/translate.go:132 +0x781
github.com/llir/llvm/asm.ParseString(0x6fbf27, 0x33, 0xc000272000, 0x3cc3, 0xc000272000, 0x3cc3, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:62 +0x187
github.com/llir/llvm/asm.ParseBytes(...)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:48
github.com/llir/llvm/asm.ParseFile(0x6fbf27, 0x33, 0xc0000cc460, 0x1, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:29 +0x13e
github.com/llir/llvm/asm.TestParseFile(0xc0000b2100)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm_test.go:531 +0x16d
testing.tRunner(0xc0000b2100, 0x707c80)
	/home/u/go/src/testing/testing.go:916 +0xc1
created by testing.(*T).Run
	/home/u/go/src/testing/testing.go:967 +0x351
FAIL	github.com/llir/llvm/asm	0.020s
?   	github.com/llir/llvm/asm/enum	[no test files]
?   	github.com/llir/llvm/cmd/l-ir	[no test files]
?   	github.com/llir/llvm/cmd/l-tm	[no test files]
ok  	github.com/llir/llvm/internal/enc	(cached)
ok  	github.com/llir/llvm/internal/natsort	(cached)
2019/10/31 19:47:52 === [ ../testdata/llvm/test/Bitcode/compatibility.ll ] ===
2019/10/31 19:47:52 === [ ../testdata/coreutils/test/cat.ll ] ===
--- FAIL: TestModule (0.35s)
    asm_test.go:36: unable to parse "../testdata/llvm/test/Bitcode/compatibility.ll" into AST; syntax error at line 164
        unable to parse "../testdata/llvm/test/Bitcode/compatibility.ll" into an AST
        github.com/llir/llvm/asm.ParseString
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:58
        github.com/llir/llvm/asm.ParseBytes
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:48
        github.com/llir/llvm/asm.ParseFile
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:29
        github.com/llir/llvm/ir_test.TestModule
        	/home/u/Desktop/go/src/github.com/llir/llvm/ir/asm_test.go:34
        testing.tRunner
        	/home/u/go/src/testing/testing.go:916
        runtime.goexit
        	/home/u/go/src/runtime/asm_amd64.s:1375
FAIL
FAIL	github.com/llir/llvm/ir	0.392s
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/Bitcode/compatibility.ll ] ===
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/Assembler/2002-04-07-HexFloatConstants.ll ] ===
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/Assembler/half-constprop.ll ] ===
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/Transforms/ConstProp/constant-expr.ll ] ===
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/Assembler/insertextractvalue.ll ] ===
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/DebugInfo/ARM/selectiondag-deadcode.ll ] ===
2019/10/31 19:47:52 === [ ../../testdata/llvm/test/Transforms/InstCombine/fma.ll ] ===
--- FAIL: TestModule (0.01s)
    asm_test.go:47: unable to parse "../../testdata/llvm/test/Bitcode/compatibility.ll" into AST; syntax error at line 164
        unable to parse "../../testdata/llvm/test/Bitcode/compatibility.ll" into an AST
        github.com/llir/llvm/asm.ParseString
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:58
        github.com/llir/llvm/asm.ParseBytes
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:48
        github.com/llir/llvm/asm.ParseFile
        	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:29
        github.com/llir/llvm/ir/constant_test.TestModule
        	/home/u/Desktop/go/src/github.com/llir/llvm/ir/constant/asm_test.go:45
        testing.tRunner
        	/home/u/go/src/testing/testing.go:916
        runtime.goexit
        	/home/u/go/src/runtime/asm_amd64.s:1375
panic: support for AST value instruction type *ast.FNegInst not yet implemented [recovered]
	panic: support for AST value instruction type *ast.FNegInst not yet implemented

goroutine 19 [running]:
testing.tRunner.func1(0xc0000da100)
	/home/u/go/src/testing/testing.go:881 +0x3a3
panic(0x65e480, 0xc000232480)
	/home/u/go/src/runtime/panic.go:909 +0x155
github.com/llir/llvm/asm.(*funcGen).newValueInst(0xc0001b1940, 0xc00020880e, 0x2, 0x0, 0x7f76c4c449f8, 0xc0001dfa78, 0x0, 0x2, 0x0, 0x2)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/inst.go:148 +0x22db
github.com/llir/llvm/asm.(*funcGen).newInst(0xc0001b1940, 0x73e3a0, 0xc0001dfa60, 0xc00023a330, 0xc0001b1788, 0x9acf60, 0x7f76c6ea56d0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/inst.go:20 +0x311
github.com/llir/llvm/asm.(*funcGen).newLocals(0xc0001b1940, 0xc0001dfa48, 0x1, 0x1, 0x0, 0x30)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/local.go:116 +0x31e
github.com/llir/llvm/asm.(*funcGen).createLocals(0xc0001b1940, 0xc0001dfa48, 0x1, 0x1, 0xc0001b1860, 0x40c688)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/local.go:87 +0x50
github.com/llir/llvm/asm.(*funcGen).resolveLocals(0xc0001b1940, 0xc000213a00, 0xc000213a00, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/local.go:56 +0x61
github.com/llir/llvm/asm.(*generator).irFuncDef(0xc000167380, 0xc00015b900, 0xc0001df080, 0xc0002364c8, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/global.go:409 +0x22a
github.com/llir/llvm/asm.(*generator).translateGlobalEntities(0xc000167380, 0x33d010c40050602a, 0x5dbb2c58)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/global.go:200 +0x1ba
github.com/llir/llvm/asm.(*generator).translateTopLevelEntities(0xc000167380, 0x5e6e2a, 0x9ac520)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/module.go:271 +0x2f
github.com/llir/llvm/asm.translate(0xc0001df030, 0x737160, 0xc0001df030, 0x2)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/translate.go:132 +0x781
github.com/llir/llvm/asm.ParseString(0x6f4535, 0x36, 0xc000208000, 0x3cc3, 0xc000208000, 0x3cc3, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:62 +0x187
github.com/llir/llvm/asm.ParseBytes(...)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:48
github.com/llir/llvm/asm.ParseFile(0x6f4535, 0x36, 0xc0001b1e70, 0x1, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:29 +0x13e
github.com/llir/llvm/ir/constant_test.TestModule(0xc0000da100)
	/home/u/Desktop/go/src/github.com/llir/llvm/ir/constant/asm_test.go:45 +0x288
testing.tRunner(0xc0000da100, 0x6fb430)
	/home/u/go/src/testing/testing.go:916 +0xc1
created by testing.(*T).Run
	/home/u/go/src/testing/testing.go:967 +0x351
FAIL	github.com/llir/llvm/ir/constant	0.021s
?   	github.com/llir/llvm/ir/enum	[no test files]
2019/10/31 19:47:53 === [ ../../testdata/llvm/test/Assembler/debug-info.ll ] ===
--- FAIL: TestModule (0.00s)
panic: unable to locate DIFlag enum corresponding to "DIFlagLittleEndian" [recovered]
	panic: unable to locate DIFlag enum corresponding to "DIFlagLittleEndian"

goroutine 19 [running]:
testing.tRunner.func1(0xc0000dc100)
	/home/u/go/src/testing/testing.go:881 +0x3a3
panic(0x65e480, 0xc000096610)
	/home/u/go/src/runtime/panic.go:909 +0x155
github.com/llir/llvm/asm/enum.DIFlagFromString(0xc0000fdd27, 0x12, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/enum/diflag_string.go:92 +0x17d
github.com/llir/llvm/asm.irDIFlag(0x73b720, 0xc0000ae700, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/specialized_metadata.go:1487 +0x171
github.com/llir/llvm/asm.irDIFlags(0xc00010be00, 0x6fb1e0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/specialized_metadata.go:1476 +0x7f
github.com/llir/llvm/asm.(*generator).irDIBasicType(0xc00009dd40, 0x744b20, 0xc0000d00f0, 0xc0000ae6b8, 0xc0000d00f0, 0xc0000ae6b8, 0x735860)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/specialized_metadata.go:103 +0x204
github.com/llir/llvm/asm.(*generator).irSpecializedMDNode(0xc00009dd40, 0x7f05da90a218, 0xc0000d00f0, 0x73b520, 0xc0000ae6b8, 0x745001, 0xc00010c780, 0x200000000000000, 0xffffffffffffffff)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/specialized_metadata.go:21 +0x175a
github.com/llir/llvm/asm.(*generator).irMetadataDef(0xc00009dd40, 0x7f05da90a218, 0xc0000d00f0, 0xc0000ae1a0, 0x1, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/module.go:394 +0xe7
github.com/llir/llvm/asm.(*generator).translateMetadataDefs(0xc00009dd40, 0x0, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/module.go:373 +0x111
github.com/llir/llvm/asm.(*generator).translateTopLevelEntities(0xc00009dd40, 0x240fd6, 0x9ab520)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/module.go:281 +0x19d
github.com/llir/llvm/asm.translate(0xc0000ae038, 0x736f20, 0xc0000ae038, 0x2)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/translate.go:132 +0x781
github.com/llir/llvm/asm.ParseString(0x6f32a3, 0x30, 0xc0000fc000, 0x1ef4, 0xc0000fc000, 0x1ef4, 0x0)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:62 +0x187
github.com/llir/llvm/asm.ParseBytes(...)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:48
github.com/llir/llvm/asm.ParseFile(0x6f32a3, 0x30, 0xc00004ef00, 0x1, 0x1)
	/home/u/Desktop/go/src/github.com/llir/llvm/asm/asm.go:29 +0x13e
github.com/llir/llvm/ir/metadata_test.TestModule(0xc0000dc100)
	/home/u/Desktop/go/src/github.com/llir/llvm/ir/metadata/asm_test.go:34 +0x186
testing.tRunner(0xc0000dc100, 0x6fb210)
	/home/u/go/src/testing/testing.go:916 +0xc1
created by testing.(*T).Run
	/home/u/go/src/testing/testing.go:967 +0x351
FAIL	github.com/llir/llvm/ir/metadata	0.007s
ok  	github.com/llir/llvm/ir/types	(cached)
?   	github.com/llir/llvm/ir/value	[no test files]
FAIL

@mewmew
Copy link
Member Author

mewmew commented Nov 1, 2019

The following new language concepts were introduced.

@g.partition = global i32 0, partition "part"
  %atomicrmw.fadd = atomicrmw fadd float* %word, float 1.0 monotonic
  %atomicrmw.fsub = atomicrmw fsub float* %word, float 1.0 monotonic
  %f.nnan = select nnan i1 %cond, float %op1, float %op2
  %t10 = alloca <vscale x 4 x i32>

mewmew added a commit to llir/grammar that referenced this issue Nov 1, 2019
mewmew added a commit to llir/grammar that referenced this issue Nov 1, 2019
mewmew added a commit to llir/grammar that referenced this issue Nov 1, 2019
mewmew added a commit to llir/grammar that referenced this issue Nov 1, 2019
mewmew added a commit to llir/grammar that referenced this issue Nov 1, 2019
@mewmew
Copy link
Member Author

mewmew commented Nov 1, 2019

Current set of test cases failing are as follows:

=== [ ../testdata/llvm/test/Bitcode/compatibility.ll ] ===

diff --git a/compatibility.ll.golden b/compatibility.ll.golden
index 757509e..1f1152e 100644
--- a/compatibility.ll.golden
+++ b/compatibility.ll.golden
@@ -67,7 +67,7 @@ $comdat2 = comdat any
 @g.addrspace = addrspace(1) global i32 0
 @g.externally_initialized = external externally_initialized global i32
 @g.section = global i32 0, section "_DATA"
-@g.partition = global i32 0, partition "part"
+@g.partition = global i32 0
 @comdat.any = global i32 0, comdat
 @comdat.exactmatch = global i32 0, comdat
 @comdat.largest = global i32 0, comdat
@@ -103,7 +103,7 @@ $comdat2 = comdat any
 @a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
 @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
 @a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr
-@alias.partition = alias i32, i32* @g.partition, partition "part"
+@alias.partition = alias i32, i32* @g.partition

 @ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver
 @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
@@ -111,7 +111,7 @@ $comdat2 = comdat any
 @ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver
 @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
 @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
-@ifunc.partition = ifunc void (), i8* ()* @ifunc_resolver, partition "part"
+@ifunc.partition = ifunc void (), i8* ()* @ifunc_resolver

 declare void @g.f1()

@@ -436,7 +436,7 @@ declare void @f.strictfp() #35

 declare void @f.section() section "80"

-define void @f.partition() partition "part" {
+define void @f.partition() {
 ; <label>:0
 	ret void
 }
@@ -578,21 +578,21 @@ define void @fastmathflags_binops(float %op1, float %op2) {

 define void @fastmathflags_select(i1 %cond, float %op1, float %op2) {
 ; <label>:0
-	%f.nnan = select nnan i1 %cond, float %op1, float %op2
-	%f.ninf = select ninf i1 %cond, float %op1, float %op2
-	%f.nsz = select nsz i1 %cond, float %op1, float %op2
-	%f.arcp = select arcp i1 %cond, float %op1, float %op2
-	%f.contract = select contract i1 %cond, float %op1, float %op2
-	%f.afn = select afn i1 %cond, float %op1, float %op2
-	%f.reassoc = select reassoc i1 %cond, float %op1, float %op2
-	%f.fast = select fast i1 %cond, float %op1, float %op2
+	%f.nnan = select i1 %cond, float %op1, float %op2
+	%f.ninf = select i1 %cond, float %op1, float %op2
+	%f.nsz = select i1 %cond, float %op1, float %op2
+	%f.arcp = select i1 %cond, float %op1, float %op2
+	%f.contract = select i1 %cond, float %op1, float %op2
+	%f.afn = select i1 %cond, float %op1, float %op2
+	%f.reassoc = select i1 %cond, float %op1, float %op2
+	%f.fast = select i1 %cond, float %op1, float %op2
 	ret void
 }

 define void @fastmathflags_vector_select(<2 x i1> %cond, <2 x double> %op1, <2 x double> %op2) {
 ; <label>:0
-	%f.nnan.nsz = select nnan nsz <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
-	%f.fast = select fast <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
+	%f.nnan.nsz = select <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
+	%f.fast = select <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
 	ret void
 }

@@ -1258,7 +1258,7 @@ define i8** @constexpr() {
 	ret i8** getelementptr inbounds ({ [4 x i8*], [4 x i8*] }, { [4 x i8*], [4 x i8*] }* null, i32 0, inrange i32 1, i32 2)
 }

-declare void @llvm.test.immarg.intrinsic(i32 immarg)
+declare void @llvm.test.immarg.intrinsic(i32)

 declare void @byval_type(i32* byval(i32) align 2)

=== [ ../testdata/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll ] ===

diff --git a/vec_demanded_elts.ll.golden b/vec_demanded_elts.ll.golden
index ac66f6a..729daa1 100644
--- a/vec_demanded_elts.ll.golden
+++ b/vec_demanded_elts.ll.golden
@@ -328,7 +328,7 @@ define <3 x float> @shuf_frem_const_op1(<3 x float> %x) {
 define i32* @gep_vbase_w_s_idx(<2 x i32*> %base) {
 ; <label>:0
 	%gep = getelementptr i32, <2 x i32*> %base, i64 1
-	%ee = extractelement <2 x i32*> %gep, i32 1
+	%ee = extractelement i32* %gep, i32 1
 	ret i32* %ee
 }

@@ -337,7 +337,7 @@ define i32* @gep_splat_base_w_s_idx(i32* %base) {
 	%basevec1 = insertelement <2 x i32*> undef, i32* %base, i32 0
 	%basevec2 = shufflevector <2 x i32*> %basevec1, <2 x i32*> undef, <2 x i32> zeroinitializer
 	%gep = getelementptr i32, <2 x i32*> %basevec2, i64 1
-	%ee = extractelement <2 x i32*> %gep, i32 1
+	%ee = extractelement i32* %gep, i32 1
 	ret i32* %ee
 }

@@ -362,7 +362,7 @@ define i32* @gep_splat_base_w_vidx(i32* %base, <2 x i64> %idxvec) {
 define i32* @gep_cvbase_w_s_idx(<2 x i32*> %base, i64 %raw_addr) {
 ; <label>:0
 	%gep = getelementptr i32, <2 x i32*> <i32* @GLOBAL, i32* @GLOBAL>, i64 %raw_addr
-	%ee = extractelement <2 x i32*> %gep, i32 1
+	%ee = extractelement i32* %gep, i32 1
 	ret i32* %ee
 }

=== [ ../testdata/llvm/test/Feature/fp-intrinsics.ll ] ===

diff --git a/fp-intrinsics.ll.golden b/fp-intrinsics.ll.golden
index 64bfe1d..417e8d7 100644
--- a/fp-intrinsics.ll.golden
+++ b/fp-intrinsics.ll.golden
@@ -114,7 +114,7 @@ entry:

 define float @f20() {
 entry:
-	%result = call float @llvm.experimental.constrained.fptrunc.f32.f64(double 42.1, metadata !"round.dynamic", metadata !"fpexcept.strict")
+	%result = call float @llvm.experimental.constrained.fptrunc.f32.f64(double 0x40450CCCCCCCCCCD, metadata !"round.dynamic", metadata !"fpexcept.strict")
 	ret float %result
 }

=== [ ../testdata/llvm/test/Assembler/call-nonzero-program-addrspace-2.ll ] ===

diff --git a/call-nonzero-program-addrspace-2.ll.golden b/call-nonzero-program-addrspace-2.ll.golden
index 84905da..6b0cb13 100644
--- a/call-nonzero-program-addrspace-2.ll.golden
+++ b/call-nonzero-program-addrspace-2.ll.golden
@@ -1,7 +1,7 @@
 define i8 @test_unnamed(i8 (i32)*, i8 (i32) addrspace(42)*) {
 define i8 @test_unnamed(i8 (i32)*, i8 (i32) addrspace(42)*) {
 ; <label>:2
 	%3 = call i8 %0(i32 0)
-	%4 = call addrspace(42) i8 %1(i32 0)
+	%4 = call i8 %1(i32 0)
 	%5 = call i8 %1(i32 0)
 	ret i8 0
 }

=== [ ../testdata/llvm/test/Assembler/call-nonzero-program-addrspace.ll ] ===

diff --git a/call-nonzero-program-addrspace.ll.golden b/call-nonzero-program-addrspace.ll.golden
index e34b8e1..da74225 100644
--- a/call-nonzero-program-addrspace.ll.golden
+++ b/call-nonzero-program-addrspace.ll.golden
@@ -1,7 +1,7 @@
 define i8 @test(i8 (i32)* %fnptr0, i8 (i32) addrspace(42)* %fnptr42) {
 define i8 @test(i8 (i32)* %fnptr0, i8 (i32) addrspace(42)* %fnptr42) {
 ; <label>:0
 	%explicit_as_0 = call i8 %fnptr0(i32 0)
-	%explicit_as_42 = call addrspace(42) i8 %fnptr42(i32 0)
+	%explicit_as_42 = call i8 %fnptr42(i32 0)
 	%call_no_as = call i8 %fnptr42(i32 0)
 	ret i8 0
 }

=== [ ../testdata/llvm/test/Assembler/invoke-nonzero-program-addrspace.ll ] ===

diff --git a/invoke-nonzero-program-addrspace.ll.golden b/invoke-nonzero-program-addrspace.ll.golden
index d183ac6..b835a23 100644
--- a/invoke-nonzero-program-addrspace.ll.golden
+++ b/invoke-nonzero-program-addrspace.ll.golden
@@ -1,20 +1,21 @@
-define i8 @test_invoke(i8 (i32)* %fnptr0, i8 (i32) addrspace(200)* %fnptr200) personality i32 (...) addrspace(200)* @__gxx_personality_v0 {
+define i8 @test_invoke(i8 (i32)* %fnptr0, i8 (i32) addrspace(200)* %fnptr200) personality i32 (...)* @__gxx_personality_v0 {
 ; <label>:0
 	%explicit_as_0 = invoke i8 %fnptr0(i32 0)
 		to label %ok unwind label %lpad

 ; <label>:1
-	%explicit_as_42 = invoke addrspace(200) i8 %fnptr200(i32 0)
+	%explicit_as_42 = invoke i8 %fnptr200(i32 0)
 		to label %ok unwind label %lpad

 ; <label>:2
 	%no_as = invoke i8 %fnptr200(i32 0)
 		to label %ok unwind label %lpad

 ok:
 	ret i8 0

 lpad:
 	%exn = landingpad {i8*, i32}
 	%exn = landingpad { i8*, i32 }
 		cleanup
 	unreachable
 }

mewmew added a commit that referenced this issue Nov 1, 2019
@mewmew
Copy link
Member Author

mewmew commented Nov 27, 2019

Anyone adventurous enough may consider themselves invited to take upon the challenge of updating the grammar to LLVM 9.0. @dannypsnl? :)

I've tried to reference commits to this issue that update the grammar for LLVM 9.0, so they may help out as a reference for what kind of changes that need to be done.

  • Update DISPFlag enum to LLVM 9.0:
  1. update ir/enum/enum.go (ref: c9a607e)
  2. run go generate in llir/llvm/ir
  3. run make in llir/llvm/asm
  • Add scalable vector type:
  1. update grammar (ref: llir/grammar@3b4b8e2)
  2. regenerate parser by running make in llir/ll
  3. update llir/llvm/ir/types package to handle optional Scalable boolean on vector type (ref: 47b379d) and add parsing logic for *ast.ScalableVectorType to llir/llvm/asm.

See other referenced commits of this issue for further examples.

And, if you need guidance when taking on this challenge, just reach out :)

Cheers,
Robin

Edit: related to this issue are also #105 and #106, which track the update of test cases and new language constructs for LLVM 9.0.

@mewmew mewmew added this to the v0.3 milestone Nov 27, 2019
mewmew added a commit to llir/grammar that referenced this issue Nov 27, 2019
@mewmew
Copy link
Member Author

mewmew commented Nov 28, 2019

For future reference, from #110 (comment)

As DwarfAttEncoding is now a valid DIExpressionField, we needed to update the AST to IR converter. This was done in commit: 5a787c4

For reference, prior to this commit, we got the following panic:

panic: support for DIExpression field *ast.DwarfAttEncodingEnum not yet implemented [recovered]

	panic: support for DIExpression field *ast.DwarfAttEncodingEnum not yet implemented

goroutine 18 [running]:

testing.tRunner.func1(0xc0000e0100)

	/home/travis/.gimme/versions/go1.12.linux.amd64/src/testing/testing.go:830 +0x388

panic(0x676460, 0xc0001b5270)

	/home/travis/.gimme/versions/go1.12.linux.amd64/src/runtime/panic.go:522 +0x1b5

github.com/llir/llvm/asm.(*generator).irDIExpressionField(0xc0001ac820, 0x7fcff94dc160, 0xc0001c2600, 0x1, 0x2, 0xc0001c1860, 0x1)

	/home/travis/gopath/src/github.com/llir/llvm/asm/specialized_metadata.go:493 +0x243

github.com/llir/llvm/asm.(*generator).irDIExpression(0xc0001ac820, 0x7689c0, 0xc0001d6060, 0xc0001c25e0, 0xc0001d6060, 0x67b800, 0x758b00)

mewmew added a commit to llir/grammar that referenced this issue Dec 5, 2019
mewmew added a commit to llir/grammar that referenced this issue Dec 5, 2019
@mewmew mewmew added the howto label Dec 5, 2019
@mewmew
Copy link
Member Author

mewmew commented Dec 5, 2019

llir/llvm now supports the language constructs of LLVM 9.0, and the grammar has been updated.

The only remaining concept is module summaries, which is tracked by the dedicated issue #43. Closing this issue in favour #43.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant