llvm.org GIT mirror llvm / 9e79a4f
[InstCombine] InstCombine and InstSimplify for minimum and maximum Summary: Depends on D52765 Reviewers: aheejin, dschuff Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D52766 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344799 91177308-0d34-0410-b5e6-96231b3b80d8 Thomas Lively 11 months ago
9 changed file(s) with 920 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
48264826 }
48274827 break;
48284828 case Intrinsic::maxnum:
4829 case Intrinsic::minnum: {
4829 case Intrinsic::minnum:
4830 case Intrinsic::maximum:
4831 case Intrinsic::minimum: {
48304832 // If the arguments are the same, this is a no-op.
48314833 if (Op0 == Op1) return Op0;
48324834
4833 // If one argument is NaN or undef, return the other argument.
4834 if (match(Op0, m_CombineOr(m_NaN(), m_Undef()))) return Op1;
4835 if (match(Op1, m_CombineOr(m_NaN(), m_Undef()))) return Op0;
4835 // If one argument is undef, return the other argument.
4836 if (match(Op0, m_Undef()))
4837 return Op1;
4838 if (match(Op1, m_Undef()))
4839 return Op0;
4840
4841 // If one argument is NaN, return other or NaN appropriately.
4842 bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
4843 if (match(Op0, m_NaN()))
4844 return PropagateNaN ? Op0 : Op1;
4845 if (match(Op1, m_NaN()))
4846 return PropagateNaN ? Op1 : Op0;
48364847
48374848 // Min/max of the same operation with common operand:
48384849 // m(m(X, Y)), X --> m(X, Y) (4 commuted variants)
48454856 (M1->getOperand(0) == Op0 || M1->getOperand(1) == Op0))
48464857 return Op1;
48474858
4848 // minnum(X, -Inf) --> -Inf (and commuted variant)
4849 // maxnum(X, +Inf) --> +Inf (and commuted variant)
4850 bool UseNegInf = IID == Intrinsic::minnum;
4859 // min(X, -Inf) --> -Inf (and commuted variant)
4860 // max(X, +Inf) --> +Inf (and commuted variant)
4861 bool UseNegInf = IID == Intrinsic::minnum || IID == Intrinsic::minimum;
48514862 const APFloat *C;
48524863 if ((match(Op0, m_APFloat(C)) && C->isInfinity() &&
48534864 C->isNegative() == UseNegInf) ||
28972897 cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI,
28982898 SignBitOnly, Depth + 1));
28992899
2900 case Intrinsic::maximum:
2901 return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
2902 Depth + 1) ||
2903 cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, SignBitOnly,
2904 Depth + 1);
29002905 case Intrinsic::minnum:
2906 case Intrinsic::minimum:
29012907 return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
29022908 Depth + 1) &&
29032909 cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, SignBitOnly,
20192019 }
20202020
20212021 case Intrinsic::minnum:
2022 case Intrinsic::maxnum: {
2022 case Intrinsic::maxnum:
2023 case Intrinsic::minimum:
2024 case Intrinsic::maximum: {
20232025 Value *Arg0 = II->getArgOperand(0);
20242026 Value *Arg1 = II->getArgOperand(1);
20252027 // Canonicalize constants to the RHS.
20332035 if (match(Arg0, m_FNeg(m_Value(X))) && match(Arg1, m_FNeg(m_Value(Y))) &&
20342036 (Arg0->hasOneUse() || Arg1->hasOneUse())) {
20352037 // If both operands are negated, invert the call and negate the result:
2036 // minnum(-X, -Y) --> -(maxnum(X, Y))
2037 // maxnum(-X, -Y) --> -(minnum(X, Y))
2038 Intrinsic::ID NewIID = II->getIntrinsicID() == Intrinsic::maxnum ?
2039 Intrinsic::minnum : Intrinsic::maxnum;
2038 // min(-X, -Y) --> -(max(X, Y))
2039 // max(-X, -Y) --> -(min(X, Y))
2040 Intrinsic::ID NewIID;
2041 switch (II->getIntrinsicID()) {
2042 case Intrinsic::maxnum:
2043 NewIID = Intrinsic::minnum;
2044 break;
2045 case Intrinsic::minnum:
2046 NewIID = Intrinsic::maxnum;
2047 break;
2048 case Intrinsic::maximum:
2049 NewIID = Intrinsic::minimum;
2050 break;
2051 case Intrinsic::minimum:
2052 NewIID = Intrinsic::maximum;
2053 break;
2054 default:
2055 llvm_unreachable("unexpected intrinsic ID");
2056 }
20402057 Value *NewCall = Builder.CreateBinaryIntrinsic(NewIID, X, Y, II);
20412058 Instruction *FNeg = BinaryOperator::CreateFNeg(NewCall);
20422059 FNeg->copyIRFlags(II);
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -instcombine < %s | FileCheck %s
2
3 declare float @llvm.maximum.f32(float, float)
4 declare <2 x float> @llvm.maximum.v2f32(<2 x float>, <2 x float>)
5 declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>)
6
7 declare double @llvm.maximum.f64(double, double)
8 declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
9
10 define float @constant_fold_maximum_f32() {
11 ; CHECK-LABEL: @constant_fold_maximum_f32(
12 ; CHECK-NEXT: ret float 2.000000e+00
13 ;
14 %x = call float @llvm.maximum.f32(float 1.0, float 2.0)
15 ret float %x
16 }
17
18 define float @constant_fold_maximum_f32_inv() {
19 ; CHECK-LABEL: @constant_fold_maximum_f32_inv(
20 ; CHECK-NEXT: ret float 2.000000e+00
21 ;
22 %x = call float @llvm.maximum.f32(float 2.0, float 1.0)
23 ret float %x
24 }
25
26 define float @constant_fold_maximum_f32_nan0() {
27 ; CHECK-LABEL: @constant_fold_maximum_f32_nan0(
28 ; CHECK-NEXT: ret float 0x7FF8000000000000
29 ;
30 %x = call float @llvm.maximum.f32(float 0x7FF8000000000000, float 2.0)
31 ret float %x
32 }
33
34 define float @constant_fold_maximum_f32_nan1() {
35 ; CHECK-LABEL: @constant_fold_maximum_f32_nan1(
36 ; CHECK-NEXT: ret float 0x7FF8000000000000
37 ;
38 %x = call float @llvm.maximum.f32(float 2.0, float 0x7FF8000000000000)
39 ret float %x
40 }
41
42 define float @constant_fold_maximum_f32_nan_nan() {
43 ; CHECK-LABEL: @constant_fold_maximum_f32_nan_nan(
44 ; CHECK-NEXT: ret float 0x7FF8000000000000
45 ;
46 %x = call float @llvm.maximum.f32(float 0x7FF8000000000000, float 0x7FF8000000000000)
47 ret float %x
48 }
49
50 define float @constant_fold_maximum_f32_p0_p0() {
51 ; CHECK-LABEL: @constant_fold_maximum_f32_p0_p0(
52 ; CHECK-NEXT: ret float 0.000000e+00
53 ;
54 %x = call float @llvm.maximum.f32(float 0.0, float 0.0)
55 ret float %x
56 }
57
58 define float @constant_fold_maximum_f32_p0_n0() {
59 ; CHECK-LABEL: @constant_fold_maximum_f32_p0_n0(
60 ; CHECK-NEXT: ret float 0.000000e+00
61 ;
62 %x = call float @llvm.maximum.f32(float 0.0, float -0.0)
63 ret float %x
64 }
65
66 define float @constant_fold_maximum_f32_n0_p0() {
67 ; CHECK-LABEL: @constant_fold_maximum_f32_n0_p0(
68 ; CHECK-NEXT: ret float 0.000000e+00
69 ;
70 %x = call float @llvm.maximum.f32(float -0.0, float 0.0)
71 ret float %x
72 }
73
74 define float @constant_fold_maximum_f32_n0_n0() {
75 ; CHECK-LABEL: @constant_fold_maximum_f32_n0_n0(
76 ; CHECK-NEXT: ret float -0.000000e+00
77 ;
78 %x = call float @llvm.maximum.f32(float -0.0, float -0.0)
79 ret float %x
80 }
81
82 define <4 x float> @constant_fold_maximum_v4f32() {
83 ; CHECK-LABEL: @constant_fold_maximum_v4f32(
84 ; CHECK-NEXT: ret <4 x float>
85 ;
86 %x = call <4 x float> @llvm.maximum.v4f32(<4 x float> , <4 x float> )
87 ret <4 x float> %x
88 }
89
90 define double @constant_fold_maximum_f64() {
91 ; CHECK-LABEL: @constant_fold_maximum_f64(
92 ; CHECK-NEXT: ret double 2.000000e+00
93 ;
94 %x = call double @llvm.maximum.f64(double 1.0, double 2.0)
95 ret double %x
96 }
97
98 define double @constant_fold_maximum_f64_nan0() {
99 ; CHECK-LABEL: @constant_fold_maximum_f64_nan0(
100 ; CHECK-NEXT: ret double 0x7FF8000000000000
101 ;
102 %x = call double @llvm.maximum.f64(double 0x7FF8000000000000, double 2.0)
103 ret double %x
104 }
105
106 define double @constant_fold_maximum_f64_nan1() {
107 ; CHECK-LABEL: @constant_fold_maximum_f64_nan1(
108 ; CHECK-NEXT: ret double 0x7FF8000000000000
109 ;
110 %x = call double @llvm.maximum.f64(double 2.0, double 0x7FF8000000000000)
111 ret double %x
112 }
113
114 define double @constant_fold_maximum_f64_nan_nan() {
115 ; CHECK-LABEL: @constant_fold_maximum_f64_nan_nan(
116 ; CHECK-NEXT: ret double 0x7FF8000000000000
117 ;
118 %x = call double @llvm.maximum.f64(double 0x7FF8000000000000, double 0x7FF8000000000000)
119 ret double %x
120 }
121
122 define float @canonicalize_constant_maximum_f32(float %x) {
123 ; CHECK-LABEL: @canonicalize_constant_maximum_f32(
124 ; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float 1.000000e+00)
125 ; CHECK-NEXT: ret float [[Y]]
126 ;
127 %y = call float @llvm.maximum.f32(float 1.0, float %x)
128 ret float %y
129 }
130
131 define float @maximum_f32_nan_val(float %x) {
132 ; CHECK-LABEL: @maximum_f32_nan_val(
133 ; CHECK-NEXT: ret float 0x7FF8000000000000
134 ;
135 %y = call float @llvm.maximum.f32(float 0x7FF8000000000000, float %x)
136 ret float %y
137 }
138
139 define float @maximum_f32_val_nan(float %x) {
140 ; CHECK-LABEL: @maximum_f32_val_nan(
141 ; CHECK-NEXT: ret float 0x7FF8000000000000
142 ;
143 %y = call float @llvm.maximum.f32(float %x, float 0x7FF8000000000000)
144 ret float %y
145 }
146
147 define float @maximum4(float %x, float %y, float %z, float %w) {
148 ; CHECK-LABEL: @maximum4(
149 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
150 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maximum.f32(float [[Z:%.*]], float [[W:%.*]])
151 ; CHECK-NEXT: [[C:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[B]])
152 ; CHECK-NEXT: ret float [[C]]
153 ;
154 %a = call float @llvm.maximum.f32(float %x, float %y)
155 %b = call float @llvm.maximum.f32(float %z, float %w)
156 %c = call float @llvm.maximum.f32(float %a, float %b)
157 ret float %c
158 }
159
160 ; PR37404 - https://bugs.llvm.org/show_bug.cgi?id=37404
161
162 define <2 x float> @neg_neg(<2 x float> %x, <2 x float> %y) {
163 ; CHECK-LABEL: @neg_neg(
164 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.minimum.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]])
165 ; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> , [[TMP1]]
166 ; CHECK-NEXT: ret <2 x float> [[R]]
167 ;
168 %negx = fsub <2 x float> , %x
169 %negy = fsub <2 x float> , %y
170 %r = call <2 x float> @llvm.maximum.v2f32(<2 x float> %negx, <2 x float> %negy)
171 ret <2 x float> %r
172 }
173
174 ; FMF is not required, but it should be propagated from the intrinsic (not the fnegs).
175
176 define float @neg_neg_vec_fmf(float %x, float %y) {
177 ; CHECK-LABEL: @neg_neg_vec_fmf(
178 ; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
179 ; CHECK-NEXT: [[R:%.*]] = fsub fast float -0.000000e+00, [[TMP1]]
180 ; CHECK-NEXT: ret float [[R]]
181 ;
182 %negx = fsub arcp float -0.0, %x
183 %negy = fsub afn float -0.0, %y
184 %r = call fast float @llvm.maximum.f32(float %negx, float %negy)
185 ret float %r
186 }
187
188 ; 1 extra use of an intermediate value should still allow the fold,
189 ; but 2 would require more instructions than we started with.
190
191 declare void @use(float)
192 define float @neg_neg_extra_use_x(float %x, float %y) {
193 ; CHECK-LABEL: @neg_neg_extra_use_x(
194 ; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
195 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[Y:%.*]])
196 ; CHECK-NEXT: [[R:%.*]] = fsub float -0.000000e+00, [[TMP1]]
197 ; CHECK-NEXT: call void @use(float [[NEGX]])
198 ; CHECK-NEXT: ret float [[R]]
199 ;
200 %negx = fsub float -0.0, %x
201 %negy = fsub float -0.0, %y
202 %r = call float @llvm.maximum.f32(float %negx, float %negy)
203 call void @use(float %negx)
204 ret float %r
205 }
206
207 define float @neg_neg_extra_use_y(float %x, float %y) {
208 ; CHECK-LABEL: @neg_neg_extra_use_y(
209 ; CHECK-NEXT: [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
210 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y]])
211 ; CHECK-NEXT: [[R:%.*]] = fsub float -0.000000e+00, [[TMP1]]
212 ; CHECK-NEXT: call void @use(float [[NEGY]])
213 ; CHECK-NEXT: ret float [[R]]
214 ;
215 %negx = fsub float -0.0, %x
216 %negy = fsub float -0.0, %y
217 %r = call float @llvm.maximum.f32(float %negx, float %negy)
218 call void @use(float %negy)
219 ret float %r
220 }
221
222 define float @neg_neg_extra_use_x_and_y(float %x, float %y) {
223 ; CHECK-LABEL: @neg_neg_extra_use_x_and_y(
224 ; CHECK-NEXT: [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
225 ; CHECK-NEXT: [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
226 ; CHECK-NEXT: [[R:%.*]] = call float @llvm.maximum.f32(float [[NEGX]], float [[NEGY]])
227 ; CHECK-NEXT: call void @use(float [[NEGX]])
228 ; CHECK-NEXT: call void @use(float [[NEGY]])
229 ; CHECK-NEXT: ret float [[R]]
230 ;
231 %negx = fsub float -0.0, %x
232 %negy = fsub float -0.0, %y
233 %r = call float @llvm.maximum.f32(float %negx, float %negy)
234 call void @use(float %negx)
235 call void @use(float %negy)
236 ret float %r
237 }
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -instcombine < %s | FileCheck %s
2
3 declare float @llvm.minimum.f32(float, float)
4 declare float @llvm.minimum.v2f32(<2 x float>, <2 x float>)
5 declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>)
6
7 declare double @llvm.minimum.f64(double, double)
8 declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
9
10 declare float @llvm.maximum.f32(float, float)
11
12 define float @constant_fold_minimum_f32() {
13 ; CHECK-LABEL: @constant_fold_minimum_f32(
14 ; CHECK-NEXT: ret float 1.000000e+00
15 ;
16 %x = call float @llvm.minimum.f32(float 1.0, float 2.0)
17 ret float %x
18 }
19
20 define float @constant_fold_minimum_f32_inv() {
21 ; CHECK-LABEL: @constant_fold_minimum_f32_inv(
22 ; CHECK-NEXT: ret float 1.000000e+00
23 ;
24 %x = call float @llvm.minimum.f32(float 2.0, float 1.0)
25 ret float %x
26 }
27
28 define float @constant_fold_minimum_f32_nan0() {
29 ; CHECK-LABEL: @constant_fold_minimum_f32_nan0(
30 ; CHECK-NEXT: ret float 0x7FF8000000000000
31 ;
32 %x = call float @llvm.minimum.f32(float 0x7FF8000000000000, float 2.0)
33 ret float %x
34 }
35
36 define float @constant_fold_minimum_f32_nan1() {
37 ; CHECK-LABEL: @constant_fold_minimum_f32_nan1(
38 ; CHECK-NEXT: ret float 0x7FF8000000000000
39 ;
40 %x = call float @llvm.minimum.f32(float 2.0, float 0x7FF8000000000000)
41 ret float %x
42 }
43
44 define float @constant_fold_minimum_f32_nan_nan() {
45 ; CHECK-LABEL: @constant_fold_minimum_f32_nan_nan(
46 ; CHECK-NEXT: ret float 0x7FF8000000000000
47 ;
48 %x = call float @llvm.minimum.f32(float 0x7FF8000000000000, float 0x7FF8000000000000)
49 ret float %x
50 }
51
52 define float @constant_fold_minimum_f32_p0_p0() {
53 ; CHECK-LABEL: @constant_fold_minimum_f32_p0_p0(
54 ; CHECK-NEXT: ret float 0.000000e+00
55 ;
56 %x = call float @llvm.minimum.f32(float 0.0, float 0.0)
57 ret float %x
58 }
59
60 define float @constant_fold_minimum_f32_p0_n0() {
61 ; CHECK-LABEL: @constant_fold_minimum_f32_p0_n0(
62 ; CHECK-NEXT: ret float -0.000000e+00
63 ;
64 %x = call float @llvm.minimum.f32(float 0.0, float -0.0)
65 ret float %x
66 }
67
68 define float @constant_fold_minimum_f32_n0_p0() {
69 ; CHECK-LABEL: @constant_fold_minimum_f32_n0_p0(
70 ; CHECK-NEXT: ret float -0.000000e+00
71 ;
72 %x = call float @llvm.minimum.f32(float -0.0, float 0.0)
73 ret float %x
74 }
75
76 define float @constant_fold_minimum_f32_n0_n0() {
77 ; CHECK-LABEL: @constant_fold_minimum_f32_n0_n0(
78 ; CHECK-NEXT: ret float -0.000000e+00
79 ;
80 %x = call float @llvm.minimum.f32(float -0.0, float -0.0)
81 ret float %x
82 }
83
84 define <4 x float> @constant_fold_minimum_v4f32() {
85 ; CHECK-LABEL: @constant_fold_minimum_v4f32(
86 ; CHECK-NEXT: ret <4 x float>
87 ;
88 %x = call <4 x float> @llvm.minimum.v4f32(<4 x float> , <4 x float> )
89 ret <4 x float> %x
90 }
91
92 define double @constant_fold_minimum_f64() {
93 ; CHECK-LABEL: @constant_fold_minimum_f64(
94 ; CHECK-NEXT: ret double 1.000000e+00
95 ;
96 %x = call double @llvm.minimum.f64(double 1.0, double 2.0)
97 ret double %x
98 }
99
100 define double @constant_fold_minimum_f64_nan0() {
101 ; CHECK-LABEL: @constant_fold_minimum_f64_nan0(
102 ; CHECK-NEXT: ret double 0x7FF8000000000000
103 ;
104 %x = call double @llvm.minimum.f64(double 0x7FF8000000000000, double 2.0)
105 ret double %x
106 }
107
108 define double @constant_fold_minimum_f64_nan1() {
109 ; CHECK-LABEL: @constant_fold_minimum_f64_nan1(
110 ; CHECK-NEXT: ret double 0x7FF8000000000000
111 ;
112 %x = call double @llvm.minimum.f64(double 2.0, double 0x7FF8000000000000)
113 ret double %x
114 }
115
116 define double @constant_fold_minimum_f64_nan_nan() {
117 ; CHECK-LABEL: @constant_fold_minimum_f64_nan_nan(
118 ; CHECK-NEXT: ret double 0x7FF8000000000000
119 ;
120 %x = call double @llvm.minimum.f64(double 0x7FF8000000000000, double 0x7FF8000000000000)
121 ret double %x
122 }
123
124 define float @canonicalize_constant_minimum_f32(float %x) {
125 ; CHECK-LABEL: @canonicalize_constant_minimum_f32(
126 ; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float 1.000000e+00)
127 ; CHECK-NEXT: ret float [[Y]]
128 ;
129 %y = call float @llvm.minimum.f32(float 1.0, float %x)
130 ret float %y
131 }
132
133 define float @minimum_f32_nan_val(float %x) {
134 ; CHECK-LABEL: @minimum_f32_nan_val(
135 ; CHECK-NEXT: ret float 0x7FF8000000000000
136 ;
137 %y = call float @llvm.minimum.f32(float 0x7FF8000000000000, float %x)
138 ret float %y
139 }
140
141 define float @minimum_f32_val_nan(float %x) {
142 ; CHECK-LABEL: @minimum_f32_val_nan(
143 ; CHECK-NEXT: ret float 0x7FF8000000000000
144 ;
145 %y = call float @llvm.minimum.f32(float %x, float 0x7FF8000000000000)
146 ret float %y
147 }
148
149 define float @minimum4(float %x, float %y, float %z, float %w) {
150 ; CHECK-LABEL: @minimum4(
151 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
152 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minimum.f32(float [[Z:%.*]], float [[W:%.*]])
153 ; CHECK-NEXT: [[C:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[B]])
154 ; CHECK-NEXT: ret float [[C]]
155 ;
156 %a = call float @llvm.minimum.f32(float %x, float %y)
157 %b = call float @llvm.minimum.f32(float %z, float %w)
158 %c = call float @llvm.minimum.f32(float %a, float %b)
159 ret float %c
160 }
161
162 define float @minimum_x_maximum_x_y(float %x, float %y) {
163 ; CHECK-LABEL: @minimum_x_maximum_x_y(
164 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
165 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[A]])
166 ; CHECK-NEXT: ret float [[B]]
167 ;
168 %a = call float @llvm.maximum.f32(float %x, float %y)
169 %b = call float @llvm.minimum.f32(float %x, float %a)
170 ret float %b
171 }
172
173 define float @maximum_x_minimum_x_y(float %x, float %y) {
174 ; CHECK-LABEL: @maximum_x_minimum_x_y(
175 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
176 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maximum.f32(float [[X]], float [[A]])
177 ; CHECK-NEXT: ret float [[B]]
178 ;
179 %a = call float @llvm.minimum.f32(float %x, float %y)
180 %b = call float @llvm.maximum.f32(float %x, float %a)
181 ret float %b
182 }
183
184 ; PR37405 - https://bugs.llvm.org/show_bug.cgi?id=37405
185
186 define double @neg_neg(double %x, double %y) {
187 ; CHECK-LABEL: @neg_neg(
188 ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X:%.*]], double [[Y:%.*]])
189 ; CHECK-NEXT: [[R:%.*]] = fsub double -0.000000e+00, [[TMP1]]
190 ; CHECK-NEXT: ret double [[R]]
191 ;
192 %negx = fsub double -0.0, %x
193 %negy = fsub double -0.0, %y
194 %r = call double @llvm.minimum.f64(double %negx, double %negy)
195 ret double %r
196 }
197
198 ; FMF is not required, but it should be propagated from the intrinsic (not the fnegs).
199 ; Also, make sure this works with vectors.
200
201 define <2 x double> @neg_neg_vec_fmf(<2 x double> %x, <2 x double> %y) {
202 ; CHECK-LABEL: @neg_neg_vec_fmf(
203 ; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf <2 x double> @llvm.maximum.v2f64(<2 x double> [[X:%.*]], <2 x double> [[Y:%.*]])
204 ; CHECK-NEXT: [[R:%.*]] = fsub nnan ninf <2 x double> , [[TMP1]]
205 ; CHECK-NEXT: ret <2 x double> [[R]]
206 ;
207 %negx = fsub reassoc <2 x double> , %x
208 %negy = fsub fast <2 x double> , %y
209 %r = call nnan ninf <2 x double> @llvm.minimum.v2f64(<2 x double> %negx, <2 x double> %negy)
210 ret <2 x double> %r
211 }
212
213 ; 1 extra use of an intermediate value should still allow the fold,
214 ; but 2 would require more instructions than we started with.
215
216 declare void @use(double)
217 define double @neg_neg_extra_use_x(double %x, double %y) {
218 ; CHECK-LABEL: @neg_neg_extra_use_x(
219 ; CHECK-NEXT: [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
220 ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X]], double [[Y:%.*]])
221 ; CHECK-NEXT: [[R:%.*]] = fsub double -0.000000e+00, [[TMP1]]
222 ; CHECK-NEXT: call void @use(double [[NEGX]])
223 ; CHECK-NEXT: ret double [[R]]
224 ;
225 %negx = fsub double -0.0, %x
226 %negy = fsub double -0.0, %y
227 %r = call double @llvm.minimum.f64(double %negx, double %negy)
228 call void @use(double %negx)
229 ret double %r
230 }
231
232 define double @neg_neg_extra_use_y(double %x, double %y) {
233 ; CHECK-LABEL: @neg_neg_extra_use_y(
234 ; CHECK-NEXT: [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]]
235 ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X:%.*]], double [[Y]])
236 ; CHECK-NEXT: [[R:%.*]] = fsub double -0.000000e+00, [[TMP1]]
237 ; CHECK-NEXT: call void @use(double [[NEGY]])
238 ; CHECK-NEXT: ret double [[R]]
239 ;
240 %negx = fsub double -0.0, %x
241 %negy = fsub double -0.0, %y
242 %r = call double @llvm.minimum.f64(double %negx, double %negy)
243 call void @use(double %negy)
244 ret double %r
245 }
246
247 define double @neg_neg_extra_use_x_and_y(double %x, double %y) {
248 ; CHECK-LABEL: @neg_neg_extra_use_x_and_y(
249 ; CHECK-NEXT: [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
250 ; CHECK-NEXT: [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]]
251 ; CHECK-NEXT: [[R:%.*]] = call double @llvm.minimum.f64(double [[NEGX]], double [[NEGY]])
252 ; CHECK-NEXT: call void @use(double [[NEGX]])
253 ; CHECK-NEXT: call void @use(double [[NEGY]])
254 ; CHECK-NEXT: ret double [[R]]
255 ;
256 %negx = fsub double -0.0, %x
257 %negy = fsub double -0.0, %y
258 %r = call double @llvm.minimum.f64(double %negx, double %negy)
259 call void @use(double %negx)
260 call void @use(double %negy)
261 ret double %r
262 }
789789 ret float %val
790790 }
791791
792 declare float @llvm.minimum.f32(float, float)
793 declare float @llvm.maximum.f32(float, float)
794 declare double @llvm.minimum.f64(double, double)
795 declare double @llvm.maximum.f64(double, double)
796 declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
797 declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
798
799 ; From the LangRef for minimum/maximum:
800 ; "If either operand is a NaN, returns NaN."
801
802 define double @maximum_nan_op0(double %x) {
803 ; CHECK-LABEL: @maximum_nan_op0(
804 ; CHECK-NEXT: ret double 0x7FF8000000000000
805 ;
806 %r = call double @llvm.maximum.f64(double 0x7ff8000000000000, double %x)
807 ret double %r
808 }
809
810 define double @maximum_nan_op1(double %x) {
811 ; CHECK-LABEL: @maximum_nan_op1(
812 ; CHECK-NEXT: ret double 0x7FF800000000DEAD
813 ;
814 %r = call double @llvm.maximum.f64(double %x, double 0x7ff800000000dead)
815 ret double %r
816 }
817
818 define double @minimum_nan_op0(double %x) {
819 ; CHECK-LABEL: @minimum_nan_op0(
820 ; CHECK-NEXT: ret double 0x7FF8000DEAD00000
821 ;
822 %r = call double @llvm.minimum.f64(double 0x7ff8000dead00000, double %x)
823 ret double %r
824 }
825
826 define double @minimum_nan_op1(double %x) {
827 ; CHECK-LABEL: @minimum_nan_op1(
828 ; CHECK-NEXT: ret double 0x7FF800DEAD00DEAD
829 ;
830 %r = call double @llvm.minimum.f64(double %x, double 0x7ff800dead00dead)
831 ret double %r
832 }
833
834 define <2 x double> @maximum_nan_op0_vec(<2 x double> %x) {
835 ; CHECK-LABEL: @maximum_nan_op0_vec(
836 ; CHECK-NEXT: ret <2 x double>
837 ;
838 %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> , <2 x double> %x)
839 ret <2 x double> %r
840 }
841
842 define <2 x double> @maximum_nan_op1_vec(<2 x double> %x) {
843 ; CHECK-LABEL: @maximum_nan_op1_vec(
844 ; CHECK-NEXT: ret <2 x double>
845 ;
846 %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> )
847 ret <2 x double> %r
848 }
849
850 define <2 x double> @minimum_nan_op0_vec(<2 x double> %x) {
851 ; CHECK-LABEL: @minimum_nan_op0_vec(
852 ; CHECK-NEXT: ret <2 x double>
853 ;
854 %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> , <2 x double> %x)
855 ret <2 x double> %r
856 }
857
858 define <2 x double> @minimum_nan_op1_vec(<2 x double> %x) {
859 ; CHECK-LABEL: @minimum_nan_op1_vec(
860 ; CHECK-NEXT: ret <2 x double>
861 ;
862 %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> )
863 ret <2 x double> %r
864 }
865
866 define float @maximum_undef_op1(float %x) {
867 ; CHECK-LABEL: @maximum_undef_op1(
868 ; CHECK-NEXT: ret float [[X:%.*]]
869 ;
870 %val = call float @llvm.maximum.f32(float %x, float undef)
871 ret float %val
872 }
873
874 define float @maximum_undef_op0(float %x) {
875 ; CHECK-LABEL: @maximum_undef_op0(
876 ; CHECK-NEXT: ret float [[X:%.*]]
877 ;
878 %val = call float @llvm.maximum.f32(float undef, float %x)
879 ret float %val
880 }
881
882 define float @minimum_undef_op1(float %x) {
883 ; CHECK-LABEL: @minimum_undef_op1(
884 ; CHECK-NEXT: ret float [[X:%.*]]
885 ;
886 %val = call float @llvm.minimum.f32(float %x, float undef)
887 ret float %val
888 }
889
890 define float @minimum_undef_op0(float %x) {
891 ; CHECK-LABEL: @minimum_undef_op0(
892 ; CHECK-NEXT: ret float [[X:%.*]]
893 ;
894 %val = call float @llvm.minimum.f32(float undef, float %x)
895 ret float %val
896 }
897
898 define float @minimum_undef_undef(float %x) {
899 ; CHECK-LABEL: @minimum_undef_undef(
900 ; CHECK-NEXT: ret float undef
901 ;
902 %val = call float @llvm.minimum.f32(float undef, float undef)
903 ret float %val
904 }
905
906 define float @maximum_undef_undef(float %x) {
907 ; CHECK-LABEL: @maximum_undef_undef(
908 ; CHECK-NEXT: ret float undef
909 ;
910 %val = call float @llvm.maximum.f32(float undef, float undef)
911 ret float %val
912 }
913
914 define float @minimum_same_args(float %x) {
915 ; CHECK-LABEL: @minimum_same_args(
916 ; CHECK-NEXT: ret float [[X:%.*]]
917 ;
918 %y = call float @llvm.minimum.f32(float %x, float %x)
919 ret float %y
920 }
921
922 define float @maximum_same_args(float %x) {
923 ; CHECK-LABEL: @maximum_same_args(
924 ; CHECK-NEXT: ret float [[X:%.*]]
925 ;
926 %y = call float @llvm.maximum.f32(float %x, float %x)
927 ret float %y
928 }
929
930 define float @minimum_x_minimum_x_y(float %x, float %y) {
931 ; CHECK-LABEL: @minimum_x_minimum_x_y(
932 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
933 ; CHECK-NEXT: ret float [[A]]
934 ;
935 %a = call float @llvm.minimum.f32(float %x, float %y)
936 %b = call float @llvm.minimum.f32(float %x, float %a)
937 ret float %b
938 }
939
940 define float @minimum_y_minimum_x_y(float %x, float %y) {
941 ; CHECK-LABEL: @minimum_y_minimum_x_y(
942 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
943 ; CHECK-NEXT: ret float [[A]]
944 ;
945 %a = call float @llvm.minimum.f32(float %x, float %y)
946 %b = call float @llvm.minimum.f32(float %y, float %a)
947 ret float %b
948 }
949
950 define float @minimum_x_y_minimum_x(float %x, float %y) {
951 ; CHECK-LABEL: @minimum_x_y_minimum_x(
952 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
953 ; CHECK-NEXT: ret float [[A]]
954 ;
955 %a = call float @llvm.minimum.f32(float %x, float %y)
956 %b = call float @llvm.minimum.f32(float %a, float %x)
957 ret float %b
958 }
959
960 define float @minimum_x_y_minimum_y(float %x, float %y) {
961 ; CHECK-LABEL: @minimum_x_y_minimum_y(
962 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
963 ; CHECK-NEXT: ret float [[A]]
964 ;
965 %a = call float @llvm.minimum.f32(float %x, float %y)
966 %b = call float @llvm.minimum.f32(float %a, float %y)
967 ret float %b
968 }
969
970 ; negative test
971
972 define float @minimum_z_minimum_x_y(float %x, float %y, float %z) {
973 ; CHECK-LABEL: @minimum_z_minimum_x_y(
974 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
975 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minimum.f32(float [[Z:%.*]], float [[A]])
976 ; CHECK-NEXT: ret float [[B]]
977 ;
978 %a = call float @llvm.minimum.f32(float %x, float %y)
979 %b = call float @llvm.minimum.f32(float %z, float %a)
980 ret float %b
981 }
982
983 ; negative test
984
985 define float @minimum_x_y_minimum_z(float %x, float %y, float %z) {
986 ; CHECK-LABEL: @minimum_x_y_minimum_z(
987 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
988 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[Z:%.*]])
989 ; CHECK-NEXT: ret float [[B]]
990 ;
991 %a = call float @llvm.minimum.f32(float %x, float %y)
992 %b = call float @llvm.minimum.f32(float %a, float %z)
993 ret float %b
994 }
995
996 ; minimum(X, -INF) --> -INF
997
998 define float @minimum_neginf(float %x) {
999 ; CHECK-LABEL: @minimum_neginf(
1000 ; CHECK-NEXT: ret float 0xFFF0000000000000
1001 ;
1002 %val = call float @llvm.minimum.f32(float %x, float 0xFFF0000000000000)
1003 ret float %val
1004 }
1005
1006 define <2 x double> @minimum_neginf_commute_vec(<2 x double> %x) {
1007 ; CHECK-LABEL: @minimum_neginf_commute_vec(
1008 ; CHECK-NEXT: ret <2 x double>
1009 ;
1010 %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> , <2 x double> %x)
1011 ret <2 x double> %r
1012 }
1013
1014 ; negative test
1015
1016 define float @minimum_inf(float %x) {
1017 ; CHECK-LABEL: @minimum_inf(
1018 ; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.minimum.f32(float 0x7FF0000000000000, float [[X:%.*]])
1019 ; CHECK-NEXT: ret float [[VAL]]
1020 ;
1021 %val = call float @llvm.minimum.f32(float 0x7FF0000000000000, float %x)
1022 ret float %val
1023 }
1024 define float @maximum_x_maximum_x_y(float %x, float %y) {
1025 ; CHECK-LABEL: @maximum_x_maximum_x_y(
1026 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1027 ; CHECK-NEXT: ret float [[A]]
1028 ;
1029 %a = call float @llvm.maximum.f32(float %x, float %y)
1030 %b = call float @llvm.maximum.f32(float %x, float %a)
1031 ret float %b
1032 }
1033
1034 define float @maximum_y_maximum_x_y(float %x, float %y) {
1035 ; CHECK-LABEL: @maximum_y_maximum_x_y(
1036 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1037 ; CHECK-NEXT: ret float [[A]]
1038 ;
1039 %a = call float @llvm.maximum.f32(float %x, float %y)
1040 %b = call float @llvm.maximum.f32(float %y, float %a)
1041 ret float %b
1042 }
1043
1044 define float @maximum_x_y_maximum_x(float %x, float %y) {
1045 ; CHECK-LABEL: @maximum_x_y_maximum_x(
1046 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1047 ; CHECK-NEXT: ret float [[A]]
1048 ;
1049 %a = call float @llvm.maximum.f32(float %x, float %y)
1050 %b = call float @llvm.maximum.f32(float %a, float %x)
1051 ret float %b
1052 }
1053
1054 define float @maximum_x_y_maximum_y(float %x, float %y) {
1055 ; CHECK-LABEL: @maximum_x_y_maximum_y(
1056 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1057 ; CHECK-NEXT: ret float [[A]]
1058 ;
1059 %a = call float @llvm.maximum.f32(float %x, float %y)
1060 %b = call float @llvm.maximum.f32(float %a, float %y)
1061 ret float %b
1062 }
1063
1064 ; negative test
1065
1066 define float @maximum_z_maximum_x_y(float %x, float %y, float %z) {
1067 ; CHECK-LABEL: @maximum_z_maximum_x_y(
1068 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1069 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maximum.f32(float [[Z:%.*]], float [[A]])
1070 ; CHECK-NEXT: ret float [[B]]
1071 ;
1072 %a = call float @llvm.maximum.f32(float %x, float %y)
1073 %b = call float @llvm.maximum.f32(float %z, float %a)
1074 ret float %b
1075 }
1076
1077 ; negative test
1078
1079 define float @maximum_x_y_maximum_z(float %x, float %y, float %z) {
1080 ; CHECK-LABEL: @maximum_x_y_maximum_z(
1081 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1082 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[Z:%.*]])
1083 ; CHECK-NEXT: ret float [[B]]
1084 ;
1085 %a = call float @llvm.maximum.f32(float %x, float %y)
1086 %b = call float @llvm.maximum.f32(float %a, float %z)
1087 ret float %b
1088 }
1089
1090 ; maximum(X, INF) --> INF
1091
1092 define <2 x double> @maximum_inf(<2 x double> %x) {
1093 ; CHECK-LABEL: @maximum_inf(
1094 ; CHECK-NEXT: ret <2 x double>
1095 ;
1096 %val = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double>)
1097 ret <2 x double> %val
1098 }
1099
1100 define float @maximum_inf_commute(float %x) {
1101 ; CHECK-LABEL: @maximum_inf_commute(
1102 ; CHECK-NEXT: ret float 0x7FF0000000000000
1103 ;
1104 %val = call float @llvm.maximum.f32(float 0x7FF0000000000000, float %x)
1105 ret float %val
1106 }
1107
7921108 ; Y - (Y - X) --> X
7931109
7941110 define float @fsub_fsub_common_op(float %x, float %y) {
9501266 %r = fadd reassoc nsz float %s, %y
9511267 ret float %r
9521268 }
953
178178 declare float @llvm.exp.f32(float)
179179 declare float @llvm.minnum.f32(float, float)
180180 declare float @llvm.maxnum.f32(float, float)
181 declare float @llvm.maximum.f32(float, float)
181182 declare double @llvm.exp2.f64(double)
182183 declare float @llvm.fma.f32(float,float,float)
183184
281282 ret i1 %uge
282283 }
283284
285 ; But using maximum, we can simplify, since the NaN would be propagated
286
287 define i1 @orderedLessZeroMaximum(float, float) {
288 ; CHECK-LABEL: @orderedLessZeroMaximum(
289 ; CHECK-NEXT: ret i1 true
290 ;
291 %a = call float @llvm.exp.f32(float %0)
292 %b = call float @llvm.maximum.f32(float %a, float %1)
293 %uge = fcmp uge float %b, 0.000000e+00
294 ret i1 %uge
295 }
296
284297 define i1 @known_positive_olt_with_negative_constant(double %a) {
285298 ; CHECK-LABEL: @known_positive_olt_with_negative_constant(
286299 ; CHECK-NEXT: ret i1 false
374387 %cmp = fcmp ult <2 x double> %A,
375388 ret <2 x i1> %cmp
376389 }
377
33 target datalayout = "E-m:e-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-v64:32:32-v128:32:32-a0:0:32-n32"
44
55 ; This test verifies that ceil, floor, nearbyint, trunc, rint, round,
6 ; copysign, minnum, maxnum and fabs intrinsics are considered safe
7 ; to speculate.
6 ; copysign, minnum, maxnum, minimum, maximum, and fabs intrinsics are
7 ; considered safe to speculate.
88
99 ; CHECK-LABEL: @test
1010 ; CHECK: call float @llvm.ceil.f32
4040 %tmp.8 = call float @llvm.copysign.f32(float %tmp.7, float %arg2)
4141 %tmp.9 = call float @llvm.minnum.f32(float %tmp.8, float %arg2)
4242 %tmp.10 = call float @llvm.maxnum.f32(float %tmp.9, float %arg2)
43 %tmp.11 = call float @llvm.powi.f32(float %tmp.10, i32 4)
44 call void @consume(float %tmp.11)
43 %tmp.11 = call float @llvm.minimum.f32(float %tmp.10, float %arg2)
44 %tmp.12 = call float @llvm.maximum.f32(float %tmp.11, float %arg2)
45 %tmp.13 = call float @llvm.powi.f32(float %tmp.12, i32 4)
46 call void @consume(float %tmp.13)
4547 %IND.new = add i32 %IND, 1
4648 br label %for.head
4749
6163 declare float @llvm.copysign.f32(float, float)
6264 declare float @llvm.minnum.f32(float, float)
6365 declare float @llvm.maxnum.f32(float, float)
66 declare float @llvm.minimum.f32(float, float)
67 declare float @llvm.maximum.f32(float, float)
6468 declare float @llvm.powi.f32(float, i32)
66 declare float @llvm.fabs.f32(float) nounwind readonly
77 declare float @llvm.minnum.f32(float, float) nounwind readonly
88 declare float @llvm.maxnum.f32(float, float) nounwind readonly
9 declare float @llvm.minimum.f32(float, float) nounwind readonly
10 declare float @llvm.maximum.f32(float, float) nounwind readonly
911
1012 ; ALL-LABEL: @fdiv_test(
1113 ; EXPENSIVE: select i1 %cmp, double %div, double 0.0
126128 store float %cond.i, float addrspace(1)* %out, align 4
127129 ret void
128130 }
131
132 ; ALL-LABEL: @minimum_test(
133 ; ALL: select
134 define void @minimum_test(float addrspace(1)* noalias nocapture %out, float %a, float %b) nounwind {
135 entry:
136 %cmp.i = fcmp olt float %a, 0.000000e+00
137 br i1 %cmp.i, label %test_minimum.exit, label %cond.else.i
138
139 cond.else.i: ; preds = %entry
140 %0 = tail call float @llvm.minimum.f32(float %a, float %b) nounwind readnone
141 br label %test_minimum.exit
142
143 test_minimum.exit: ; preds = %cond.else.i, %entry
144 %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
145 store float %cond.i, float addrspace(1)* %out, align 4
146 ret void
147 }
148
149 ; ALL-LABEL: @maximum_test(
150 ; ALL: select
151 define void @maximum_test(float addrspace(1)* noalias nocapture %out, float %a, float %b) nounwind {
152 entry:
153 %cmp.i = fcmp olt float %a, 0.000000e+00
154 br i1 %cmp.i, label %test_maximum.exit, label %cond.else.i
155
156 cond.else.i: ; preds = %entry
157 %0 = tail call float @llvm.maximum.f32(float %a, float %b) nounwind readnone
158 br label %test_maximum.exit
159
160 test_maximum.exit: ; preds = %cond.else.i, %entry
161 %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
162 store float %cond.i, float addrspace(1)* %out, align 4
163 ret void
164 }