[NVPTX] Add @llvm.nvvm.sqrt.f() intrinsic
authorJustin Holewinski <jholewinski@nvidia.com>
Tue, 21 May 2013 16:51:30 +0000 (16:51 +0000)
committerJustin Holewinski <jholewinski@nvidia.com>
Tue, 21 May 2013 16:51:30 +0000 (16:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182394 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/IntrinsicsNVVM.td
lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
lib/Target/NVPTX/NVPTXISelDAGToDAG.h
lib/Target/NVPTX/NVPTXInstrInfo.td
lib/Target/NVPTX/NVPTXIntrinsics.td
test/CodeGen/NVPTX/intrinsics.ll

index ebfd03e48492fb99f242c727c46562bf783a340b..c248517def6f30aeacb8f2a06b885b2d1d7d30b3 100644 (file)
@@ -405,6 +405,8 @@ def llvm_anyi64ptr_ty     : LLVMAnyPointerType<llvm_i64_ty>;     // (space)i64*
 // Sqrt
 //
 
+  def int_nvvm_sqrt_f : GCCBuiltin<"__nvvm_sqrt_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
   def int_nvvm_sqrt_rn_ftz_f : GCCBuiltin<"__nvvm_sqrt_rn_ftz_f">,
       Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
   def int_nvvm_sqrt_rn_f : GCCBuiltin<"__nvvm_sqrt_rn_f">,
index 0f4c8dbce5e3ca37b6cb026fabc589d94f4a7277..d4378c2322d4b65f27d0b23683b0e9a5439e1430 100644 (file)
@@ -42,6 +42,11 @@ static cl::opt<int> UsePrecDivF32(
              " IEEE Compliant F32 div.rnd if avaiable."),
     cl::init(2));
 
+static cl::opt<bool>
+UsePrecSqrtF32("nvptx-prec-sqrtf32",
+          cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
+          cl::init(true));
+
 /// createNVPTXISelDag - This pass converts a legalized DAG into a
 /// NVPTX-specific DAG, ready for instruction scheduling.
 FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
@@ -74,6 +79,8 @@ NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
 
   // Decide how to translate f32 div
   do_DIVF32_PREC = UsePrecDivF32;
+  // Decide how to translate f32 sqrt
+  do_SQRTF32_PREC = UsePrecSqrtF32;
   // sm less than sm_20 does not support div.rnd. Use div.full.
   if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20())
     do_DIVF32_PREC = 1;
index 70e8e464297de98670678e370974cf235b0f2e4a..ed16d4450b261f2ad0c397aaf83ee331a3187736 100644 (file)
@@ -41,6 +41,10 @@ class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel {
   //    Otherwise, use div.full
   int do_DIVF32_PREC;
 
+  // If true, generate sqrt.rn, else generate sqrt.approx. If FTZ
+  // is true, then generate the corresponding FTZ version.
+  bool do_SQRTF32_PREC;
+
   // If true, add .ftz to f32 instructions.
   // This is only meaningful for sm_20 and later, as the default
   // is not ftz.
index f43abe283b58bff8fa43c3ff175315ca63cde7d9..da6dd39b9314a6bf45996e30e1da2c42f21783be 100644 (file)
@@ -75,6 +75,9 @@ def allowFMA_ftz : Predicate<"(allowFMA && UseF32FTZ)">;
 def do_DIVF32_APPROX : Predicate<"do_DIVF32_PREC==0">;
 def do_DIVF32_FULL : Predicate<"do_DIVF32_PREC==1">;
 
+def do_SQRTF32_APPROX : Predicate<"do_SQRTF32_PREC==0">;
+def do_SQRTF32_RN : Predicate<"do_SQRTF32_PREC==1">;
+
 def hasHWROT32 : Predicate<"Subtarget.hasHWROT32()">;
 
 def true : Predicate<"1">;
index 2780ef40365dece7e369788c6f714794d579861c..24037cafefe96b8d475603272b366a04873449e5 100644 (file)
@@ -512,6 +512,16 @@ def INT_NVVM_SQRT_RM_D : F_MATH_1<"sqrt.rm.f64 \t$dst, $src0;", Float64Regs,
 def INT_NVVM_SQRT_RP_D : F_MATH_1<"sqrt.rp.f64 \t$dst, $src0;", Float64Regs,
   Float64Regs, int_nvvm_sqrt_rp_d>;
 
+// nvvm_sqrt intrinsic
+def : Pat<(int_nvvm_sqrt_f Float32Regs:$a),
+          (INT_NVVM_SQRT_RN_FTZ_F Float32Regs:$a)>, Requires<[doF32FTZ, do_SQRTF32_RN]>;
+def : Pat<(int_nvvm_sqrt_f Float32Regs:$a),
+          (INT_NVVM_SQRT_RN_F Float32Regs:$a)>, Requires<[do_SQRTF32_RN]>;
+def : Pat<(int_nvvm_sqrt_f Float32Regs:$a),
+          (INT_NVVM_SQRT_APPROX_FTZ_F Float32Regs:$a)>, Requires<[doF32FTZ]>;
+def : Pat<(int_nvvm_sqrt_f Float32Regs:$a),
+          (INT_NVVM_SQRT_APPROX_F Float32Regs:$a)>;
+
 //
 // Rsqrt
 //
index 8b0357be87cb0caaad33d33a439964981b4c5a2d..1676f20643d228248fd6d643261b9f2038b8d9dc 100644 (file)
@@ -15,5 +15,12 @@ define ptx_device double @test_fabs(double %d) {
        ret double %x
 }
 
+define float @test_nvvm_sqrt(float %a) {
+  %val = call float @llvm.nvvm.sqrt.f(float %a)
+  ret float %val
+}
+
+
 declare float @llvm.fabs.f32(float)
 declare double @llvm.fabs.f64(double)
+declare float @llvm.nvvm.sqrt.f(float)