Commit 0b4c3f8
committed
[Support][APInt] Fix sign extension, exponent and mantissa in APInt::roundToDouble
Conversion of an `APInt` to double via `APInt::roundToDouble` misses
several edge cases that result in crashes due to an assertion or in
erroneous values due to incorrect values for the exponent and mantissa
of the generated double.
The assertion is triggered when attempting to convert a multi-word
`APInt` without active bits or with active bits only in the first
word, e.g.,
`APInt(65, 0, true).roundToDouble(true)` or
`APInt(65, 1, true).roundToDouble(true)`
The issue is caused by passing the bit width as the argument to
`SignExtend64`, exceeding the maximum expected bit width of 64.
Incorrect values for the mantissa or exponent are calculated for any
multi-word, unsigned value, e.g.,
`APInt(65, "18446744073709551616" /* 2^64 */, 10).roundToDouble(false)`
This is due to `APInt::roundToDouble` expecting the exponent to
correspond to the highest of the fractional part of the double rather
than to the highest active bit and due to the missing code clearing
the highest bit after generation of the mantissa.
This patch solves the issues by simplifying the treatment of
single-word integers and by adjusting the exponent and mantissa for
multi-word integers. Tests are added for the edge cases and some
regular cases.1 parent a9a2d25 commit 0b4c3f8
2 files changed
Lines changed: 50 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
900 | 900 | | |
901 | 901 | | |
902 | 902 | | |
903 | | - | |
904 | | - | |
905 | | - | |
906 | | - | |
907 | | - | |
908 | | - | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
909 | 906 | | |
910 | 907 | | |
911 | 908 | | |
| |||
917 | 914 | | |
918 | 915 | | |
919 | 916 | | |
920 | | - | |
921 | | - | |
922 | | - | |
923 | | - | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
924 | 926 | | |
925 | 927 | | |
926 | 928 | | |
| |||
947 | 949 | | |
948 | 950 | | |
949 | 951 | | |
| 952 | + | |
950 | 953 | | |
951 | 954 | | |
952 | 955 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3980 | 3980 | | |
3981 | 3981 | | |
3982 | 3982 | | |
| 3983 | + | |
| 3984 | + | |
| 3985 | + | |
| 3986 | + | |
| 3987 | + | |
| 3988 | + | |
| 3989 | + | |
| 3990 | + | |
| 3991 | + | |
| 3992 | + | |
| 3993 | + | |
| 3994 | + | |
| 3995 | + | |
| 3996 | + | |
| 3997 | + | |
| 3998 | + | |
| 3999 | + | |
| 4000 | + | |
| 4001 | + | |
| 4002 | + | |
| 4003 | + | |
| 4004 | + | |
| 4005 | + | |
| 4006 | + | |
| 4007 | + | |
| 4008 | + | |
| 4009 | + | |
| 4010 | + | |
| 4011 | + | |
| 4012 | + | |
| 4013 | + | |
| 4014 | + | |
| 4015 | + | |
| 4016 | + | |
| 4017 | + | |
| 4018 | + | |
| 4019 | + | |
3983 | 4020 | | |
0 commit comments