Skip to content

Commit 42b3483

Browse files
authored
ValueTracking: Improve accuracy of 0 handling with PreserveSign (#173165)
If the source value is known not subnormal and not zero with the same sign, we can infer the result is also not zero with the same sign.
1 parent ffbed74 commit 42b3483

File tree

2 files changed

+34
-26
lines changed

2 files changed

+34
-26
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5308,6 +5308,14 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
53085308
if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
53095309
Known.knownNot(fcSubnormal);
53105310

5311+
if (DenormMode == DenormalMode::getPreserveSign()) {
5312+
if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
5313+
Known.knownNot(fcPosZero);
5314+
if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
5315+
Known.knownNot(fcNegZero);
5316+
break;
5317+
}
5318+
53115319
if (DenormMode.Input == DenormalMode::PositiveZero ||
53125320
(DenormMode.Output == DenormalMode::PositiveZero &&
53135321
DenormMode.Input == DenormalMode::IEEE))

llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -204,99 +204,99 @@ define float @ret_canonicalize_ieee_constant_snan() "denormal-fp-math"="ieee,iee
204204
}
205205

206206
define float @ret_canonicalize_daz_constant_pos_denormal() "denormal-fp-math"="preserve-sign,preserve-sign" {
207-
; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_pos_denormal
207+
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @ret_canonicalize_daz_constant_pos_denormal
208208
; CHECK-SAME: () #[[ATTR10:[0-9]+]] {
209-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef 0x36A0000000000000) #[[ATTR12]]
209+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf nzero sub norm) float @llvm.canonicalize.f32(float noundef 0x36A0000000000000) #[[ATTR12]]
210210
; CHECK-NEXT: ret float [[CALL]]
211211
;
212212
%call = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
213213
ret float %call
214214
}
215215

216216
define float @ret_canonicalize_daz_constant_neg_denormal() "denormal-fp-math"="preserve-sign,preserve-sign" {
217-
; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_neg_denormal
217+
; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @ret_canonicalize_daz_constant_neg_denormal
218218
; CHECK-SAME: () #[[ATTR10]] {
219-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef 0xB6A0000000000000) #[[ATTR12]]
219+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf pzero sub norm) float @llvm.canonicalize.f32(float noundef 0xB6A0000000000000) #[[ATTR12]]
220220
; CHECK-NEXT: ret float [[CALL]]
221221
;
222222
%call = call float @llvm.canonicalize.f32(float 0xb6A0000000000000)
223223
ret float %call
224224
}
225225

226226
define float @ret_canonicalize_daz_constant_pos_zero() "denormal-fp-math"="preserve-sign,preserve-sign" {
227-
; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_pos_zero
227+
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @ret_canonicalize_daz_constant_pos_zero
228228
; CHECK-SAME: () #[[ATTR10]] {
229-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef 0.000000e+00) #[[ATTR12]]
229+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf nzero sub norm) float @llvm.canonicalize.f32(float noundef 0.000000e+00) #[[ATTR12]]
230230
; CHECK-NEXT: ret float [[CALL]]
231231
;
232232
%call = call float @llvm.canonicalize.f32(float 0.0)
233233
ret float %call
234234
}
235235

236236
define float @ret_canonicalize_daz_constant_neg_zero() "denormal-fp-math"="preserve-sign,preserve-sign" {
237-
; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_neg_zero
237+
; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @ret_canonicalize_daz_constant_neg_zero
238238
; CHECK-SAME: () #[[ATTR10]] {
239-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef -0.000000e+00) #[[ATTR12]]
239+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf pzero sub norm) float @llvm.canonicalize.f32(float noundef -0.000000e+00) #[[ATTR12]]
240240
; CHECK-NEXT: ret float [[CALL]]
241241
;
242242
%call = call float @llvm.canonicalize.f32(float -0.0)
243243
ret float %call
244244
}
245245

