近日观测到dram和冰冰对RISC-V isa manual float point部分进行了补充说明的patch。
冰冰解释了 printf 打印 float 会丢失符号位,因为有 float 转 double 的过程,但是直接printf double就没有问题。
icenowy@edelgard [ tmp ] $ gcc test.c
icenowy@edelgard [ tmp ] $ ./a.out
-nan
icenowy@edelgard [ tmp ] $ cat test.c
#include <stdio.h>
union u {
unsigned long i;
double f;
};
int main()
{
union u u;
u.i = 0xfff0000001000000ul;
printf("%f\n", u.f);
return 0;
}
恰好我需要修的llvm mlir测例中出现了如下内容:
// CHECK-NEXT: -nan
%h = arith.constant 1.0 : f64
%h_p = arith.constant 0xfff0000001000000 : f64
call @func_powff64(%h, %h_p) : (f64, f64) -> ()
报错:
# .---command stderr------------
# | /home/chenyixuan/llvm-project/mlir/test/mlir-runner/test-expand-math-approx.mlir:236:17: error: CHECK-NEXT: expected string not found in input
# | // CHECK-NEXT: -nan
# | ^
# | <stdin>:39:4: note: scanning from here
# | inf
# | ^
# | <stdin>:40:1: note: possible intended match here
# | nan
# | ^
# |
# | Input file: <stdin>
# | Check file: /home/chenyixuan/llvm-project/mlir/test/mlir-runner/test-expand-math-approx.mlir
# |
# | -dump-input=help explains the following input dump.
# |
# | Input was:
# | <<<<<<
# | .
# | .
# | .
# | 34: 2.343
# | 35: 0.176171
# | 36: 1
# | 37: 6.62637
# | 38: nan
# | 39: inf
# | next:236'0 X error: no match found
# | 40: nan
# | next:236'0 ~~~~
# | next:236'1 ? possible intended match
# | 41: nan
# | next:236'0 ~~~~
# | 42: 1
# | next:236'0 ~~
# | 43: 4
# | next:236'0 ~~
# | 44: 0.25
# | next:236'0 ~~~~~
# | 45: 0
# | next:236'0 ~~
# | .
# | .
# | .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1
于是强大冰冰帮我复现了fail:
(ssh)root@lpi4a66 [ tmp ] # gcc test.c -lm -fno-builtin
(ssh)root@lpi4a66 [ tmp ] # ./a.out
nan
(ssh)root@lpi4a66 [ tmp ] # cat test.c
#include <stdio.h>
#include <math.h>
union u {
unsigned long i;
double f;
};
int main()
{
union u u;
u.i = 0xfff0000001000000ul;
printf("%f\n", pow(1.0, u.f));
return 0;
}
RISC-V 的 nan 在运算之后也会丢失符号位,于是我放宽了测例对符号位的限制。
// CHECK-NEXT: {{-?}}nan