[llvm] Add support of (f(-x) = -f(x)) for error functions (PR #81356)

Krishna Narayanan via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 11 00:23:51 PST 2024


https://github.com/Krishna-13-cyber updated https://github.com/llvm/llvm-project/pull/81356

>From cce5ab85c1ab9c289c95842b279173483764d387 Mon Sep 17 00:00:00 2001
From: Krishna-13-cyber <krishnanarayanan132002 at gmail.com>
Date: Sat, 10 Feb 2024 17:50:56 +0530
Subject: [PATCH] Add support of (Odd function, f(-x) = -f(x)) for error
 functions

---
 llvm/include/llvm/Analysis/TargetLibraryInfo.def  | 15 +++++++++++++++
 llvm/include/llvm/Analysis/TargetLibraryInfo.h    |  3 +++
 llvm/lib/Analysis/TargetLibraryInfo.cpp           |  3 +++
 llvm/lib/Transforms/Utils/BuildLibCalls.cpp       |  3 +++
 llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp    | 12 ++++++++++++
 llvm/test/Transforms/InstCombine/erf.ll           | 13 +++++++++++++
 .../tools/llvm-tli-checker/ps4-tli-check.yaml     |  4 ++--
 llvm/unittests/Analysis/TargetLibraryInfoTest.cpp |  3 +++
 8 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/InstCombine/erf.ll

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
index 6bd922eed89e15..37221eb9e47115 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
@@ -1069,6 +1069,21 @@ TLI_DEFINE_ENUM_INTERNAL(ctermid)
 TLI_DEFINE_STRING_INTERNAL("ctermid")
 TLI_DEFINE_SIG_INTERNAL(Ptr, Ptr)
 
+/// double erf(double x);
+TLI_DEFINE_ENUM_INTERNAL(erf)
+TLI_DEFINE_STRING_INTERNAL("erf")
+TLI_DEFINE_SIG_INTERNAL(Dbl, Dbl)
+
+/// float erff(float x);
+TLI_DEFINE_ENUM_INTERNAL(erff)
+TLI_DEFINE_STRING_INTERNAL("erff")
+TLI_DEFINE_SIG_INTERNAL(Flt, Flt)
+
+/// long double erfl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(erfl)
+TLI_DEFINE_STRING_INTERNAL("erfl")
+TLI_DEFINE_SIG_INTERNAL(LDbl, LDbl)
+
 /// int execl(const char *path, const char *arg, ...);
 TLI_DEFINE_ENUM_INTERNAL(execl)
 TLI_DEFINE_STRING_INTERNAL("execl")
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index daf1d8e2079f85..c7d0b5a62107c3 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -436,6 +436,9 @@ class TargetLibraryInfo {
     case LibFunc_memcmp:       case LibFunc_bcmp:       case LibFunc_strcmp:
     case LibFunc_strcpy:       case LibFunc_stpcpy:     case LibFunc_strlen:
     case LibFunc_strnlen:      case LibFunc_memchr:     case LibFunc_mempcpy:
+    case LibFunc_erf:
+    case LibFunc_erff:
+    case LibFunc_erfl:
       return true;
     }
     return false;
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 25951d2a7fe63c..edf31c85a2c8f9 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -806,6 +806,9 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
     TLI.setUnavailable(LibFunc_cabs);
     TLI.setUnavailable(LibFunc_cabsf);
     TLI.setUnavailable(LibFunc_cabsl);
+    TLI.setUnavailable(LibFunc_erf);
+    TLI.setUnavailable(LibFunc_erff);
+    TLI.setUnavailable(LibFunc_erfl);
     TLI.setUnavailable(LibFunc_ffs);
     TLI.setUnavailable(LibFunc_flockfile);
     TLI.setUnavailable(LibFunc_fseeko);
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index 12741dc5af5a1d..ed0ed345435c45 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -1137,6 +1137,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
   case LibFunc_cosl:
   case LibFunc_cospi:
   case LibFunc_cospif:
+  case LibFunc_erf:
+  case LibFunc_erff:
+  case LibFunc_erfl:
   case LibFunc_exp:
   case LibFunc_expf:
   case LibFunc_expl:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 26a34aa99e1b87..f576101fb9098a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1908,6 +1908,14 @@ Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilderBase &B) {
       *CI, B.CreateCall(FSqrt, B.CreateFAdd(RealReal, ImagImag), "cabs"));
 }
 
+static Value *optimizeOdd(CallInst *Call, IRBuilderBase &B) {
+  Value *X;
+  if (match(Call->getArgOperand(0), m_OneUse(m_FNeg(m_Value(X)))))
+    return B.CreateFNeg(
+        copyFlags(*Call, B.CreateCall(Call->getCalledFunction(), X)));
+  return nullptr;
+}
+
 static Value *optimizeTrigReflections(CallInst *Call, LibFunc Func,
                                       IRBuilderBase &B) {
   if (!isa<FPMathOperator>(Call))
@@ -3736,6 +3744,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
   case LibFunc_atanhf:
   case LibFunc_atanhl:
     return optimizeTrigInversionPairs(CI, Builder);
+  case LibFunc_erf:
+  case LibFunc_erff:
+  case LibFunc_erfl:
+    return optimizeOdd(CI, Builder); // erf(-X) --> -erf(X)
   case LibFunc_ceil:
     return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
   case LibFunc_floor:
diff --git a/llvm/test/Transforms/InstCombine/erf.ll b/llvm/test/Transforms/InstCombine/erf.ll
new file mode 100644
index 00000000000000..e08f720b548847
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/erf.ll
@@ -0,0 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function @erf_negated_arg --version 4
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+declare float @erff(float)
+
+define float @erf_negated_arg(float %x) {
+  %fneg = fneg float %x
+  %call.i = call noundef float @erff(float noundef %fneg)
+  %fneg1 = fneg float %call.i
+  ret float %fneg1
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
index 23d3482fb89a78..61caf727b0f96e 100644
--- a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
+++ b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
@@ -47,10 +47,10 @@
 ## the exact count first; the two directives should add up to that.
 ## Yes, this means additions to TLI will fail this test, but the argument
 ## to -COUNT can't be an expression.
-# AVAIL: TLI knows 476 symbols, 243 available
+# AVAIL: TLI knows 479 symbols, 243 available
 # AVAIL-COUNT-243: {{^}} available
 # AVAIL-NOT:       {{^}} available
-# UNAVAIL-COUNT-233: not available
+# UNAVAIL-COUNT-236: not available
 # UNAVAIL-NOT:       not available
 
 ## This is a large file so it's worth telling lit to stop here.
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 34b06fe480f364..d09accbab6de56 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -150,6 +150,9 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
       "declare x86_fp80 @coshl(x86_fp80)\n"
       "declare x86_fp80 @cosl(x86_fp80)\n"
       "declare i8* @ctermid(i8*)\n"
+      "declare double @erf(double)\n"
+      "declare float @erff(float)\n"
+      "declare float @erfl(float)\n"
       "declare double @exp(double)\n"
       "declare double @exp2(double)\n"
       "declare float @exp2f(float)\n"



More information about the llvm-commits mailing list