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

Missing Underflow float exceptions in some cases (XuanTie Group explained) #17

Open
kxxt opened this issue Sep 3, 2023 · 24 comments
Open

Comments

@kxxt
Copy link

kxxt commented Sep 3, 2023

Some glibc tests failed because of missing expected underflow float exceptions.

FAIL: math/test-double-fma
FAIL: math/test-float-double-div  
FAIL: math/test-float-double-fma  
FAIL: math/test-float-double-mul
FAIL: math/test-float-fma
FAIL: math/test-float32-float32x-div  
FAIL: math/test-float32-float32x-fma  
FAIL: math/test-float32-float32x-mul
FAIL: math/test-float32-float64-div  
FAIL: math/test-float32-float64-fma  
FAIL: math/test-float32-float64-mul
FAIL: math/test-float32-fma
FAIL: math/test-float32x-float64-div  
FAIL: math/test-float32x-float64-fma
FAIL: math/test-float32x-fma
FAIL: math/test-float64-fma

The failing math tests have one thing in common: underflow float exception is missing. Here is the test log from math/test-float-double-div:

glibc-build/math/test-float-double-div  
testing float (argument double)  
Failure: div_downward_double (-0x4p-128, 0x1.000002p+0): Exception "Underflow" not set  
Failure: div_downward_double (0x4p-128, -0x1.000002p+0): Exception "Underflow" not set  
Failure: div_upward_double (-0x4p-128, -0x1.000002p+0): Exception "Underflow" not set  
Failure: div_upward_double (0x4p-128, 0x1.000002p+0): Exception "Underflow" not set  
  
Test suite completed:  
1732 test cases plus 1728 tests for exception flags and  
1728 tests for errno executed.  
4 errors occurred.

I built the following minimal reproduction out of this:

#include <math.h>
#include <fenv.h>
#include <stdio.h>

int main() {
  if (fesetround (FE_DOWNWARD)) {
    printf("ERROR: Failed to set rounding mode!\n");
    return 1;
  }
  float ans = fdiv(-0x4p-128, 0x1.000002p+0);
  if(fetestexcept (FE_UNDERFLOW)) {
    printf("Success: Exception Underflow is set!\n");
  } else {
    printf("Failure: Exception Underflow is not set!!!\n");
  }
}

And the following command is used to compile and run it:

gcc fdiv-repro.c  -lm -std=c2x -o fdiv-repro && ./fdiv-repro

Expected behavior: the program output Success: Exception Underflow is set!.

However, I got Failure: Exception Underflow is not set!!! .

Test results on different machines, OS and architectures:

revyos,     lpi4a: Failure: Exception Underflow is not set!!!
Arch,      sg2042: Failure: Exception Underflow is not set!!!
Arch,       lpi4a: Failure: Exception Underflow is not set!!!
Arch,   qemu-user: Success: Exception Underflow is set!
Arch,   unmatched: Success: Exception Underflow is set!
Arch, qemu-system: Success: Exception Underflow is set!
Arch,      x86_64: Success: Exception Underflow is set!

This might suggest something is wrong in the floating-point implementation of C910 & C920.

@felixonmars
Copy link

felixonmars commented Sep 3, 2023

Adding some test results:

Arch,     cv1800b: Failure: Exception Underflow is not set!!!
Arch,       poros: Success: Exception Underflow is set!
Arch,visionfivev1: Success: Exception Underflow is set!
Arch,visionfivev2: Success: Exception Underflow is set!

This suggests that C906 could be affected too.

@ksco
Copy link

ksco commented Sep 3, 2023

Minimal assembly reproduction:

#!/bin/sh

cat <<EOF | as -o thead_bug_probe.o -
.global _start
_start:
    li      a3,0x41
    fscsr   a3
    li      a1, 0xb80fffffc000007f
    fmv.d.x fa5, a1
    fcvt.s.d fa0, fa5
    frflags a0
    li      a7, 93
    ecall
EOF

ld thead_bug_probe.o -o thead_bug_probe

./thead_bug_probe

echo $?

Expected output: 3
LicheePi 4A output: 1

@felixonmars
Copy link

I have tried to run berkeley's testfloat which compares against a softfloat implementation, suggested by @sequencer

Here are all the failed test cases:

