Fast-math flags for LLVM IR parsing and printing
authorMichael Ilseman <milseman@apple.com>
Tue, 27 Nov 2012 00:42:44 +0000 (00:42 +0000)
committerMichael Ilseman <milseman@apple.com>
Tue, 27 Nov 2012 00:42:44 +0000 (00:42 +0000)
Added in the ability to read LLVM IR text that contains fast-math flags as a sequence of capital letters separated by spaces in any order. Added in the printing of the fast-math flags in a canonical order, and don't print the other flags when 'fast' is specified, as 'fast' implies all the others.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168645 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h
lib/AsmParser/LLToken.h
lib/VMCore/AsmWriter.cpp

index d8ffe8fb7324119403dec6f0a7f0451315065e1b..eb176aefcb01e5541dd786e50fa9103b9db21535 100644 (file)
@@ -402,7 +402,7 @@ lltok::Kind LLLexer::LexExclaim() {
   }
   return lltok::exclaim;
 }
-  
+
 /// LexIdentifier: Handle several related productions:
 ///    Label           [-a-zA-Z$._0-9]+:
 ///    IntegerType     i[0-9]+
@@ -498,6 +498,11 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(seq_cst);
   KEYWORD(singlethread);
 
+  KEYWORD(nnan)
+  KEYWORD(ninf)
+  KEYWORD(nsz)
+  KEYWORD(arcp)
+  KEYWORD(fast)
   KEYWORD(nuw);
   KEYWORD(nsw);
   KEYWORD(exact);
index 41cca685769fede0f24009a182a80eeb30fece01..65f4245062265b017059cfc2b598c3132897fecb 100644 (file)
@@ -3012,7 +3012,17 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
   }
   case lltok::kw_fadd:
   case lltok::kw_fsub:
-  case lltok::kw_fmul:    return ParseArithmetic(Inst, PFS, KeywordVal, 2);
+  case lltok::kw_fmul:
+  case lltok::kw_fdiv:
+  case lltok::kw_frem: {
+    FastMathFlags FMF = EatFastMathFlagsIfPresent();
+    int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2);
+    if (Res != 0)
+      return Res;
+    if (FMF.any())
+      Inst->setFastMathFlags(FMF);
+    return 0;
+  }
 
   case lltok::kw_sdiv:
   case lltok::kw_udiv:
@@ -3027,8 +3037,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
 
   case lltok::kw_urem:
   case lltok::kw_srem:   return ParseArithmetic(Inst, PFS, KeywordVal, 1);
-  case lltok::kw_fdiv:
-  case lltok::kw_frem:   return ParseArithmetic(Inst, PFS, KeywordVal, 2);
   case lltok::kw_and:
   case lltok::kw_or:
   case lltok::kw_xor:    return ParseLogical(Inst, PFS, KeywordVal);
index 9f9672d67b5bf2814ea3e0a773ae92229b68ad1b..8e04705a7b272118139d210d271ab1f09ce43d26 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/Attributes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/Operator.h"
 #include "llvm/Type.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
@@ -154,6 +155,21 @@ namespace llvm {
       Lex.Lex();
       return true;
     }
+
+    FastMathFlags EatFastMathFlagsIfPresent() {
+      FastMathFlags FMF;
+      while (true)
+        switch (Lex.getKind()) {
+        case lltok::kw_fast: FMF.UnsafeAlgebra   = true; Lex.Lex(); continue;
+        case lltok::kw_nnan: FMF.NoNaNs          = true; Lex.Lex(); continue;
+        case lltok::kw_ninf: FMF.NoInfs          = true; Lex.Lex(); continue;
+        case lltok::kw_nsz:  FMF.NoSignedZeros   = true; Lex.Lex(); continue;
+        case lltok::kw_arcp: FMF.AllowReciprocal = true; Lex.Lex(); continue;
+        default: return FMF;
+        }
+      return FMF;
+    }
+
     bool ParseOptionalToken(lltok::Kind T, bool &Present, LocTy *Loc = 0) {
       if (Lex.getKind() != T) {
         Present = false;
index 036686d31823834586a45b033d7418908a29a66f..1ec1b1e1264c1a550b67546ce6ec0bf4716acf8c 100644 (file)
@@ -60,6 +60,11 @@ namespace lltok {
     kw_atomic,
     kw_unordered, kw_monotonic, kw_acquire, kw_release, kw_acq_rel, kw_seq_cst,
     kw_singlethread,
+    kw_nnan,
+    kw_ninf,
+    kw_nsz,
+    kw_arcp,
+    kw_fast,
     kw_nuw,
     kw_nsw,
     kw_exact,
index c45a04f12b72207c77c12a50edffabbd763c799f..433f3e011d66f2dee4cc4b51d6f9e4fc44bb2f22 100644 (file)
@@ -703,6 +703,22 @@ static void writeAtomicRMWOperation(raw_ostream &Out,
 }
 
 static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
+  if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U)) {
+    // Unsafe algebra implies all the others, no need to write them all out
+    if (FPO->hasUnsafeAlgebra())
+      Out << " fast";
+    else {
+      if (FPO->hasNoNaNs())
+        Out << " nnan";
+      if (FPO->hasNoInfs())
+        Out << " ninf";
+      if (FPO->hasNoSignedZeros())
+        Out << " nsz";
+      if (FPO->hasAllowReciprocal())
+        Out << " arcp";
+    }
+  }
+
   if (const OverflowingBinaryOperator *OBO =
         dyn_cast<OverflowingBinaryOperator>(U)) {
     if (OBO->hasNoUnsignedWrap())