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 +}