246246
define float @ret_canonicalize_daz_constant_pos_normal() "denormal-fp-math"="preserve-sign,preserve-sign" {
247-
; CHECK-LABEL: define noundef nofpclass(nan inf sub nnorm) float @ret_canonicalize_daz_constant_pos_normal
247+
; CHECK-LABEL: define noundef nofpclass(nan inf zero sub nnorm) float @ret_canonicalize_daz_constant_pos_normal
248248
; CHECK-SAME: () #[[ATTR10]] {
249-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub nnorm) float @llvm.canonicalize.f32(float noundef 8.000000e+00) #[[ATTR12]]
249+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf zero sub nnorm) float @llvm.canonicalize.f32(float noundef 8.000000e+00) #[[ATTR12]]
250250
; CHECK-NEXT: ret float [[CALL]]
251251
;
252252
%call = call float @llvm.canonicalize.f32(float 8.0)
253253
ret float %call
254254
}
255255

256256
define float @ret_canonicalize_daz_constant_neg_normal() "denormal-fp-math"="preserve-sign,preserve-sign" {
257-
; CHECK-LABEL: define noundef nofpclass(nan inf sub pnorm) float @ret_canonicalize_daz_constant_neg_normal
257+
; CHECK-LABEL: define noundef nofpclass(nan inf zero sub pnorm) float @ret_canonicalize_daz_constant_neg_normal
258258
; CHECK-SAME: () #[[ATTR10]] {
259-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub pnorm) float @llvm.canonicalize.f32(float noundef -8.000000e+00) #[[ATTR12]]
259+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf zero sub pnorm) float @llvm.canonicalize.f32(float noundef -8.000000e+00) #[[ATTR12]]
260260
; CHECK-NEXT: ret float [[CALL]]
261261
;
262262
%call = call float @llvm.canonicalize.f32(float -8.0)
263263
ret float %call
264264
}
265265

266266
define float @ret_canonicalize_daz_constant_pos_inf() "denormal-fp-math"="preserve-sign,preserve-sign" {
267-
; CHECK-LABEL: define noundef nofpclass(nan ninf sub norm) float @ret_canonicalize_daz_constant_pos_inf
267+
; CHECK-LABEL: define noundef nofpclass(nan ninf zero sub norm) float @ret_canonicalize_daz_constant_pos_inf
268268
; CHECK-SAME: () #[[ATTR10]] {
269-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan ninf sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF0000000000000) #[[ATTR12]]
269+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan ninf zero sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF0000000000000) #[[ATTR12]]
270270
; CHECK-NEXT: ret float [[CALL]]
271271
;
272272
%call = call float @llvm.canonicalize.f32(float 0x7FF0000000000000)
273273
ret float %call
274274
}
275275

276276
define float @ret_canonicalize_daz_constant_neg_inf() "denormal-fp-math"="preserve-sign,preserve-sign" {
277-
; CHECK-LABEL: define noundef nofpclass(nan pinf sub norm) float @ret_canonicalize_daz_constant_neg_inf
277+
; CHECK-LABEL: define noundef nofpclass(nan pinf zero sub norm) float @ret_canonicalize_daz_constant_neg_inf
278278
; CHECK-SAME: () #[[ATTR10]] {
279-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan pinf sub norm) float @llvm.canonicalize.f32(float noundef 0xFFF0000000000000) #[[ATTR12]]
279+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan pinf zero sub norm) float @llvm.canonicalize.f32(float noundef 0xFFF0000000000000) #[[ATTR12]]
280280
; CHECK-NEXT: ret float [[CALL]]
281281
;
282282
%call = call float @llvm.canonicalize.f32(float 0xFFF0000000000000)
283283
ret float %call
284284
}
285285

286286
define float @ret_canonicalize_daz_constant_qnan() "denormal-fp-math"="preserve-sign,preserve-sign" {
287-
; CHECK-LABEL: define noundef nofpclass(snan inf sub norm) float @ret_canonicalize_daz_constant_qnan
287+
; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) float @ret_canonicalize_daz_constant_qnan
288288
; CHECK-SAME: () #[[ATTR10]] {
289-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF8000000000000) #[[ATTR12]]
289+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf zero sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF8000000000000) #[[ATTR12]]
290290
; CHECK-NEXT: ret float [[CALL]]
291291
;
292292
%call = call float @llvm.canonicalize.f32(float 0x7FF8000000000000)
293293
ret float %call
294294
}
295295

