Skip to content

Commit 71f4761

Browse files
committed
[PowerPC][compiler-rt][builtins]Fix __fixunstfti builtin on PowerPC
__fixunstfti converts a long double (IBM double-double) to an unsigned 128 bit integer. This patch enables it to handle a previously unhandled case in which a negative low double may impact the result of the conversion. Collaborated with @masoud.ataei and @renenkel. Patch By: Baptiste Saleil Differential Revision: https://reviews.llvm.org/D69193
1 parent 8204d9f commit 71f4761

File tree

2 files changed

+662
-10
lines changed

2 files changed

+662
-10
lines changed

compiler-rt/lib/builtins/ppc/fixunstfti.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ __uint128_t __fixunstfti(long double input) {
3434
} ldUnion;
3535

3636
// If the long double is less than 1.0 or negative,
37-
// return 0.0.
37+
// return 0.
3838
if (input < 1.0)
39-
return 0.0;
39+
return 0;
4040

4141
// Retrieve the 64-bit patterns of high and low doubles.
4242
// Compute the unbiased exponent of both high and low doubles by
@@ -99,6 +99,16 @@ __uint128_t __fixunstfti(long double input) {
9999
loResult <<= shift;
100100
}
101101

102+
// If the low double is negative, it may change the integer value of the
103+
// whole number if the absolute value of its fractional part is bigger than
104+
// the fractional part of the high double. Because both doubles cannot
105+
// overlap, this situation only occurs when the high double has no
106+
// fractional part.
107+
ldUnion.ld = input;
108+
if ((ldUnion.d[0] == (double)hiResult) &&
109+
(ldUnion.d[1] < (double)((__int128_t)loResult)))
110+
loResult--;
111+
102112
// Add the high and low doublewords together to form a 128 bit integer.
103113
result = loResult + hiResult;
104114
return result;

0 commit comments

Comments
 (0)