Skip to content

Commit a1beb61

Browse files
authored
[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 #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`.
1 parent 74e5a3b commit a1beb61

File tree

3 files changed

+92
-10
lines changed

3 files changed

+92
-10
lines changed

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4136,6 +4136,11 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
41364136
return optimizeMemCpy(CI, Builder);
41374137
case Intrinsic::memmove:
41384138
return optimizeMemMove(CI, Builder);
4139+
case Intrinsic::sin:
4140+
case Intrinsic::cos:
4141+
if (UnsafeFPShrink)
4142+
return optimizeUnaryDoubleFP(CI, Builder, TLI, /*isPrecise=*/true);
4143+
return nullptr;
41394144
default:
41404145
return nullptr;
41414146
}

llvm/test/Transforms/InstCombine/cos-1.ll

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -435,11 +435,15 @@ define float @unary_negated_and_shrinkable_libcall(float %f) {
435435
; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?
436436

437437
define float @negated_and_shrinkable_intrinsic(float %f) {
438-
; ANY-LABEL: @negated_and_shrinkable_intrinsic(
439-
; ANY-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
440-
; ANY-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
441-
; ANY-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float
442-
; ANY-NEXT: ret float [[CONV2]]
438+
; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_intrinsic(
439+
; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
440+
; NO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
441+
; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float
442+
; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]
443+
;
444+
; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_intrinsic(
445+
; DO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])
446+
; DO-FLOAT-SHRINK-NEXT: ret float [[COS]]
443447
;
444448
%conv1 = fpext float %f to double
445449
%neg = fsub double -0.0, %conv1
@@ -449,11 +453,15 @@ define float @negated_and_shrinkable_intrinsic(float %f) {
449453
}
450454

451455
define float @unary_negated_and_shrinkable_intrinsic(float %f) {
452-
; ANY-LABEL: @unary_negated_and_shrinkable_intrinsic(
453-
; ANY-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
454-
; ANY-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
455-
; ANY-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float
456-
; ANY-NEXT: ret float [[CONV2]]
456+
; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_intrinsic(
457+
; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double
458+
; NO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])
459+
; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float
460+
; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]
461+
;
462+
; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_intrinsic(
463+
; DO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])
464+
; DO-FLOAT-SHRINK-NEXT: ret float [[COS]]
457465
;
458466
%conv1 = fpext float %f to double
459467
%neg = fneg double %conv1
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=ANY,NO-FLOAT-SHRINK
3+
; RUN: opt < %s -passes=instcombine -enable-double-float-shrink -S | FileCheck %s --check-prefixes=ANY,DO-FLOAT-SHRINK
4+
5+
declare double @llvm.cos.f64(double)
6+
declare float @llvm.cos.f32(float)
7+
8+
declare double @llvm.sin.f64(double)
9+
declare float @llvm.sin.f32(float)
10+
11+
; cos -> cosf
12+
13+
define float @cos_no_fastmath(float %f) {
14+
; NO-FLOAT-SHRINK-LABEL: @cos_no_fastmath(
15+
; NO-FLOAT-SHRINK-NEXT: [[D:%.*]] = fpext float [[F:%.*]] to double
16+
; NO-FLOAT-SHRINK-NEXT: [[RESULT:%.*]] = call double @llvm.cos.f64(double [[D]])
17+
; NO-FLOAT-SHRINK-NEXT: [[TRUNCATED_RESULT:%.*]] = fptrunc double [[RESULT]] to float
18+
; NO-FLOAT-SHRINK-NEXT: ret float [[TRUNCATED_RESULT]]
19+
;
20+
; DO-FLOAT-SHRINK-LABEL: @cos_no_fastmath(
21+
; DO-FLOAT-SHRINK-NEXT: [[TMP1:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])
22+
; DO-FLOAT-SHRINK-NEXT: ret float [[TMP1]]
23+
;
24+
%d = fpext float %f to double
25+
%result = call double @llvm.cos.f64(double %d)
26+
%truncated_result = fptrunc double %result to float
27+
ret float %truncated_result
28+
}
29+
30+
define float @cos_fastmath(float %f) {
31+
; ANY-LABEL: @cos_fastmath(
32+
; ANY-NEXT: [[TMP1:%.*]] = call fast float @llvm.cos.f32(float [[F:%.*]])
33+
; ANY-NEXT: ret float [[TMP1]]
34+
;
35+
%d = fpext float %f to double
36+
%result = call fast double @llvm.cos.f64(double %d)
37+
%truncated_result = fptrunc double %result to float
38+
ret float %truncated_result
39+
}
40+
41+
; sin -> sinf
42+
43+
define float @sin_no_fastmath(float %f) {
44+
; NO-FLOAT-SHRINK-LABEL: @sin_no_fastmath(
45+
; NO-FLOAT-SHRINK-NEXT: [[D:%.*]] = fpext float [[F:%.*]] to double
46+
; NO-FLOAT-SHRINK-NEXT: [[RESULT:%.*]] = call double @llvm.sin.f64(double [[D]])
47+
; NO-FLOAT-SHRINK-NEXT: [[TRUNCATED_RESULT:%.*]] = fptrunc double [[RESULT]] to float
48+
; NO-FLOAT-SHRINK-NEXT: ret float [[TRUNCATED_RESULT]]
49+
;
50+
; DO-FLOAT-SHRINK-LABEL: @sin_no_fastmath(
51+
; DO-FLOAT-SHRINK-NEXT: [[TMP1:%.*]] = call float @llvm.sin.f32(float [[F:%.*]])
52+
; DO-FLOAT-SHRINK-NEXT: ret float [[TMP1]]
53+
;
54+
%d = fpext float %f to double
55+
%result = call double @llvm.sin.f64(double %d)
56+
%truncated_result = fptrunc double %result to float
57+
ret float %truncated_result
58+
}
59+
60+
define float @sin_fastmath(float %f) {
61+
; ANY-LABEL: @sin_fastmath(
62+
; ANY-NEXT: [[TMP1:%.*]] = call fast float @llvm.sin.f32(float [[F:%.*]])
63+
; ANY-NEXT: ret float [[TMP1]]
64+
;
65+
%d = fpext float %f to double
66+
%result = call fast double @llvm.sin.f64(double %d)
67+
%truncated_result = fptrunc double %result to float
68+
ret float %truncated_result
69+
}

0 commit comments

Comments
 (0)