-
Notifications
You must be signed in to change notification settings - Fork 49
Open
Description
This issue was identified during the testing validation for the 2024.06 release, specifically occurring with the em CPU (-mcpu=em).
The test case has been reduced. It checks the correctness of type conversions between integers and floating-point numbers. The critical part involves converting a maximum negative value from an integer to a floating-point number and back, ensuring the value remains unchanged.
$ cat test.c
#include <stdlib.h>
int
main (void)
{
static volatile signed long long ivin, ivout;
static volatile double fv1, fv2;
ivin = ((signed long long)(unsigned long long)~(unsigned long long)0);
fv1 = ((signed long long)(unsigned long long)~(unsigned long long)0);
fv2 = ivin;
ivout = fv2;
if ((1) && ivout != ivin)
abort();
exit (0);
}
$ arc-elf32-gcc \
-fdiagnostics-plain-output \
--specs=hl.specs \
-mcpu=em \
-O0 \
test.c \
-lm -o ./test.x
$ nsimdrv \
-on nsim_isa_enable_timer_0 \
-on nsim_isa_enable_timer_1 \
-off invalid_instruction_interrupt \
-off memory_exception_interrupt \
-on nsim_download_elf_sections \
-prop=nsim_hlink_gnu_io_ext=1 \
-p nsim_isa_family=av2em \
-p nsim_isa_core=3 \
-on nsim_isa_sat \
-p nsim_isa_shift_option=0 \
-p nsim_isa_bitscan_option=0 \
./test.x
$ echo $?
6ivin = ((signed long long)(unsigned long long)~(unsigned long long)0);
fv1 = ((signed long long)(unsigned long long)~(unsigned long long)0);- The expression
(unsigned long long)~(unsigned long long)0results in the maximum unsigned long long value,0xFFFFFFFF. - Casting this to a signed long long gives
-1because of two's complement representation. - Both
ivinandfv1are assigned this value, so both hold-1.
fv2 = ivin;- Assigning
ivin(which is-1) tofv2, a double, should theoretically result in-1.0. - However,
fv2holds-0.9999999962747097.
ivout = fv2;- Converting
fv2(holding-0.9999999962747097) back to an integer results in0. This is because when a floating-point number between-1.0and0.0is converted to an integer, it truncates towards zero.
if ((1) && ivout != ivin)
abort();- With that said,
ivoutis0andivinis-1, so the conditionivout != ivinis true, resulting in a call toabort()with a non-zero exit status6.
Note: According to Jenkins results from the last release (arc-2023.09), this test case passes. However, I was unable to reproduce the passing result. The expected behavior was compared to arc600.
Metadata
Metadata
Assignees
Labels
No labels