Express the number of ULPs in fpaccuracy metadata as a real rather than a
authorDuncan Sands <baldrick@free.fr>
Tue, 10 Apr 2012 08:22:43 +0000 (08:22 +0000)
committerDuncan Sands <baldrick@free.fr>
Tue, 10 Apr 2012 08:22:43 +0000 (08:22 +0000)
rational number, eg as 2.5 rather than 5, 2.  OK'd by Peter Collingbourne.

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

docs/LangRef.html
include/llvm/ADT/APFloat.h
lib/VMCore/Verifier.cpp
test/Verifier/fpaccuracy.ll [new file with mode: 0644]

index e6d47a6ce5bbbf443e0bf45cb12e1a8967eeddc4..4f6b137ed189ce9a3352fc4aeb42b8f1131e4e8f 100644 (file)
@@ -3021,13 +3021,13 @@ call void @llvm.dbg.value(metadata !24, i64 0, metadata !25)
 
 </blockquote>
 
-<p>The maximum relative error may be any rational number.  The metadata node
-   shall consist of a pair of unsigned integers respectively representing
-   the numerator and denominator.  For example, 2.5 ULP:</p>
+<p>The metadata node shall consist of a single non-negative floating
+   point number representing the maximum relative error.  For example,
+   2.5 ULP:</p>
 
 <div class="doc_code">
 <pre>
-!0 = metadata !{ i32 5, i32 2 }
+!0 = metadata !{ float 2.5 }
 </pre>
 </div>
 
index d40727dfcef1143aef4b3c14381e1126a56e81b0..2b466f900c81f4ba1c778893b69bcc28c3a91b5a 100644 (file)
@@ -320,6 +320,7 @@ namespace llvm {
     const fltSemantics &getSemantics() const { return *semantics; }
     bool isZero() const { return category == fcZero; }
     bool isNonZero() const { return category != fcZero; }
+    bool isNormal() const { return category == fcNormal; }
     bool isNaN() const { return category == fcNaN; }
     bool isInfinity() const { return category == fcInfinity; }
     bool isNegative() const { return sign; }
index b6648016c660b74cf8c997335b09a1a64df76ca0..96492e44d56f8e32c8066d7803a1bd75e82ba149 100644 (file)
@@ -1653,6 +1653,18 @@ void Verifier::visitInstruction(Instruction &I) {
     }
   }
 
+  if (MDNode *MD = I.getMetadata(LLVMContext::MD_fpaccuracy)) {
+    Assert1(I.getType()->isFPOrFPVectorTy(),
+            "fpaccuracy requires a floating point result!", &I);
+    Assert1(MD->getNumOperands() == 1, "fpaccuracy takes one operand!", &I);
+    ConstantFP *Op = dyn_cast_or_null<ConstantFP>(MD->getOperand(0));
+    Assert1(Op, "fpaccuracy ULPs not a floating point number!", &I);
+    APFloat ULPs = Op->getValueAPF();
+    Assert1(ULPs.isNormal() || ULPs.isZero(),
+            "fpaccuracy ULPs not a normal number!", &I);
+    Assert1(!ULPs.isNegative(), "fpaccuracy ULPs is negative!", &I);
+  }
+
   MDNode *MD = I.getMetadata(LLVMContext::MD_range);
   Assert1(!MD || isa<LoadInst>(I), "Ranges are only for loads!", &I);
 
diff --git a/test/Verifier/fpaccuracy.ll b/test/Verifier/fpaccuracy.ll
new file mode 100644 (file)
index 0000000..2fefde0
--- /dev/null
@@ -0,0 +1,31 @@
+; RUN: not llvm-as < %s |& FileCheck %s
+
+define void @foo(i32 %i, float %f, <2 x float> %g) {
+  %s = add i32 %i, %i, !fpaccuracy !0
+; CHECK: fpaccuracy requires a floating point result!
+  %t = fadd float %f, %f, !fpaccuracy !1
+; CHECK: fpaccuracy takes one operand!
+  %u = fadd float %f, %f, !fpaccuracy !2
+; CHECK: fpaccuracy takes one operand!
+  %v = fadd float %f, %f, !fpaccuracy !3
+; CHECK: fpaccuracy ULPs not a floating point number!
+  %w = fadd float %f, %f, !fpaccuracy !0
+; Above line is correct.
+  %w2 = fadd <2 x float> %g, %g, !fpaccuracy !0
+; Above line is correct.
+  %x = fadd float %f, %f, !fpaccuracy !4
+; CHECK: fpaccuracy ULPs is negative!
+  %y = fadd float %f, %f, !fpaccuracy !5
+; CHECK: fpaccuracy ULPs is negative!
+  %z = fadd float %f, %f, !fpaccuracy !6
+; CHECK: fpaccuracy ULPs not a normal number!
+  ret void
+}
+
+!0 = metadata !{ float 1.0 }
+!1 = metadata !{ }
+!2 = metadata !{ float 1.0, float 1.0 }
+!3 = metadata !{ i32 1 }
+!4 = metadata !{ float -1.0 }
+!5 = metadata !{ float -0.0 }
+!6 = metadata !{ float 0x7FFFFFFF00000000 }