Fix usage of signbit() in SRFI 144 #747
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
C standard defines
signbit()
as a macro returning "non-zero value" for negative arguments (see 7.12.3.6 of C11 standard). SRFI 144'sflsign-bit
is defined to return exactly 1.Make sure to convert the result of signbit() call into "boolean int" which is either 0 or 1.
This is not a theoretical issue. This causes SRFI 144 test suite to fail on many architectures that are not x86_64 or ARM64.
GCC on x86_64 compiles
signbit()
aswhich indeed returns either 0 or 1.
movmskpd
extracts 2-bit sign mask from the FP value in src register and stores that in low-order bits of the dst register. Then the unneeded extra bit is masked out, leaving only the lowest bit set or unset.However, other architectures don't have such conveniences and go with more direct approach. For example, GCC on ARMv7 produces this:
which effectively returns either 0 or -1. Generated code masks out everything but the sign bit and returns the result as is. The value 0x80000000 is the representation of -1.
Even on i386
signbit()
is compiled aswhich effectively returns either 0 or 512:
fxam
sets C1 bit FPU status word to the sign of FP value, then the status word is extracted, the "sign bit" is masked out, and left as is.