Testing f32_mul, rounding near_even.
46464 tests total.
Errors found in f32_mul, rounding near_even:
+01.000000  +7E.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+01.000000  -7E.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+01.7FFFFF  +7E.000000  => +01.000000 ....x  expected +01.000000 ...ux
+01.7FFFFF  -7E.000000  => -01.000000 ....x  expected -01.000000 ...ux
+7E.000000  +01.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+7E.000000  -01.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+7E.7FFFFF  +01.000000  => +01.000000 ....x  expected +01.000000 ...ux
+7E.7FFFFF  -01.000000  => -01.000000 ....x  expected -01.000000 ...ux
-01.000000  +7E.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-01.000000  -7E.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-01.7FFFFF  +7E.000000  => -01.000000 ....x  expected -01.000000 ...ux
-01.7FFFFF  -7E.000000  => +01.000000 ....x  expected +01.000000 ...ux
-7E.000000  +01.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-7E.000000  -01.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-7E.7FFFFF  +01.000000  => -01.000000 ....x  expected -01.000000 ...ux
-7E.7FFFFF  -01.000000  => +01.000000 ....x  expected +01.000000 ...ux
46464 tests performed; 16 errors found.
Testing f32_mul, rounding min.
46464 tests total.
Errors found in f32_mul, rounding min:
+01.000000  -7E.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+01.7FFFFF  -7D.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+01.7FFFFF  -7E.000000  => -01.000000 ....x  expected -01.000000 ...ux
+7D.7FFFFF  -01.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+7E.000000  -01.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+7E.7FFFFF  -01.000000  => -01.000000 ....x  expected -01.000000 ...ux
-01.000000  +7E.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-01.7FFFFF  +7D.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-01.7FFFFF  +7E.000000  => -01.000000 ....x  expected -01.000000 ...ux
-7D.7FFFFF  +01.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-7E.000000  +01.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-7E.7FFFFF  +01.000000  => -01.000000 ....x  expected -01.000000 ...ux
46464 tests performed; 12 errors found.
Testing f32_mul, rounding max.
46464 tests total.
Errors found in f32_mul, rounding max:
+01.000000  +7E.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+01.7FFFFF  +7D.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+01.7FFFFF  +7E.000000  => +01.000000 ....x  expected +01.000000 ...ux
+7D.7FFFFF  +01.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+7E.000000  +01.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+7E.7FFFFF  +01.000000  => +01.000000 ....x  expected +01.000000 ...ux
-01.000000  -7E.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-01.7FFFFF  -7D.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-01.7FFFFF  -7E.000000  => +01.000000 ....x  expected +01.000000 ...ux
-7D.7FFFFF  -01.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-7E.000000  -01.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-7E.7FFFFF  -01.000000  => +01.000000 ....x  expected +01.000000 ...ux
46464 tests performed; 12 errors found.
Testing f32_div, rounding near_even.
46464 tests total.
Errors found in f32_div, rounding near_even:
+01.7FFFFF  +80.000000  => +01.000000 ....x  expected +01.000000 ...ux
+01.7FFFFF  -80.000000  => -01.000000 ....x  expected -01.000000 ...ux
+7E.7FFFFF  -FD.000000  => -01.000000 ....x  expected -01.000000 ...ux
+7F.7FFFFF  +FE.000000  => +01.000000 ....x  expected +01.000000 ...ux
-01.7FFFFF  +80.000000  => -01.000000 ....x  expected -01.000000 ...ux
-01.7FFFFF  -80.000000  => +01.000000 ....x  expected +01.000000 ...ux
-7E.7FFFFF  -FD.000000  => +01.000000 ....x  expected +01.000000 ...ux
-7F.7FFFFF  +FE.000000  => -01.000000 ....x  expected -01.000000 ...ux
46464 tests performed; 8 errors found.
Testing f32_div, rounding min.
46464 tests total.
Errors found in f32_div, rounding min:
+00.7FFFFF  -7E.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+01.000000  -7F.000001  => -01.000000 ....x  expected -01.000000 ...ux
+01.7FFFFF  -80.000000  => -01.000000 ....x  expected -01.000000 ...ux
+01.7FFFFE  -7F.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
+7E.7FFFFF  -FD.000000  => -01.000000 ....x  expected -01.000000 ...ux
+7F.000000  -FD.000001  => -01.000000 ....x  expected -01.000000 ...ux
+7F.7FFFFE  -FD.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-00.7FFFFF  +7E.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-01.000000  +7F.000001  => -01.000000 ....x  expected -01.000000 ...ux
-01.7FFFFF  +80.000000  => -01.000000 ....x  expected -01.000000 ...ux
-01.7FFFFE  +7F.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
-7F.7FFFFF  +FE.000000  => -01.000000 ....x  expected -01.000000 ...ux
-80.000000  +FE.000001  => -01.000000 ....x  expected -01.000000 ...ux
-80.7FFFFE  +FE.7FFFFF  => -01.000000 ....x  expected -01.000000 ...ux
46464 tests performed; 14 errors found.
Testing f32_div, rounding max.
46464 tests total.
Errors found in f32_div, rounding max:
+00.7FFFFF  +7E.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+01.000000  +7F.000001  => +01.000000 ....x  expected +01.000000 ...ux
+01.7FFFFF  +80.000000  => +01.000000 ....x  expected +01.000000 ...ux
+01.7FFFFE  +7F.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
+7F.7FFFFF  +FE.000000  => +01.000000 ....x  expected +01.000000 ...ux
+80.000000  +FE.000001  => +01.000000 ....x  expected +01.000000 ...ux
+80.7FFFFE  +FE.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-00.7FFFFF  -7E.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-01.000000  -7F.000001  => +01.000000 ....x  expected +01.000000 ...ux
-01.7FFFFF  -80.000000  => +01.000000 ....x  expected +01.000000 ...ux
-01.7FFFFE  -7F.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
-7E.7FFFFF  -FD.000000  => +01.000000 ....x  expected +01.000000 ...ux
-7F.000000  -FD.000001  => +01.000000 ....x  expected +01.000000 ...ux
-7F.7FFFFE  -FD.7FFFFF  => +01.000000 ....x  expected +01.000000 ...ux
46464 tests performed; 14 errors found.
Testing f64_mul, rounding near_even.
46464 tests total.
Errors found in f64_mul, rounding near_even:
+001.0000000000000  +3FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.0000000000000  -3FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  +3FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  -3FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FE.0000000000000  +001.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FE.0000000000000  -001.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FE.FFFFFFFFFFFFF  +001.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FE.FFFFFFFFFFFFF  -001.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.0000000000000  +3FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.0000000000000  -3FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  +3FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  -3FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FE.0000000000000  +001.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FE.0000000000000  -001.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FE.FFFFFFFFFFFFF  +001.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FE.FFFFFFFFFFFFF  -001.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
46464 tests performed; 16 errors found.
Testing f64_mul, rounding min.
46464 tests total.
Errors found in f64_mul, rounding min:
+001.0000000000000  -3FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  -3FD.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  -3FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FD.FFFFFFFFFFFFF  -001.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FE.0000000000000  -001.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FE.FFFFFFFFFFFFF  -001.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.0000000000000  +3FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  +3FD.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  +3FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FD.FFFFFFFFFFFFF  +001.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FE.0000000000000  +001.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FE.FFFFFFFFFFFFF  +001.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
46464 tests performed; 12 errors found.
Testing f64_mul, rounding max.
46464 tests total.
Errors found in f64_mul, rounding max:
+001.0000000000000  +3FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  +3FD.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  +3FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FD.FFFFFFFFFFFFF  +001.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FE.0000000000000  +001.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FE.FFFFFFFFFFFFF  +001.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.0000000000000  -3FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  -3FD.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  -3FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FD.FFFFFFFFFFFFF  -001.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FE.0000000000000  -001.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FE.FFFFFFFFFFFFF  -001.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
46464 tests performed; 12 errors found.
Testing f64_div, rounding near_even.
46464 tests total.
Errors found in f64_div, rounding near_even:
+001.FFFFFFFFFFFFF  +400.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  -400.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FF.FFFFFFFFFFFFF  +7FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FF.FFFFFFFFFFFFF  -7FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  +400.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  -400.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FF.FFFFFFFFFFFFF  +7FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FF.FFFFFFFFFFFFF  -7FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
46464 tests performed; 8 errors found.
Testing f64_div, rounding min.
46464 tests total.
Errors found in f64_div, rounding min:
+000.FFFFFFFFFFFFF  -3FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+001.0000000000000  -3FF.0000000000001
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  -400.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+001.FFFFFFFFFFFFE  -3FF.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+3FF.FFFFFFFFFFFFF  -7FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+400.0000000000000  -7FE.0000000000001
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
+400.FFFFFFFFFFFFE  -7FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-000.FFFFFFFFFFFFF  +3FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.0000000000000  +3FF.0000000000001
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  +400.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-001.FFFFFFFFFFFFE  +3FF.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-3FF.FFFFFFFFFFFFF  +7FE.0000000000000
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-400.0000000000000  +7FE.0000000000001
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
-400.FFFFFFFFFFFFE  +7FE.FFFFFFFFFFFFF
        => -001.0000000000000 ....x  expected -001.0000000000000 ...ux
