[cfe-commits] r143136 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenOpenCL/fpaccuracy.cl

Peter Collingbourne peter at pcc.me.uk
Thu Oct 27 12:19:51 PDT 2011


Author: pcc
Date: Thu Oct 27 14:19:51 2011
New Revision: 143136

URL: http://llvm.org/viewvc/llvm-project?rev=143136&view=rev
Log:
Annotate imprecise FP division with fpaccuracy metadata

The OpenCL single precision division operation is only required to
be accurate to 2.5ulp.  Annotate the fdiv instruction with metadata
which signals to the backend that an imprecise divide instruction
may be used.

Added:
    cfe/trunk/test/CodeGenOpenCL/fpaccuracy.cl
Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=143136&r1=143135&r2=143136&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Oct 27 14:19:51 2011
@@ -23,6 +23,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/Intrinsics.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Target/TargetData.h"
 using namespace clang;
 using namespace CodeGen;
@@ -2752,3 +2753,18 @@
     return RValue::get(0);
   return ConvertTempToRValue(*this, E->getType(), OrigDest);
 }
+
+void CodeGenFunction::SetFPAccuracy(llvm::Value *Val, unsigned AccuracyN,
+                                    unsigned AccuracyD) {
+  assert(Val->getType()->isFPOrFPVectorTy());
+  if (!AccuracyN || !isa<llvm::Instruction>(Val))
+    return;
+
+  llvm::Value *Vals[2];
+  Vals[0] = llvm::ConstantInt::get(Int32Ty, AccuracyN);
+  Vals[1] = llvm::ConstantInt::get(Int32Ty, AccuracyD);
+  llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), Vals);
+
+  cast<llvm::Instruction>(Val)->setMetadata(llvm::LLVMContext::MD_fpaccuracy,
+                                            Node);
+}

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=143136&r1=143135&r2=143136&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Oct 27 14:19:51 2011
@@ -1772,8 +1772,18 @@
       Builder.SetInsertPoint(DivCont);
     }
   }
-  if (Ops.LHS->getType()->isFPOrFPVectorTy())
-    return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
+  if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
+    llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
+    if (CGF.getContext().getLangOptions().OpenCL) {
+      // OpenCL 1.1 7.4: minimum accuracy of single precision / is 2.5ulp
+      llvm::Type *ValTy = Val->getType();
+      if (ValTy->isFloatTy() ||
+          (isa<llvm::VectorType>(ValTy) &&
+           cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
+        CGF.SetFPAccuracy(Val, 5, 2);
+    }
+    return Val;
+  }
   else if (Ops.Ty->hasUnsignedIntegerRepresentation())
     return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
   else

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=143136&r1=143135&r2=143136&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Oct 27 14:19:51 2011
@@ -2382,6 +2382,11 @@
   /// a r-value suitable for passing the given parameter.
   void EmitDelegateCallArg(CallArgList &args, const VarDecl *param);
 
+  /// SetFPAccuracy - Set the minimum required accuracy of the given floating
+  /// point operation, expressed as the maximum relative error in ulp.
+  void SetFPAccuracy(llvm::Value *Val, unsigned AccuracyN,
+                     unsigned AccuracyD = 1);
+
 private:
   void EmitReturnOfRValue(RValue RV, QualType Ty);
 

Added: cfe/trunk/test/CodeGenOpenCL/fpaccuracy.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/fpaccuracy.cl?rev=143136&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/fpaccuracy.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/fpaccuracy.cl Thu Oct 27 14:19:51 2011
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+
+float spscalardiv(float a, float b) {
+  // CHECK: @spscalardiv
+  // CHECK: fdiv{{.*}}, !fpaccuracy ![[MD:[0-9]+]]
+  return a / b;
+}
+
+float4 spvectordiv(float4 a, float4 b) {
+  // CHECK: @spvectordiv
+  // CHECK: fdiv{{.*}}, !fpaccuracy ![[MD]]
+  return a / b;
+}
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+double dpscalardiv(double a, double b) {
+  // CHECK: @dpscalardiv
+  // CHECK-NOT: !fpaccuracy
+  return a / b;
+}
+
+// CHECK: ![[MD]] = metadata !{i{{[0-9]+}} 5, i{{[0-9]+}} 2}





More information about the cfe-commits mailing list