summary refs log tree commit diff stats
path: root/results/scraper/launchpad/1701835
blob: 941851672d8303e51a1a9d1a71bdb3f474cd2b2f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
floating-point operation bugs in qemu-alpha

When running the gnulib testsuite, I'm seeing test failures in the tests for libm functions
  cbrt
  cbrtf
  ceil
  ceilf
  coshf
  exp2
  exp2f
  floor
  floorf
  fma
  fmaf
  fmal
  frexp
  frexpf
  hypot
  hypotf
  hypotl
  ilogb
  ilogbf
  isfinite
  isinf
  isnan
  isnand
  isnanf
  ldexp
  ldexpf
  ldexpl
  log1p
  log1pf
  log2
  log2f
  logb
  logbf
  logbl
  rint
  rintf
  rintl
  signbit
  sqrt
  sqrtf
  strtod
that I don't see when running the same (statically linked) executables in a VM, through qemu-system-alpha.

How to reproduce:
- Using gnulib, run ./gnulib-tool --create-testdir --dir=../testdir-math --single-configure cbrt cbrtf ceil ceilf coshf exp2 exp2f float floor floorf fma fmaf fmal frexp frexpf hypot hypotf hypotl ilogb ilogbf isfinite isinf isnan isnand isnanf ldexp ldexpf ldexpl log1p log1pf log2 log2f logb logbf logbl math printf-frexp rint rintf rintl round roundf signbit sqrt sqrtf strtod trunc truncf
- Copy the resulting directory to a VM running Linux 2.6.26 with qemu-system-alpha.
- There, configure and build the package:
  mkdir build-native-static; cd build-native-static; ../configure CPPFLAGS="-Wall" LDFLAGS="-static"; make; make check
  Only 4 tests fail.
- Copy the resulting binaries back to the original x86_64 machine.
- Set environment variables for using qemu-alpha.
- Here, 50 tests fail that did not fail originally:

