Skip to content

Commit 0e96713

Browse files
dtcxzywtstellar
authored andcommitted
[ValueTracking] Bail out on x86_fp80 when computing fpclass with knownbits (llvm#130477)
In llvm#97762, we assume the minimum possible value of X is NaN implies X is NaN. But it doesn't hold for x86_fp80 format. If the knownbits of X are `?'011111111111110'????????????????????????????????????????????????????????????????`, the minimum possible value of X is NaN/unnormal. However, it can be a normal value. Closes llvm#130408. (cherry picked from commit 029e102)
1 parent 0fda7e6 commit 0e96713

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

llvm/lib/Analysis/ValueTracking.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -6135,13 +6135,14 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
61356135
else if (Bits.isNegative())
61366136
Known.signBitMustBeOne();
61376137

6138-
if (Ty->isIEEE()) {
6138+
if (Ty->isIEEELikeFPTy()) {
61396139
// IEEE floats are NaN when all bits of the exponent plus at least one of
61406140
// the fraction bits are 1. This means:
61416141
// - If we assume unknown bits are 0 and the value is NaN, it will
61426142
// always be NaN
61436143
// - If we assume unknown bits are 1 and the value is not NaN, it can
61446144
// never be NaN
6145+
// Note: They do not hold for x86_fp80 format.
61456146
if (APFloat(Ty->getFltSemantics(), Bits.One).isNaN())
61466147
Known.KnownFPClasses = fcNan;
61476148
else if (!APFloat(Ty->getFltSemantics(), ~Bits.Zero).isNaN())

llvm/test/Transforms/InstSimplify/fcmp.ll

+17
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,20 @@ define i1 @poison2(float %x) {
1616
%v = fcmp ueq float %x, poison
1717
ret i1 %v
1818
}
19+
20+
define i1 @pr130408(x86_fp80 %x) {
21+
; CHECK-LABEL: @pr130408(
22+
; CHECK-NEXT: [[BITS:%.*]] = bitcast x86_fp80 [[X:%.*]] to i80
23+
; CHECK-NEXT: [[MASKED:%.*]] = and i80 [[BITS]], -604444463063240877801473
24+
; CHECK-NEXT: [[OR:%.*]] = or i80 [[MASKED]], 302194561415509874573312
25+
; CHECK-NEXT: [[FP:%.*]] = bitcast i80 [[OR]] to x86_fp80
26+
; CHECK-NEXT: [[RES:%.*]] = fcmp uno x86_fp80 [[FP]], 0xK00000000000000000000
27+
; CHECK-NEXT: ret i1 [[RES]]
28+
;
29+
%bits = bitcast x86_fp80 %x to i80
30+
%masked = and i80 %bits, -604444463063240877801473
31+
%or = or i80 %masked, 302194561415509874573312
32+
%fp = bitcast i80 %or to x86_fp80
33+
%res = fcmp uno x86_fp80 %fp, 0xK00000000000000000000
34+
ret i1 %res
35+
}

0 commit comments

Comments
 (0)