296296
define float @ret_canonicalize_daz_constant_snan() "denormal-fp-math"="preserve-sign,preserve-sign" {
297-
; CHECK-LABEL: define noundef nofpclass(snan inf sub norm) float @ret_canonicalize_daz_constant_snan
297+
; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) float @ret_canonicalize_daz_constant_snan
298298
; CHECK-SAME: () #[[ATTR10]] {
299-
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF1000000000000) #[[ATTR12]]
299+
; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf zero sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF1000000000000) #[[ATTR12]]
300300
; CHECK-NEXT: ret float [[CALL]]
301301
;
302302
%call = call float @llvm.canonicalize.f32(float 0x7FF1000000000000)
@@ -504,9 +504,9 @@ define float @ret_canonicalize_dynamic_constant_snan() "denormal-fp-math"="dynam
504504
}
505505

506506
define float @ret_canonicalize_daz_not_nzero_not_nsub(float nofpclass(nzero nsub) %x) "denormal-fp-math"="preserve-sign,preserve-sign" {
507-
; CHECK-LABEL: define nofpclass(snan sub) float @ret_canonicalize_daz_not_nzero_not_nsub
507+
; CHECK-LABEL: define nofpclass(snan nzero sub) float @ret_canonicalize_daz_not_nzero_not_nsub
508508
; CHECK-SAME: (float nofpclass(nzero nsub) [[X:%.*]]) #[[ATTR10]] {
509-
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.canonicalize.f32(float nofpclass(nzero nsub) [[X]]) #[[ATTR12]]
509+
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan nzero sub) float @llvm.canonicalize.f32(float nofpclass(nzero nsub) [[X]]) #[[ATTR12]]
510510
; CHECK-NEXT: ret float [[CALL]]
511511
;
512512
%call = call float @llvm.canonicalize.f32(float %x)
@@ -534,9 +534,9 @@ define float @ret_canonicalize_daz_not_nzero(float nofpclass(nzero) %x) "denorma
534534
}
535535

536536
define float @ret_canonicalize_daz_not_pzero_not_psub(float nofpclass(pzero psub) %x) "denormal-fp-math"="preserve-sign,preserve-sign" {
537-
; CHECK-LABEL: define nofpclass(snan sub) float @ret_canonicalize_daz_not_pzero_not_psub
537+
; CHECK-LABEL: define nofpclass(snan pzero sub) float @ret_canonicalize_daz_not_pzero_not_psub
538538
; CHECK-SAME: (float nofpclass(pzero psub) [[X:%.*]]) #[[ATTR10]] {
539-
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.canonicalize.f32(float nofpclass(pzero psub) [[X]]) #[[ATTR12]]
539+
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan pzero sub) float @llvm.canonicalize.f32(float nofpclass(pzero psub) [[X]]) #[[ATTR12]]
540540
; CHECK-NEXT: ret float [[CALL]]
541541
;
542542
%call = call float @llvm.canonicalize.f32(float %x)
@@ -584,9 +584,9 @@ define float @ret_canonicalize_daz_not_sub(float nofpclass(sub) %x) "denormal-fp
584584
}
585585

586586
define float @ret_canonicalize_daz_not_sub_not_nzero(float nofpclass(sub nzero) %x) "denormal-fp-math"="preserve-sign,preserve-sign" {
587-
; CHECK-LABEL: define nofpclass(snan sub) float @ret_canonicalize_daz_not_sub_not_nzero
587+
; CHECK-LABEL: define nofpclass(snan nzero sub) float @ret_canonicalize_daz_not_sub_not_nzero
588588
; CHECK-SAME: (float nofpclass(nzero sub) [[X:%.*]]) #[[ATTR10]] {
589-
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.canonicalize.f32(float nofpclass(nzero sub) [[X]]) #[[ATTR12]]
589+
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan nzero sub) float @llvm.canonicalize.f32(float nofpclass(nzero sub) [[X]]) #[[ATTR12]]
590590
; CHECK-NEXT: ret float [[CALL]]
591591
;
592592
%call = call float @llvm.canonicalize.f32(float %x)

0 commit comments

Comments
 (0)