$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-cbrt
../../gltests/test-cbrt.h:39: assertion 'err > - L_(4.0) * L_(16.0) / TWO_MANT_DIG && err < L_(4.0) * L_(16.0) / TWO_MANT_DIG' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ceil1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ceil2
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ceilf1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ceilf2
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-coshf 
../../gltests/test-coshf.c:37: assertion 'y >= 1.1854652f && y <= 1.1854653f' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-float
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-floor1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-floor2
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-floorf1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-floorf2
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-fma1   
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-fma2
../../gltests/test-fma2.h:116: assertion 'result == expected' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-fmaf1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-fmaf2
../../gltests/test-fma2.h:116: assertion 'result == expected' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-fmal2
../../gltests/test-fma2.h:116: assertion 'result == expected' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-frexp
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-frexpf
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-hypot 
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-hypotf
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-hypotl
../../gltests/test-hypot.h:41: assertion 'z == HUGEVAL' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ilogb 
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ilogbf
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isfinite
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isinf   
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isnan
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isnand-nolibm
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isnand       
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isnanf-nolibm
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-isnanf       
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ldexp 
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ldexpf
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-ldexpl
../../gltests/test-ldexp.h:99: assertion 'y == expected' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-log1p 
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-log1pf
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-log2  
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-log2f
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-logb 
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-logbf
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-math 
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-printf-frexp
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-rint        
../../gltests/test-rint.c:63: assertion 'rint (0.7) == 1.0' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-rintf
../../gltests/test-rintf.c:63: assertion 'rintf (0.7f) == 1.0f' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-rintl
../../gltests/test-rintl.c:68: assertion 'rintl (0.7L) == 1.0L' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-round1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-roundf1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-signbit
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-sqrt   
../../gltests/test-sqrt.h:40: assertion 'err > - L_(16.0) / TWO_MANT_DIG && err < L_(16.0) / TWO_MANT_DIG' failed
Aborted (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-trunc1
Floating point exception (core dumped)
$ ~/inst-qemu/2.9.0/bin/qemu-alpha test-truncf1
Floating point exception (core dumped)



The behaviour in qemu-2.11 is the same as in qemu-2.9.

This is likely expected/correct behavior. You should try building with -mieee.

> You should try building with -mieee.

When I build with
../configure CFLAGS="-mieee -O2 -g" CPPFLAGS=-Wall LDFLAGS="-static -lieee"
I observe the exact same behaviour: Only 4 tests fail in a VM executed with qemu-system-alpha, whereas the same test failures (from test-cbrt to test-truncf1) are seen with qemu-alpha.

Most likely some bits are initialized differently in the FPCR.

Run this:

#include <stdio.h>
#include <string.h>

double get_fpcr()
{
    double x;
    asm ("mf_fpcr %0": "=f" (x));
    return x;
}

int main()
{
    double fpcr = get_fpcr();
    unsigned long l;
    memcpy(&l, &fpcr, 8);
    printf("%016lx\n", l);
    return 0;
}

Under qemu-system-alpha I get 680e800000000000.

Under qemu-system-alpha I get 680e800000000000 as well.

Under qemu-alpha (versions 2.8.1, 2.9.0, 2.10.0, 2.11.0, 2.12.0, 3.1.0) I get 600e800000000000, i.e. bit 59 is unset.

https://download.majix.org/dec/alpha_arch_ref.pdf

The bits are defined in 4.7.8 Floating-Point Control Register (FPCR). 59/58 zero is chopped rounding. This does not seem like a good default.

The fpcr value seen in a process running in a VM comes from the Linux kernel, file linux/arch/alpha/kernel/process.c, function flush_thread():

        /* Arrange for each exec'ed process to start off with a clean slate
           with respect to the FPU.  This is all exceptions disabled.  */
        current_thread_info()->ieee_state = 0;
        wrfpcr(FPCR_DYN_NORMAL | ieee_swcr_to_fpcr(0));

where FPCR_DYN_NORMAL is 0x2UL << 58 /* towards nearest */

Where do we go from here? As far as I understand, qemu-alpha ought to initialize the DYN bits to FPCR_DYN_NORMAL. Where in the code should this be done? I see code in target/alpha/cpu.c, function alpha_cpu_initfn, that initializes the DYN bits to FPCR_DYN_NORMAL. Is this at the wrong place? Is it insufficient for another reason?

Should be fixed by:

http://lists.nongnu.org/archive/html/qemu-devel/2019-01/msg00726.html

No, it is not fixed: even with this patch the program that fetches the fpcr still prints 600e800000000000, and the various program crashes still occur.

Commit https://git.qemu.org/?p=qemu.git;a=commitdiff;h=29eb528078683 claims that this has been fixed. Is the problem still reproducible with QEMU 4.0?

The problem is still reproducible with QEMU 4.0.0:
- The test programs test-cbrt ... test-truncf1 crash or abort as described.
- The test program from comment #6, run with qemu-alpha, prints 600e800000000000, i.e. bit 59 is unset.

There seems to be more confusion of the sort. This fixes it for me:

--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10226,7 +10226,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     return -TARGET_EFAULT;
                 }
                 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
-                fpcr = orig_fpcr & FPCR_DYN_MASK;
+                fpcr = orig_fpcr & ((uint64_t) FPCR_DYN_MASK << 32);

                 /* Copied from linux ieee_swcr_to_fpcr.  */
                 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;

But I would consider this a workaround at best. Having a right-shifted mask in the first place seems rather unhelpful to me.

There is quite a bit missing for proper user-level emulation.
Please try

https://patchwork.ozlabs.org/patch/1091847/

The patch mentioned in #15 fixes the issue:
- The test programs test-cbrt ... test-truncf1 now all succeed.
- The test program from comment #6, run with qemu-alpha, prints 680e800000000000, i.e. bit 59 is set.

Thanks Richard!!

Patch now merged to master and will be in QEMU 4.1.

https://git.qemu.org/?p=qemu.git;a=commitdiff;h=21ba856499f9c0ccdc