46464 tests performed; 14 errors found.
Testing f64_div, rounding max.
46464 tests total.
Errors found in f64_div, rounding max:
+000.FFFFFFFFFFFFF  +3FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.0000000000000  +3FF.0000000000001
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.FFFFFFFFFFFFF  +400.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+001.FFFFFFFFFFFFE  +3FF.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+3FF.FFFFFFFFFFFFF  +7FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+400.0000000000000  +7FE.0000000000001
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
+400.FFFFFFFFFFFFE  +7FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-000.FFFFFFFFFFFFF  -3FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.0000000000000  -3FF.0000000000001
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.FFFFFFFFFFFFF  -400.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-001.FFFFFFFFFFFFE  -3FF.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-3FF.FFFFFFFFFFFFF  -7FE.0000000000000
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-400.0000000000000  -7FE.0000000000001
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
-400.FFFFFFFFFFFFE  -7FE.FFFFFFFFFFFFF
        => +001.0000000000000 ....x  expected +001.0000000000000 ...ux
46464 tests performed; 14 errors found.

@sequencer
Copy link

What a shame.

@eastonman
Copy link

Unbelievable

@Kreyren
Copy link

Kreyren commented Sep 10, 2023

CC @chainsx

@MrThanlon
Copy link

c908 (kendryte k230) test success

