1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine -S < %s | FileCheck %s
3
4declare double @llvm.fabs.f64(double)
5declare float @llvm.fabs.f32(float)
6declare <4 x double> @llvm.fabs.v4f64(<4 x double>)
7declare void @use(double)
8
9declare double @llvm.copysign.f64(double, double)
10declare float @llvm.copysign.f32(float, float)
11
12define double @fabs_copysign(double %x) {
13; CHECK-LABEL: @fabs_copysign(
14; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
15; CHECK-NEXT:    ret double [[TMP1]]
16;
17  %f = tail call double @llvm.fabs.f64(double %x)
18  %div = fdiv nnan ninf double %x, %f
19  ret double %div
20}
21
22define double @fabs_copysign_commuted(double %x) {
23; CHECK-LABEL: @fabs_copysign_commuted(
24; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
25; CHECK-NEXT:    ret double [[TMP1]]
26;
27  %f = tail call double @llvm.fabs.f64(double %x)
28  %div = fdiv nnan ninf double %f, %x
29  ret double %div
30}
31
32define <4 x double> @fabs_copysign_vec(<4 x double> %x) {
33; CHECK-LABEL: @fabs_copysign_vec(
34; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf <4 x double> @llvm.copysign.v4f64(<4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, <4 x double> [[X:%.*]])
35; CHECK-NEXT:    ret <4 x double> [[TMP1]]
36;
37  %f = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
38  %div = fdiv nnan ninf <4 x double> %x, %f
39  ret <4 x double> %div
40}
41
42define <4 x double> @fabs_copysign_vec_commuted(<4 x double> %x) {
43; CHECK-LABEL: @fabs_copysign_vec_commuted(
44; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf <4 x double> @llvm.copysign.v4f64(<4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, <4 x double> [[X:%.*]])
45; CHECK-NEXT:    ret <4 x double> [[TMP1]]
46;
47  %f = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
48  %div = fdiv nnan ninf <4 x double> %f, %x
49  ret <4 x double> %div
50}
51
52define float @fabs_copysignf(float %x) {
53; CHECK-LABEL: @fabs_copysignf(
54; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]])
55; CHECK-NEXT:    ret float [[TMP1]]
56;
57  %f = tail call float @llvm.fabs.f32(float %x)
58  %div = fdiv nnan ninf float %x, %f
59  ret float %div
60}
61
62define double @fabs_copysign_use(double %x) {
63; CHECK-LABEL: @fabs_copysign_use(
64; CHECK-NEXT:    [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
65; CHECK-NEXT:    call void @use(double [[F]])
66; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf double @llvm.copysign.f64(double 1.000000e+00, double [[X]])
67; CHECK-NEXT:    ret double [[TMP1]]
68;
69  %f = tail call double @llvm.fabs.f64(double %x)
70  call void @use(double %f)
71  %div = fdiv nnan ninf double %x, %f
72  ret double %div
73}
74
75; Negative tests
76
77define double @fabs_copysign_mismatch(double %x, double %y) {
78; CHECK-LABEL: @fabs_copysign_mismatch(
79; CHECK-NEXT:    [[F:%.*]] = tail call double @llvm.fabs.f64(double [[Y:%.*]])
80; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X:%.*]], [[F]]
81; CHECK-NEXT:    ret double [[DIV]]
82;
83  %f = tail call double @llvm.fabs.f64(double %y)
84  %div = fdiv double %x, %f
85  ret double %div
86}
87
88define double @fabs_copysign_commuted_mismatch(double %x, double %y) {
89; CHECK-LABEL: @fabs_copysign_commuted_mismatch(
90; CHECK-NEXT:    [[F:%.*]] = tail call double @llvm.fabs.f64(double [[Y:%.*]])
91; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[F]], [[X:%.*]]
92; CHECK-NEXT:    ret double [[DIV]]
93;
94  %f = tail call double @llvm.fabs.f64(double %y)
95  %div = fdiv double %f, %x
96  ret double %div
97}
98
99define double @fabs_copysign_no_nnan(double %x) {
100; CHECK-LABEL: @fabs_copysign_no_nnan(
101; CHECK-NEXT:    [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
102; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf double [[X]], [[F]]
103; CHECK-NEXT:    ret double [[DIV]]
104;
105  %f = tail call double @llvm.fabs.f64(double %x)
106  %div = fdiv ninf double %x, %f
107  ret double %div
108}
109
110define double @fabs_copysign_no_ninf(double %x) {
111; CHECK-LABEL: @fabs_copysign_no_ninf(
112; CHECK-NEXT:    [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
113; CHECK-NEXT:    [[DIV:%.*]] = fdiv nnan double [[X]], [[F]]
114; CHECK-NEXT:    ret double [[DIV]]
115;
116  %f = tail call double @llvm.fabs.f64(double %x)
117  %div = fdiv nnan double %x, %f
118  ret double %div
119}
120