[llvm] a1beb61 - [SimplifyLibCalls] Shrink sin, cos to sinf, cosf when allowed (#139082)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 8 21:25:39 PDT 2025


Author: Guy David
Date: 2025-05-09T07:25:35+03:00
New Revision: a1beb619403a781153c170f041f39a3bac1cebb7

URL: https://github.com/llvm/llvm-project/commit/a1beb619403a781153c170f041f39a3bac1cebb7
DIFF: https://github.com/llvm/llvm-project/commit/a1beb619403a781153c170f041f39a3bac1cebb7.diff

LOG: [SimplifyLibCalls] Shrink sin, cos to sinf, cosf when allowed (#139082)

This optimization already exists, but for the libcall versions of these
functions and not for their intrinsic form.
Solves https://github.com/llvm/llvm-project/issues/139044.

There are probably more opportunities for other intrinsics, because the
switch-case in `LibCallSimplifier::optimizeCall` covers only `pow`,
`exp2`, `log`, `log2`, `log10`, `sqrt`, `memset`, `memcpy` and
`memmove`.

Added: 
    llvm/test/Transforms/InstCombine/simplify-intrinsics.ll

Modified: 
    llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/test/Transforms/InstCombine/cos-1.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 941e787f91eff..94a79ad824370 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -4136,6 +4136,11 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
       return optimizeMemCpy(CI, Builder);
     case Intrinsic::memmove:
       return optimizeMemMove(CI, Builder);
+    case Intrinsic::sin:
+    case Intrinsic::cos:
+      if (UnsafeFPShrink)
+        return optimizeUnaryDoubleFP(CI, Builder, TLI, /*isPrecise=*/true);
+      return nullptr;
     default:
       return nullptr;
     }

diff  --git a/llvm/test/Transforms/InstCombine/cos-1.ll b/llvm/test/Transforms/InstCombine/cos-1.ll
index 168d88fb3a942..7c66f27a7f5c2 100644
--- a/llvm/test/Transforms/InstCombine/cos-1.ll
+++ b/llvm/test/Transforms/InstCombine/cos-1.ll
@@ -435,11 +435,15 @@ define float @unary_negated_and_shrinkable_libcall(float %f) {
 ; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?
 
 define float @negated_and_shrinkable_intrinsic(float %f) {
-; ANY-LABEL: @negated_and_shrinkable_intrinsic(
-; ANY-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
-; ANY-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
-; ANY-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
-; ANY-NEXT:    ret float [[CONV2]]
+; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_intrinsic(
+; NO-FLOAT-SHRINK-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
+; NO-FLOAT-SHRINK-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
+; NO-FLOAT-SHRINK-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
+; NO-FLOAT-SHRINK-NEXT:    ret float [[CONV2]]
+;
+; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_intrinsic(
+; DO-FLOAT-SHRINK-NEXT:    [[COS:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])
+; DO-FLOAT-SHRINK-NEXT:    ret float [[COS]]
 ;
   %conv1 = fpext float %f to double
   %neg = fsub double -0.0, %conv1
@@ -449,11 +453,15 @@ define float @negated_and_shrinkable_intrinsic(float %f) {
 }
 
 define float @unary_negated_and_shrinkable_intrinsic(float %f) {
-; ANY-LABEL: @unary_negated_and_shrinkable_intrinsic(
-; ANY-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
-; ANY-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
-; ANY-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
-; ANY-NEXT:    ret float [[CONV2]]
+; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_intrinsic(
+; NO-FLOAT-SHRINK-NEXT:    [[CONV1:%.*]] = fpext float [[F:%.*]] to double
+; NO-FLOAT-SHRINK-NEXT:    [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
+; NO-FLOAT-SHRINK-NEXT:    [[CONV2:%.*]] = fptrunc double [[COS]] to float
+; NO-FLOAT-SHRINK-NEXT:    ret float [[CONV2]]
+;
+; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_intrinsic(
+; DO-FLOAT-SHRINK-NEXT:    [[COS:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])
+; DO-FLOAT-SHRINK-NEXT:    ret float [[COS]]
 ;
   %conv1 = fpext float %f to double
   %neg = fneg double %conv1

diff  --git a/llvm/test/Transforms/InstCombine/simplify-intrinsics.ll b/llvm/test/Transforms/InstCombine/simplify-intrinsics.ll
new file mode 100644
index 0000000000000..8536512b8035f
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/simplify-intrinsics.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S                             | FileCheck %s --check-prefixes=ANY,NO-FLOAT-SHRINK
+; RUN: opt < %s -passes=instcombine -enable-double-float-shrink -S | FileCheck %s --check-prefixes=ANY,DO-FLOAT-SHRINK
+
+declare double @llvm.cos.f64(double)
+declare float @llvm.cos.f32(float)
+
+declare double @llvm.sin.f64(double)
+declare float @llvm.sin.f32(float)
+
+; cos -> cosf
+
+define float @cos_no_fastmath(float %f) {
+; NO-FLOAT-SHRINK-LABEL: @cos_no_fastmath(
+; NO-FLOAT-SHRINK-NEXT:    [[D:%.*]] = fpext float [[F:%.*]] to double
+; NO-FLOAT-SHRINK-NEXT:    [[RESULT:%.*]] = call double @llvm.cos.f64(double [[D]])
+; NO-FLOAT-SHRINK-NEXT:    [[TRUNCATED_RESULT:%.*]] = fptrunc double [[RESULT]] to float
+; NO-FLOAT-SHRINK-NEXT:    ret float [[TRUNCATED_RESULT]]
+;
+; DO-FLOAT-SHRINK-LABEL: @cos_no_fastmath(
+; DO-FLOAT-SHRINK-NEXT:    [[TMP1:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])
+; DO-FLOAT-SHRINK-NEXT:    ret float [[TMP1]]
+;
+  %d = fpext float %f to double
+  %result = call double @llvm.cos.f64(double %d)
+  %truncated_result = fptrunc double %result to float
+  ret float %truncated_result
+}
+
+define float @cos_fastmath(float %f) {
+; ANY-LABEL: @cos_fastmath(
+; ANY-NEXT:    [[TMP1:%.*]] = call fast float @llvm.cos.f32(float [[F:%.*]])
+; ANY-NEXT:    ret float [[TMP1]]
+;
+  %d = fpext float %f to double
+  %result = call fast double @llvm.cos.f64(double %d)
+  %truncated_result = fptrunc double %result to float
+  ret float %truncated_result
+}
+
+; sin -> sinf
+
+define float @sin_no_fastmath(float %f) {
+; NO-FLOAT-SHRINK-LABEL: @sin_no_fastmath(
+; NO-FLOAT-SHRINK-NEXT:    [[D:%.*]] = fpext float [[F:%.*]] to double
+; NO-FLOAT-SHRINK-NEXT:    [[RESULT:%.*]] = call double @llvm.sin.f64(double [[D]])
+; NO-FLOAT-SHRINK-NEXT:    [[TRUNCATED_RESULT:%.*]] = fptrunc double [[RESULT]] to float
+; NO-FLOAT-SHRINK-NEXT:    ret float [[TRUNCATED_RESULT]]
+;
+; DO-FLOAT-SHRINK-LABEL: @sin_no_fastmath(
+; DO-FLOAT-SHRINK-NEXT:    [[TMP1:%.*]] = call float @llvm.sin.f32(float [[F:%.*]])
+; DO-FLOAT-SHRINK-NEXT:    ret float [[TMP1]]
+;
+  %d = fpext float %f to double
+  %result = call double @llvm.sin.f64(double %d)
+  %truncated_result = fptrunc double %result to float
+  ret float %truncated_result
+}
+
+define float @sin_fastmath(float %f) {
+; ANY-LABEL: @sin_fastmath(
+; ANY-NEXT:    [[TMP1:%.*]] = call fast float @llvm.sin.f32(float [[F:%.*]])
+; ANY-NEXT:    ret float [[TMP1]]
+;
+  %d = fpext float %f to double
+  %result = call fast double @llvm.sin.f64(double %d)
+  %truncated_result = fptrunc double %result to float
+  ret float %truncated_result
+}


        


More information about the llvm-commits mailing list