@@ -12,6 +12,16 @@ define float @neg_constant(float %x) {
1212 ret float %mul
1313}
1414
15+ define float @unary_neg_constant (float %x ) {
16+ ; CHECK-LABEL: @unary_neg_constant(
17+ ; CHECK-NEXT: [[MUL:%.*]] = fmul ninf float [[X:%.*]], -2.000000e+01
18+ ; CHECK-NEXT: ret float [[MUL]]
19+ ;
20+ %sub = fneg float %x
21+ %mul = fmul ninf float %sub , 2 .0e+1
22+ ret float %mul
23+ }
24+
1525define <2 x float > @neg_constant_vec (<2 x float > %x ) {
1626; CHECK-LABEL: @neg_constant_vec(
1727; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[X:%.*]], <float -2.000000e+00, float -3.000000e+00>
@@ -22,6 +32,16 @@ define <2 x float> @neg_constant_vec(<2 x float> %x) {
2232 ret <2 x float > %mul
2333}
2434
35+ define <2 x float > @unary_neg_constant_vec (<2 x float > %x ) {
36+ ; CHECK-LABEL: @unary_neg_constant_vec(
37+ ; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[X:%.*]], <float -2.000000e+00, float -3.000000e+00>
38+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
39+ ;
40+ %sub = fneg <2 x float > %x
41+ %mul = fmul ninf <2 x float > %sub , <float 2 .0 , float 3 .0 >
42+ ret <2 x float > %mul
43+ }
44+
2545define <2 x float > @neg_constant_vec_undef (<2 x float > %x ) {
2646; CHECK-LABEL: @neg_constant_vec_undef(
2747; CHECK-NEXT: [[MUL:%.*]] = fmul ninf <2 x float> [[X:%.*]], <float -2.000000e+00, float -3.000000e+00>
@@ -43,6 +63,16 @@ define float @neg_nsz_constant(float %x) {
4363 ret float %mul
4464}
4565
66+ define float @unary_neg_nsz_constant (float %x ) {
67+ ; CHECK-LABEL: @unary_neg_nsz_constant(
68+ ; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[X:%.*]], -2.000000e+01
69+ ; CHECK-NEXT: ret float [[MUL]]
70+ ;
71+ %sub = fneg nsz float %x
72+ %mul = fmul nnan float %sub , 2 .0e+1
73+ ret float %mul
74+ }
75+
4676; (-0.0 - X) * (-0.0 - Y) => X * Y
4777define float @neg_neg (float %x , float %y ) {
4878; CHECK-LABEL: @neg_neg(
@@ -55,6 +85,39 @@ define float @neg_neg(float %x, float %y) {
5585 ret float %mul
5686}
5787
88+ define float @unary_neg_unary_neg (float %x , float %y ) {
89+ ; CHECK-LABEL: @unary_neg_unary_neg(
90+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp float [[X:%.*]], [[Y:%.*]]
91+ ; CHECK-NEXT: ret float [[MUL]]
92+ ;
93+ %sub1 = fneg float %x
94+ %sub2 = fneg float %y
95+ %mul = fmul arcp float %sub1 , %sub2
96+ ret float %mul
97+ }
98+
99+ define float @unary_neg_neg (float %x , float %y ) {
100+ ; CHECK-LABEL: @unary_neg_neg(
101+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp float [[X:%.*]], [[Y:%.*]]
102+ ; CHECK-NEXT: ret float [[MUL]]
103+ ;
104+ %sub1 = fneg float %x
105+ %sub2 = fsub float -0 .0 , %y
106+ %mul = fmul arcp float %sub1 , %sub2
107+ ret float %mul
108+ }
109+
110+ define float @neg_unary_neg (float %x , float %y ) {
111+ ; CHECK-LABEL: @neg_unary_neg(
112+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp float [[X:%.*]], [[Y:%.*]]
113+ ; CHECK-NEXT: ret float [[MUL]]
114+ ;
115+ %sub1 = fsub float -0 .0 , %x
116+ %sub2 = fneg float %y
117+ %mul = fmul arcp float %sub1 , %sub2
118+ ret float %mul
119+ }
120+
58121define <2 x float > @neg_neg_vec (<2 x float > %x , <2 x float > %y ) {
59122; CHECK-LABEL: @neg_neg_vec(
60123; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
@@ -66,6 +129,39 @@ define <2 x float> @neg_neg_vec(<2 x float> %x, <2 x float> %y) {
66129 ret <2 x float > %mul
67130}
68131
132+ define <2 x float > @unary_neg_unary_neg_vec (<2 x float > %x , <2 x float > %y ) {
133+ ; CHECK-LABEL: @unary_neg_unary_neg_vec(
134+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
135+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
136+ ;
137+ %sub1 = fneg <2 x float > %x
138+ %sub2 = fneg <2 x float > %y
139+ %mul = fmul arcp <2 x float > %sub1 , %sub2
140+ ret <2 x float > %mul
141+ }
142+
143+ define <2 x float > @unary_neg_neg_vec (<2 x float > %x , <2 x float > %y ) {
144+ ; CHECK-LABEL: @unary_neg_neg_vec(
145+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
146+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
147+ ;
148+ %sub1 = fneg <2 x float > %x
149+ %sub2 = fsub <2 x float > <float -0 .0 , float -0 .0 >, %y
150+ %mul = fmul arcp <2 x float > %sub1 , %sub2
151+ ret <2 x float > %mul
152+ }
153+
154+ define <2 x float > @neg_unary_neg_vec (<2 x float > %x , <2 x float > %y ) {
155+ ; CHECK-LABEL: @neg_unary_neg_vec(
156+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
157+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
158+ ;
159+ %sub1 = fsub <2 x float > <float -0 .0 , float -0 .0 >, %x
160+ %sub2 = fneg <2 x float > %y
161+ %mul = fmul arcp <2 x float > %sub1 , %sub2
162+ ret <2 x float > %mul
163+ }
164+
69165define <2 x float > @neg_neg_vec_undef (<2 x float > %x , <2 x float > %y ) {
70166; CHECK-LABEL: @neg_neg_vec_undef(
71167; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
@@ -77,6 +173,28 @@ define <2 x float> @neg_neg_vec_undef(<2 x float> %x, <2 x float> %y) {
77173 ret <2 x float > %mul
78174}
79175
176+ define <2 x float > @unary_neg_neg_vec_undef (<2 x float > %x , <2 x float > %y ) {
177+ ; CHECK-LABEL: @unary_neg_neg_vec_undef(
178+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
179+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
180+ ;
181+ %neg = fneg <2 x float > %x
182+ %sub = fsub <2 x float > <float undef , float -0 .0 >, %y
183+ %mul = fmul arcp <2 x float > %neg , %sub
184+ ret <2 x float > %mul
185+ }
186+
187+ define <2 x float > @neg_unary_neg_vec_undef (<2 x float > %x , <2 x float > %y ) {
188+ ; CHECK-LABEL: @neg_unary_neg_vec_undef(
189+ ; CHECK-NEXT: [[MUL:%.*]] = fmul arcp <2 x float> [[X:%.*]], [[Y:%.*]]
190+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
191+ ;
192+ %sub = fsub <2 x float > <float -0 .0 , float undef >, %x
193+ %neg = fneg <2 x float > %y
194+ %mul = fmul arcp <2 x float > %sub , %neg
195+ ret <2 x float > %mul
196+ }
197+
80198; (0.0 - X) * (0.0 - Y) => X * Y
81199define float @neg_neg_nsz (float %x , float %y ) {
82200; CHECK-LABEL: @neg_neg_nsz(
@@ -108,6 +226,57 @@ define float @neg_neg_multi_use(float %x, float %y) {
108226 ret float %mul
109227}
110228
229+ define float @unary_neg_unary_neg_multi_use (float %x , float %y ) {
230+ ; CHECK-LABEL: @unary_neg_unary_neg_multi_use(
231+ ; CHECK-NEXT: [[NX:%.*]] = fneg float [[X:%.*]]
232+ ; CHECK-NEXT: [[NY:%.*]] = fneg float [[Y:%.*]]
233+ ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X]], [[Y]]
234+ ; CHECK-NEXT: call void @use_f32(float [[NX]])
235+ ; CHECK-NEXT: call void @use_f32(float [[NY]])
236+ ; CHECK-NEXT: ret float [[MUL]]
237+ ;
238+ %nx = fneg float %x
239+ %ny = fneg float %y
240+ %mul = fmul afn float %nx , %ny
241+ call void @use_f32 (float %nx )
242+ call void @use_f32 (float %ny )
243+ ret float %mul
244+ }
245+
246+ define float @unary_neg_neg_multi_use (float %x , float %y ) {
247+ ; CHECK-LABEL: @unary_neg_neg_multi_use(
248+ ; CHECK-NEXT: [[NX:%.*]] = fneg float [[X:%.*]]
249+ ; CHECK-NEXT: [[NY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
250+ ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X]], [[Y]]
251+ ; CHECK-NEXT: call void @use_f32(float [[NX]])
252+ ; CHECK-NEXT: call void @use_f32(float [[NY]])
253+ ; CHECK-NEXT: ret float [[MUL]]
254+ ;
255+ %nx = fneg float %x
256+ %ny = fsub float -0 .0 , %y
257+ %mul = fmul afn float %nx , %ny
258+ call void @use_f32 (float %nx )
259+ call void @use_f32 (float %ny )
260+ ret float %mul
261+ }
262+
263+ define float @neg_unary_neg_multi_use (float %x , float %y ) {
264+ ; CHECK-LABEL: @neg_unary_neg_multi_use(
265+ ; CHECK-NEXT: [[NX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
266+ ; CHECK-NEXT: [[NY:%.*]] = fneg float [[Y:%.*]]
267+ ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[X]], [[Y]]
268+ ; CHECK-NEXT: call void @use_f32(float [[NX]])
269+ ; CHECK-NEXT: call void @use_f32(float [[NY]])
270+ ; CHECK-NEXT: ret float [[MUL]]
271+ ;
272+ %nx = fsub float -0 .0 , %x
273+ %ny = fneg float %y
274+ %mul = fmul afn float %nx , %ny
275+ call void @use_f32 (float %nx )
276+ call void @use_f32 (float %ny )
277+ ret float %mul
278+ }
279+
111280; (-0.0 - X) * Y => -0.0 - (X * Y)
112281define float @neg_sink (float %x , float %y ) {
113282; CHECK-LABEL: @neg_sink(
@@ -120,6 +289,17 @@ define float @neg_sink(float %x, float %y) {
120289 ret float %mul
121290}
122291
292+ define float @unary_neg_sink (float %x , float %y ) {
293+ ; CHECK-LABEL: @unary_neg_sink(
294+ ; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
295+ ; CHECK-NEXT: [[MUL:%.*]] = fsub float -0.000000e+00, [[TMP1]]
296+ ; CHECK-NEXT: ret float [[MUL]]
297+ ;
298+ %neg = fneg float %x
299+ %mul = fmul float %neg , %y
300+ ret float %mul
301+ }
302+
123303define <2 x float > @neg_sink_vec (<2 x float > %x , <2 x float > %y ) {
124304; CHECK-LABEL: @neg_sink_vec(
125305; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[Y:%.*]]
@@ -131,6 +311,18 @@ define <2 x float> @neg_sink_vec(<2 x float> %x, <2 x float> %y) {
131311 ret <2 x float > %mul
132312}
133313
314+ ; FIXME: Should generate a unary FNeg.
315+ define <2 x float > @unary_neg_sink_vec (<2 x float > %x , <2 x float > %y ) {
316+ ; CHECK-LABEL: @unary_neg_sink_vec(
317+ ; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[Y:%.*]]
318+ ; CHECK-NEXT: [[MUL:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
319+ ; CHECK-NEXT: ret <2 x float> [[MUL]]
320+ ;
321+ %sub = fneg <2 x float > %x
322+ %mul = fmul <2 x float > %sub , %y
323+ ret <2 x float > %mul
324+ }
325+
134326define <2 x float > @neg_sink_vec_undef (<2 x float > %x , <2 x float > %y ) {
135327; CHECK-LABEL: @neg_sink_vec_undef(
136328; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[Y:%.*]]
@@ -169,6 +361,19 @@ define float @neg_sink_multi_use(float %x, float %y) {
169361 ret float %mul2
170362}
171363
364+ define float @unary_neg_sink_multi_use (float %x , float %y ) {
365+ ; CHECK-LABEL: @unary_neg_sink_multi_use(
366+ ; CHECK-NEXT: [[SUB1:%.*]] = fneg float [[X:%.*]]
367+ ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUB1]], [[Y:%.*]]
368+ ; CHECK-NEXT: [[MUL2:%.*]] = fmul float [[MUL]], [[SUB1]]
369+ ; CHECK-NEXT: ret float [[MUL2]]
370+ ;
371+ %sub1 = fneg float %x
372+ %mul = fmul float %sub1 , %y
373+ %mul2 = fmul float %mul , %sub1
374+ ret float %mul2
375+ }
376+
172377; Don't crash when attempting to cast a constant FMul to an instruction.
173378define void @test8 (i32* %inout ) {
174379; CHECK-LABEL: @test8(
0 commit comments