@palmer-dabbelt
Copy link

Minimal assembly reproduction:

#!/bin/sh

cat <<EOF | as -o thead_bug_probe.o -
.global _start
_start:
    li      a3,0x41
    fscsr   a3
    li      a1, 0xb80fffffc000007f
    fmv.d.x fa5, a1
    fcvt.s.d fa0, fa5
    frflags a0
    li      a7, 93
    ecall
EOF

ld thead_bug_probe.o -o thead_bug_probe

./thead_bug_probe

echo $?

Expected output: 3 LicheePi 4A output: 1

Can you send this to LKML? We should be dynamically probing for this behavior and marking it as an errata for userspace.

@Kreyren
Copy link

Kreyren commented Sep 19, 2023

Do we have any information on whether this problem is fixable in a way that can be used in mission critical environment (no weird hacks)? Or if not what the projected impact of this would be?

@Kreyren
Copy link

Kreyren commented Sep 19, 2023

c908 (kendryte k230) test success -- @MrThanlon (#17 (comment))

Provide test results plz

@sdanfa
Copy link

sdanfa commented Sep 20, 2023

Wow, how did the company did not think to test with test suite units before shipping the boards out?? Really incredible beyond belief.

@hailinzeng
Copy link

image

@hailinzeng
Copy link

C910 datasheet: https://www.t-head.cn/product/C910

@CoelacanthusHex
Copy link

C910 datasheet: t-head.cn/product/C910

图片
In IEEE754-2008 Section 7.5, "The underflow exception shall be signaled when a tiny non-zero result is detected."
In Section 7.1, "This clause specifies five kinds of exceptions that shall be signaled when they arise; the signal invokes default or alternate handling for the signaled exception. For each kind of exception the implementation shall provide a corresponding status flag."
So if C910 doesn't generate float point exceptions, it's not compatible with IEEE754 fully. It conflicts with the 3rd of Section FPU of the C910 datasheet.

@palmer-dabbelt
Copy link

The RISC-V ISA manual is even more explicit about this:

8.4 Subnormal Arithmetic
Operations on subnormal numbers are handled in accordance with the IEEE 754-2008 standard.
In the parlance of the IEEE standard, tininess is detected after rounding.

that said, the T-Head designs pretty frequently violate the ISA so it wouldn't be surprising that's the case here too.

Unfortunately RISC-V still has vendors self-certify their designs. So it doesn't really matter what any of the specs say, we're just stuck with the mess. Unless there's some magic bit we can set to make this IEEE, we're probably stuck just recording it as a user-visible errata -- at least we can probe for this by executing a code sequence and then turn off the FPU until userspace acks it can handle the errata.

That said, that's all probably best discussed on the upstream lists.

@Shanchuang666
Copy link

Please refer to this issue. C910 may have a misunderstanding of the IEEE 754 on after rounding and Rounding-direction attributes. Forgive me for taking the liberty of commenting.
riscv-software-src/riscv-isa-sim#1461
http://www.jhauser.us/arithmetic/SoftFloat-3/doc/SoftFloat-FAQ.html

@yesuweiYYYY
Copy link

Minimal assembly reproduction:

#!/bin/sh

cat <<EOF | as -o thead_bug_probe.o -
.global _start
_start:
    li      a3,0x41
    fscsr   a3
    li      a1, 0xb80fffffc000007f
    fmv.d.x fa5, a1
    fcvt.s.d fa0, fa5
    frflags a0
    li      a7, 93
    ecall
EOF

ld thead_bug_probe.o -o thead_bug_probe

./thead_bug_probe

echo $?

Expected output: 3 LicheePi 4A output: 1

Can you send this to LKML? We should be dynamically probing for this behavior and marking it as an errata for userspace.

Minimal assembly reproduction:

#!/bin/sh

cat <<EOF | as -o thead_bug_probe.o -
.global _start
_start:
    li      a3,0x41
    fscsr   a3
    li      a1, 0xb80fffffc000007f
    fmv.d.x fa5, a1
    fcvt.s.d fa0, fa5
    frflags a0
    li      a7, 93
    ecall
EOF

ld thead_bug_probe.o -o thead_bug_probe

./thead_bug_probe

echo $?

Expected output: 3 LicheePi 4A output: 1

In my opinion this case expected output 1,the LicheePi 4A is true。
exponent of “0xb80fffffc000007f ” is about -126,but underflow need nearly -149.

@Headcrabed
Copy link

Minimal assembly reproduction:

#!/bin/sh

cat <<EOF | as -o thead_bug_probe.o -
.global _start
_start:
    li      a3,0x41
    fscsr   a3
    li      a1, 0xb80fffffc000007f
    fmv.d.x fa5, a1
    fcvt.s.d fa0, fa5
    frflags a0
    li      a7, 93
    ecall
EOF

ld thead_bug_probe.o -o thead_bug_probe

./thead_bug_probe

echo $?

Expected output: 3 LicheePi 4A output: 1

Can you send this to LKML? We should be dynamically probing for this behavior and marking it as an errata for userspace.

Minimal assembly reproduction:

#!/bin/sh

cat <<EOF | as -o thead_bug_probe.o -
.global _start
_start:
    li      a3,0x41
    fscsr   a3
    li      a1, 0xb80fffffc000007f
    fmv.d.x fa5, a1
    fcvt.s.d fa0, fa5
    frflags a0
    li      a7, 93
    ecall
EOF

ld thead_bug_probe.o -o thead_bug_probe

./thead_bug_probe

echo $?

Expected output: 3 LicheePi 4A output: 1

In my opinion this case expected output 1,the LicheePi 4A is true。 exponent of “0xb80fffffc000007f ” is about -126,but underflow need nearly -149.

However test program on K230 reports 3

@QJtaibai
Copy link

Statement of the underflow problem of Xuantie C910 (by XuanTie Group)

Description of the issue

For RISC-V floating-point arithmetic instructions, tininess is detected after rounding as the exponent range is unbounded. Xuantie C910 uses bounded exponent to judge underflow exceptions, resulting in the following extreme cases where underflow bit may not be set:
● The exponent of the original result is emin-1(single precision is -127, double precision is -1024)
● The first N bits of the mantissa of the original result are all 1 (single precision is 24, double precision is 53)
Taking single precision as an example, if the original calculation result is:
image
According to the rounding mode (round to even) , the above results will not be rounded, resulting in an underflow exception.However, Xuantie C910 rounds the above results according to the following format, so there will be no underflow exception.
2-126x0.11111111111111111111111100001…0000
If the original calculation results do not satisfy the extreme corner scenario described above, the underflow exception can be correctly identified.

Impact of the issue

On multiplication, division and conversion instructions(narrow conversion), Xuantie C910 will miss the underflow flag only when the corner result is presented, but will still get the result consistent with correct behaviour.
At the same time, RISC-V floating-point operation exceptions only affect the underflow bit FFLAGS, not the trap. FFLAGS is an accumulative flag. If it is not the only underflow calculation in the whole program, the final calculation result and the underflow flag bit will be correct.
Therefore, in practice, the impact of this issue is expected to be very limited.

@Headcrabed
Copy link

Statement of the underflow problem of Xuantie C910 (by XuanTie Group)

Description of the issue

For RISC-V floating-point arithmetic instructions, tininess is detected after rounding as the exponent range is unbounded. Xuantie C910 uses bounded exponent to judge underflow exceptions, resulting in the following extreme cases where underflow bit may not be set: ● The exponent of the original result is emin-1(single precision is -127, double precision is -1024) ● The first N bits of the mantissa of the original result are all 1 (single precision is 24, double precision is 53) Taking single precision as an example, if the original calculation result is: image According to the rounding mode (round to even) , the above results will not be rounded, resulting in an underflow exception.However, Xuantie C910 rounds the above results according to the following format, so there will be no underflow exception. 2-126x0.11111111111111111111111100001…0000 If the original calculation results do not satisfy the extreme corner scenario described above, the underflow exception can be correctly identified.

Impact of the issue

On multiplication, division and conversion instructions(narrow conversion), Xuantie C910 will miss the underflow flag only when the corner result is presented, but will still get the result consistent with correct behaviour. At the same time, RISC-V floating-point operation exceptions only affect the underflow bit FFLAGS, not the trap. FFLAGS is an accumulative flag. If it is not the only underflow calculation in the whole program, the final calculation result and the underflow flag bit will be correct. Therefore, in practice, the impact of this issue is expected to be very limited.

Source link?

@202459768
Copy link

Statement of the underflow problem of Xuantie C910 (by XuanTie Group)

Description of the issue

For RISC-V floating-point arithmetic instructions, tininess is detected after rounding as the exponent range is unbounded. Xuantie C910 uses bounded exponent to judge underflow exceptions, resulting in the following extreme cases where underflow bit may not be set: ● The exponent of the original result is emin-1(single precision is -127, double precision is -1024) ● The first N bits of the mantissa of the original result are all 1 (single precision is 24, double precision is 53) Taking single precision as an example, if the original calculation result is: image According to the rounding mode (round to even) , the above results will not be rounded, resulting in an underflow exception.However, Xuantie C910 rounds the above results according to the following format, so there will be no underflow exception. 2-126x0.11111111111111111111111100001…0000 If the original calculation results do not satisfy the extreme corner scenario described above, the underflow exception can be correctly identified.

Impact of the issue

On multiplication, division and conversion instructions(narrow conversion), Xuantie C910 will miss the underflow flag only when the corner result is presented, but will still get the result consistent with correct behaviour. At the same time, RISC-V floating-point operation exceptions only affect the underflow bit FFLAGS, not the trap. FFLAGS is an accumulative flag. If it is not the only underflow calculation in the whole program, the final calculation result and the underflow flag bit will be correct. Therefore, in practice, the impact of this issue is expected to be very limited.

Can you provide a link to this reply?

@QJtaibai
Copy link

I am an engineer from the XuanTie Group, and it was here for the first time that the official replied to this issue. All responses from other locations will point here, so here is the Source Link.

@RevySR RevySR changed the title Missing Underflow float exceptions in some cases Missing Underflow float exceptions in some cases (XuanTie Group explained) Dec 22, 2023
@RevySR RevySR pinned this issue Dec 22, 2023
@Headcrabed
Copy link

I am an engineer from the XuanTie Group, and it was here for the first time that the official replied to this issue. All responses from other locations will point here, so here is the Source Link.

Is C920v2 and C907 also affected by this issue?

@QJtaibai
Copy link

C920v2 and C907 are not affected by this issue, and they are not open source right now.

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