; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s declare double @cosh(double) declare float @coshf(float) declare fp128 @coshl(fp128) declare double @sinh(double) declare float @sinhf(float) declare fp128 @sinhl(fp128) declare double @tanh(double) declare float @tanhf(float) declare fp128 @tanhl(fp128) declare void @use(double) ; cosh(-x) -> cosh(x) define double @cosh_negated_arg(double %x) { ; CHECK-LABEL: @cosh_negated_arg( ; CHECK-NEXT: [[COSH:%.*]] = call double @cosh(double [[X:%.*]]) ; CHECK-NEXT: ret double [[COSH]] ; %neg = fneg double %x %r = call double @cosh(double %neg) ret double %r } define double @cosh_fsub_negated_arg(double %x) { ; CHECK-LABEL: @cosh_fsub_negated_arg( ; CHECK-NEXT: [[COSH:%.*]] = call double @cosh(double [[X:%.*]]) ; CHECK-NEXT: ret double [[COSH]] ; %neg = fsub double -0.0, %x %r = call double @cosh(double %neg) ret double %r } define float @coshf_negated_arg(float %x) { ; CHECK-LABEL: @coshf_negated_arg( ; CHECK-NEXT: [[COSH:%.*]] = call float @coshf(float [[X:%.*]]) ; CHECK-NEXT: ret float [[COSH]] ; %neg = fneg float %x %r = call float @coshf(float %neg) ret float %r } define fp128 @coshl_negated_arg(fp128 %x) { ; CHECK-LABEL: @coshl_negated_arg( ; CHECK-NEXT: [[COSH:%.*]] = call fp128 @coshl(fp128 [[X:%.*]]) ; CHECK-NEXT: ret fp128 [[COSH]] ; %neg = fneg fp128 %x %r = call fp128 @coshl(fp128 %neg) ret fp128 %r } ; cosh(fabs(x)) -> cosh(x) define double @cosh_fabs_arg(double %x) { ; CHECK-LABEL: @cosh_fabs_arg( ; CHECK-NEXT: [[COSH:%.*]] = call double @cosh(double [[X:%.*]]) ; CHECK-NEXT: ret double [[COSH]] ; %fabs = call double @llvm.fabs.f64(double %x) %r = call double @cosh(double %fabs) ret double %r } declare double @llvm.fabs.f64(double) ; sinh(-x) -> -sinh(x) define double @sinh_negated_arg(double %x) { ; CHECK-LABEL: @sinh_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call double @sinh(double [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg double [[R]] ; CHECK-NEXT: ret double [[R1]] ; %neg = fneg double %x %r = call double @sinh(double %neg) ret double %r } define double @sinh_fsub_negated_arg(double %x) { ; CHECK-LABEL: @sinh_fsub_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call double @sinh(double [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg double [[R]] ; CHECK-NEXT: ret double [[R1]] ; %neg = fsub double -0.0, %x %r = call double @sinh(double %neg) ret double %r } define float @sinhf_negated_arg(float %x) { ; CHECK-LABEL: @sinhf_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call float @sinhf(float [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg float [[R]] ; CHECK-NEXT: ret float [[R1]] ; %neg = fneg float %x %r = call float @sinhf(float %neg) ret float %r } define fp128 @sinhl_negated_arg(fp128 %x) { ; CHECK-LABEL: @sinhl_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call fp128 @sinhl(fp128 [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg fp128 [[R]] ; CHECK-NEXT: ret fp128 [[R1]] ; %neg = fneg fp128 %x %r = call fp128 @sinhl(fp128 %neg) ret fp128 %r } ; -sinh(-x) -> sinh(x) define double @neg_sinh_negated_arg(double %x) { ; CHECK-LABEL: @neg_sinh_negated_arg( ; CHECK-NEXT: [[TMP1:%.*]] = call double @sinh(double [[X:%.*]]) ; CHECK-NEXT: ret double [[TMP1]] ; %neg = fneg double %x %r = call double @sinh(double %neg) %rn = fneg double %r ret double %rn } ; sinh(-x) not folded when fneg has multiple uses define double @sinh_negated_arg_extra_use(double %x) { ; CHECK-LABEL: @sinh_negated_arg_extra_use( ; CHECK-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = call double @sinh(double [[NEG]]) ; CHECK-NEXT: call void @use(double [[NEG]]) ; CHECK-NEXT: ret double [[R]] ; %neg = fneg double %x %r = call double @sinh(double %neg) call void @use(double %neg) ret double %r } ; tanh(-x) -> -tanh(x) define double @tanh_negated_arg(double %x) { ; CHECK-LABEL: @tanh_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call double @tanh(double [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg double [[R]] ; CHECK-NEXT: ret double [[R1]] ; %neg = fneg double %x %r = call double @tanh(double %neg) ret double %r } define double @tanh_fsub_negated_arg(double %x) { ; CHECK-LABEL: @tanh_fsub_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call double @tanh(double [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg double [[R]] ; CHECK-NEXT: ret double [[R1]] ; %neg = fsub double -0.0, %x %r = call double @tanh(double %neg) ret double %r } define float @tanhf_negated_arg(float %x) { ; CHECK-LABEL: @tanhf_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call float @tanhf(float [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg float [[R]] ; CHECK-NEXT: ret float [[R1]] ; %neg = fneg float %x %r = call float @tanhf(float %neg) ret float %r } define fp128 @tanhl_negated_arg(fp128 %x) { ; CHECK-LABEL: @tanhl_negated_arg( ; CHECK-NEXT: [[R:%.*]] = call fp128 @tanhl(fp128 [[R2:%.*]]) ; CHECK-NEXT: [[R1:%.*]] = fneg fp128 [[R]] ; CHECK-NEXT: ret fp128 [[R1]] ; %neg = fneg fp128 %x %r = call fp128 @tanhl(fp128 %neg) ret fp128 %r } ; -tanh(-x) -> tanh(x) define double @neg_tanh_negated_arg(double %x) { ; CHECK-LABEL: @neg_tanh_negated_arg( ; CHECK-NEXT: [[TMP1:%.*]] = call double @tanh(double [[X:%.*]]) ; CHECK-NEXT: ret double [[TMP1]] ; %neg = fneg double %x %r = call double @tanh(double %neg) %rn = fneg double %r ret double %rn }