Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

em: Wrong value conversion #637

Open
luismgsilva opened this issue Jul 16, 2024 · 0 comments
Open

em: Wrong value conversion #637

luismgsilva opened this issue Jul 16, 2024 · 0 comments
Assignees
Milestone

Comments

@luismgsilva
Copy link
Member

This issue was identified during the testing validation for the 2024.06 release, specifically occurring with the em CPU (-mcpu=em).

original test case

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 $?
6
ivin = ((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)0 results in the maximum unsigned long long value, 0xFFFFFFFF.
  • Casting this to a signed long long gives -1 because of two's complement representation.
  • Both ivin and fv1 are assigned this value, so both hold -1.
fv2 = ivin;
  • Assigning ivin (which is -1) to fv2, a double, should theoretically result in -1.0.
  • However, fv2 holds -0.9999999962747097.
ivout = fv2;
  • Converting fv2 (holding -0.9999999962747097) back to an integer results in 0. This is because when a floating-point number between -1.0 and 0.0 is converted to an integer, it truncates towards zero.
if ((1) && ivout != ivin)
  abort();
  • With that said, ivout is 0 and ivin is -1, so the condition ivout != ivin is true, resulting in a call to abort() with a non-zero exit status 6.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants