From b704d23062aa78b00999b75dcdcb628d4d84ee3f Mon Sep 17 00:00:00 2001 From: Preston Gurd Date: Mon, 27 May 2013 15:44:35 +0000 Subject: [PATCH] Convert sqrt functions into sqrt instructions when -ffast-math is in effect. When -ffast-math is in effect (on Linux, at least), clang defines __FINITE_MATH_ONLY__ > 0 when including . This causes the preprocessor to include , which renames the sqrt functions. For instance, "sqrt" is renamed as "__sqrt_finite". This patch adds the 3 new names in such a way that they will be treated as equivalent to their respective original names. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182739 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLibraryInfo.h | 8 ++++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 3 ++ lib/Target/TargetLibraryInfo.cpp | 3 ++ test/CodeGen/X86/sqrt-fastmath.ll | 60 ++++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 test/CodeGen/X86/sqrt-fastmath.ll diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index 5f01c8d8351..4b9c0442dc9 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -57,6 +57,12 @@ namespace llvm { dunder_isoc99_sscanf, /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); memcpy_chk, + /// double __sqrt_finite(double x); + sqrt_finite, + /// float __sqrt_finite(float x); + sqrtf_finite, + /// long double __sqrt_finite(long double x); + sqrtl_finite, /// char * __strdup(const char *s); dunder_strdup, /// char *__strndup(const char *s, size_t n); @@ -677,6 +683,8 @@ public: case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl: case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl: case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl: + case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite: + case LibFunc::sqrtl_finite: case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl: case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl: case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index aae11794eb0..f6867840aee 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5562,6 +5562,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl: + case LibFunc::sqrt_finite: + case LibFunc::sqrtf_finite: + case LibFunc::sqrtl_finite: if (visitUnaryFloatCall(I, ISD::FSQRT)) return; break; diff --git a/lib/Target/TargetLibraryInfo.cpp b/lib/Target/TargetLibraryInfo.cpp index ee88ce77c09..d2967d929d8 100644 --- a/lib/Target/TargetLibraryInfo.cpp +++ b/lib/Target/TargetLibraryInfo.cpp @@ -43,6 +43,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "__isoc99_scanf", "__isoc99_sscanf", "__memcpy_chk", + "__sqrt_finite", + "__sqrtf_finite", + "__sqrtl_finite", "__strdup", "__strndup", "__strtok_r", diff --git a/test/CodeGen/X86/sqrt-fastmath.ll b/test/CodeGen/X86/sqrt-fastmath.ll new file mode 100644 index 00000000000..9b5179efa42 --- /dev/null +++ b/test/CodeGen/X86/sqrt-fastmath.ll @@ -0,0 +1,60 @@ +; RUN: llc < %s -mcpu=core2 | FileCheck %s + +; generated using "clang -S -O2 -ffast-math -emit-llvm sqrt.c" from +; #include +; +; double fd(double d){ +; return sqrt(d); +; } +; +; float ff(float f){ +; return sqrtf(f); +; } +; +; long double fld(long double ld){ +; return sqrtl(ld); +; } +; +; Tests conversion of sqrt function calls into sqrt instructions when +; -ffast-math is in effect. + +; ModuleID = 'sqrt.c' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind readnone uwtable +define double @fd(double %d) #0 { +entry: +; CHECK: sqrtsd + %call = tail call double @__sqrt_finite(double %d) #2 + ret double %call +} + +; Function Attrs: nounwind readnone +declare double @__sqrt_finite(double) #1 + +; Function Attrs: nounwind readnone uwtable +define float @ff(float %f) #0 { +entry: +; CHECK: sqrtss + %call = tail call float @__sqrtf_finite(float %f) #2 + ret float %call +} + +; Function Attrs: nounwind readnone +declare float @__sqrtf_finite(float) #1 + +; Function Attrs: nounwind readnone uwtable +define x86_fp80 @fld(x86_fp80 %ld) #0 { +entry: +; CHECK: fsqrt + %call = tail call x86_fp80 @__sqrtl_finite(x86_fp80 %ld) #2 + ret x86_fp80 %call +} + +; Function Attrs: nounwind readnone +declare x86_fp80 @__sqrtl_finite(x86_fp80) #1 + +attributes #0 = { nounwind readnone uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" "use-soft-float"="false" } +attributes #1 = { nounwind readnone "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } -- 2.11.0