diff options
Diffstat (limited to 'results/classifier/semantic-bugs/other')
| -rw-r--r-- | results/classifier/semantic-bugs/other/1267955 | 187 | ||||
| -rw-r--r-- | results/classifier/semantic-bugs/other/2371 | 65 | ||||
| -rw-r--r-- | results/classifier/semantic-bugs/other/2372 | 122 | ||||
| -rw-r--r-- | results/classifier/semantic-bugs/other/2374 | 124 |
4 files changed, 498 insertions, 0 deletions
diff --git a/results/classifier/semantic-bugs/other/1267955 b/results/classifier/semantic-bugs/other/1267955 new file mode 100644 index 00000000..fe163590 --- /dev/null +++ b/results/classifier/semantic-bugs/other/1267955 @@ -0,0 +1,187 @@ +other: 0.979 +assembly: 0.959 +device: 0.954 +KVM: 0.953 +vnc: 0.950 +instruction: 0.947 +semantic: 0.945 +graphic: 0.944 +network: 0.942 +mistranslation: 0.913 +socket: 0.912 +boot: 0.895 + +[i386] Parity Flag Not Set On xor %eax,%eax + +Tested against qemu-1.7.0 as well as qemu-1.7.50 on Debian Sid + +Steps To Reproduce + +$ cat > prog.hex << EOF + +7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 +02 00 03 00 01 00 00 00 54 80 04 08 34 00 00 00 +00 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00 +00 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 +00 80 04 08 76 00 00 00 76 00 00 00 05 00 00 00 +00 10 00 00 + +31 c0 +9c + +b8 04 00 00 00 +bb 01 00 00 00 +89 e1 +ba 04 00 00 00 +cd 80 + +b8 01 00 00 00 +bb 00 00 00 00 +cd 80 + +EOF + +$ xxd -p -r prog.hex > prog +$ chmod 700 prog + +$ ./prog | hexdump -vC +00000000 46 02 00 00 |F...| +00000004 + +$ qemu-i386 ./prog | hexdump -vC +00000000 42 02 00 00 |B...| +00000004 + +On the other hand if [xor %eax, %eax] (31 c0) is replaced with sub %eax,%eax (29 c0), then the parity flag is set correctly. + +Parity should be set for a zero result. + +Signed-off-by: Richard Henderson <email address hidden> +--- + target-i386/cc_helper.c | 2 +- + target-i386/translate.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c +index ee04092..05dd12b 100644 +--- a/target-i386/cc_helper.c ++++ b/target-i386/cc_helper.c +@@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, + case CC_OP_EFLAGS: + return src1; + case CC_OP_CLR: +- return CC_Z; ++ return CC_Z | CC_P; + + case CC_OP_MULB: + return compute_all_mulb(dst, src1); +diff --git a/target-i386/translate.c b/target-i386/translate.c +index b0f2279..34f35e7 100644 +--- a/target-i386/translate.c ++++ b/target-i386/translate.c +@@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s) + return; + } + if (s->cc_op == CC_OP_CLR) { +- tcg_gen_movi_tl(cpu_cc_src, CC_Z); ++ tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P); + set_cc_op(s, CC_OP_EFLAGS); + return; + } +-- +1.8.4.2 + + + +On Fri, Jan 10, 2014 at 12:39:56PM -0800, Richard Henderson wrote: +> Parity should be set for a zero result. +> +> Signed-off-by: Richard Henderson <email address hidden> + +Reviewed-by: Edgar E. Iglesias <email address hidden> + + +> --- +> target-i386/cc_helper.c | 2 +- +> target-i386/translate.c | 2 +- +> 2 files changed, 2 insertions(+), 2 deletions(-) +> +> diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c +> index ee04092..05dd12b 100644 +> --- a/target-i386/cc_helper.c +> +++ b/target-i386/cc_helper.c +> @@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, +> case CC_OP_EFLAGS: +> return src1; +> case CC_OP_CLR: +> - return CC_Z; +> + return CC_Z | CC_P; +> +> case CC_OP_MULB: +> return compute_all_mulb(dst, src1); +> diff --git a/target-i386/translate.c b/target-i386/translate.c +> index b0f2279..34f35e7 100644 +> --- a/target-i386/translate.c +> +++ b/target-i386/translate.c +> @@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s) +> return; +> } +> if (s->cc_op == CC_OP_CLR) { +> - tcg_gen_movi_tl(cpu_cc_src, CC_Z); +> + tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P); +> set_cc_op(s, CC_OP_EFLAGS); +> return; +> } +> -- +> 1.8.4.2 +> +> + + +Quoting Richard Henderson (2014-01-10 14:39:56) +> Parity should be set for a zero result. +> +> Signed-off-by: Richard Henderson <email address hidden> + +ping for 1.7.1 + +> --- +> target-i386/cc_helper.c | 2 +- +> target-i386/translate.c | 2 +- +> 2 files changed, 2 insertions(+), 2 deletions(-) +> +> diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c +> index ee04092..05dd12b 100644 +> --- a/target-i386/cc_helper.c +> +++ b/target-i386/cc_helper.c +> @@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, +> case CC_OP_EFLAGS: +> return src1; +> case CC_OP_CLR: +> - return CC_Z; +> + return CC_Z | CC_P; +> +> case CC_OP_MULB: +> return compute_all_mulb(dst, src1); +> diff --git a/target-i386/translate.c b/target-i386/translate.c +> index b0f2279..34f35e7 100644 +> --- a/target-i386/translate.c +> +++ b/target-i386/translate.c +> @@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s) +> return; +> } +> if (s->cc_op == CC_OP_CLR) { +> - tcg_gen_movi_tl(cpu_cc_src, CC_Z); +> + tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P); +> set_cc_op(s, CC_OP_EFLAGS); +> return; +> } +> -- +> 1.8.4.2 + + + +Fix had been included here: +http://git.qemu.org/?p=qemu.git;a=commitdiff;h=d2fe51bda8adf33d07c21 +==> Closing + diff --git a/results/classifier/semantic-bugs/other/2371 b/results/classifier/semantic-bugs/other/2371 new file mode 100644 index 00000000..2db65ca1 --- /dev/null +++ b/results/classifier/semantic-bugs/other/2371 @@ -0,0 +1,65 @@ +other: 0.840 +semantic: 0.839 +graphic: 0.831 +mistranslation: 0.816 +vnc: 0.770 +socket: 0.722 +network: 0.699 +instruction: 0.679 +device: 0.671 +assembly: 0.628 +boot: 0.550 +KVM: 0.531 + +A bug in RISC-V froundnx.h instruction +Description of problem: +According to the RISCV ISA manual, the froundnx.h instruction rounds a half-precision floating-point number in the source register to an integer and writes the integer, represented as a half-precision floating-point number, to the destination register. Because the values are stored in 64-bit width registers, they must be NaN-unboxed/boxed before/after the operation. When an input value lacks the proper form of NaN-boxing, it should be treated as a canonical NaN. +However, when an incorrectly NaN-boxed value is passed to froundnx.h, QEMU produces 0 instead of the canonical NaN. This is because there is a typo in the definition of helper_froundnx_h: +``` +// target/riscv/fpu_helper.c +uint64_t helper_froundnx_h(CPURISCVState *env, uint64_t rs1) +{ + float16 frs1 = check_nanbox_s(env, rs1); // This should be check_nanbox_h. + frs1 = float16_round_to_int(frs1, &env->fp_status); + return nanbox_h(env, frs1); +} +``` +Steps to reproduce: +1. Write `test.c`. +``` +#include <stdio.h> + +char i_F6[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; +char o_F5[8]; + +void __attribute__ ((noinline)) show_state() { + for (int i = 0; i < 8; i++) { + printf("%02x ", o_F5[i]); + } + printf("\n"); +} + +void __attribute__ ((noinline)) run() { + __asm__ ( + "lui t5, %hi(i_F6)\n" + "addi t5, t5, %lo(i_F6)\n" + "fld ft6, 0(t5)\n" + ".insn 0x445372d3\n" // froundnx.h ft5, ft6 + "lui t5, %hi(o_F5)\n" + "addi t5, t5, %lo(o_F5)\n" + "fsd ft5, 0(t5)\n" + ); +} + +int main(int argc, char **argv) { + run(); + show_state(); + + return 0; +} +``` +2. Compile `test.bin` using this command: `riscv64-linux-gnu-gcc-12 -O2 -no-pie -march=rv64iv ./test.c -o ./test.bin`. +3. Run QEMU using this command: `qemu-riscv64 -L /usr/riscv64-linux-gnu/ ./test.bin`. +4. The program, runs on top of the buggy QEMU, prints `00 00 ff ff ff ff ff ff`. It should print `00 7e ff ff ff ff ff ff` after the bug is fixed. +Additional information: + diff --git a/results/classifier/semantic-bugs/other/2372 b/results/classifier/semantic-bugs/other/2372 new file mode 100644 index 00000000..577fd84a --- /dev/null +++ b/results/classifier/semantic-bugs/other/2372 @@ -0,0 +1,122 @@ +other: 0.980 +graphic: 0.975 +semantic: 0.973 +instruction: 0.950 +assembly: 0.946 +device: 0.939 +socket: 0.930 +network: 0.922 +vnc: 0.901 +boot: 0.887 +mistranslation: 0.862 +KVM: 0.808 + +A bug in AArch64 UMOPA/UMOPS (4-way) instruction +Description of problem: +umopa computes the multiplication of two matrices in the source registers and accumulates the result to the destination register. A source register’s element size is 16 bits, while a destination register’s element size is 64 bits in case of the 4-way variant of this instruction. Before performing matrix multiplication, each element should be zero-extended to a 64-bit element. + +However, the current implementation of the helper function fails to convert the element type correctly. Below is the helper function implementation: +``` +// target/arm/tcg/sme_helper.c +#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \ +static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \ +{ \ + uint64_t sum = 0; \ + /* Apply P to N as a mask, making the inactive elements 0. */ \ + n &= expand_pred_h(p); \ + sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \ + sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \ + sum += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \ + sum += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \ + return neg ? a - sum : a + sum; \ +} + +DEF_IMOP_64(umopa_d, uint16_t, uint16_t) +``` +When the multiplication is performed, each element, such as `(NTYPE)(n >> 0)`, is automatically converted to `int32_t`, so the computation result has a type `int32_t`. The result is then converted to `uint64_t`, and it is added to `sum`. It seems the elements should be casted to `uint64_t` **before** performing the multiplication. +Steps to reproduce: +1. Write `test.c`. +``` +#include <stdio.h> + +char i_P1[4] = { 0xff, 0xff, 0xff, 0xff }; +char i_P5[4] = { 0xff, 0xff, 0xff, 0xff }; +char i_Z0[32] = { // Set only the first element as non-zero + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +}; +char i_Z20[32] = { // Set only the first element as non-zero + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +}; +char i_ZA2H[128] = { 0x0, }; +char o_ZA2H[128]; + +void __attribute__ ((noinline)) show_state() { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 16; j++) { + printf("%02x ", o_ZA2H[16*i+j]); + } + printf("\n"); + } +} + +void __attribute__ ((noinline)) run() { + __asm__ ( + ".arch armv9.3-a+sme\n" + "smstart\n" + "adrp x29, i_P1\n" + "add x29, x29, :lo12:i_P1\n" + "ldr p1, [x29]\n" + "adrp x29, i_P5\n" + "add x29, x29, :lo12:i_P5\n" + "ldr p5, [x29]\n" + "adrp x29, i_Z0\n" + "add x29, x29, :lo12:i_Z0\n" + "ldr z0, [x29]\n" + "adrp x29, i_Z20\n" + "add x29, x29, :lo12:i_Z20\n" + "ldr z20, [x29]\n" + "adrp x29, i_ZA2H\n" + "add x29, x29, :lo12:i_ZA2H\n" + "mov x15, 0\n" + "ld1d {za2h.d[w15, 0]}, p1, [x29]\n" + "add x29, x29, 32\n" + "ld1d {za2h.d[w15, 1]}, p1, [x29]\n" + "add x29, x29, 32\n" + "mov x15, 2\n" + "ld1d {za2h.d[w15, 0]}, p1, [x29]\n" + "add x29, x29, 32\n" + "ld1d {za2h.d[w15, 1]}, p1, [x29]\n" + ".inst 0xa1f43402\n" // umopa za2.d, p5/m, p1/m, z0.h, z20.h + "adrp x29, o_ZA2H\n" + "add x29, x29, :lo12:o_ZA2H\n" + "mov x15, 0\n" + "st1d {za2h.d[w15, 0]}, p1, [x29]\n" + "add x29, x29, 32\n" + "st1d {za2h.d[w15, 1]}, p1, [x29]\n" + "add x29, x29, 32\n" + "mov x15, 2\n" + "st1d {za2h.d[w15, 0]}, p1, [x29]\n" + "add x29, x29, 32\n" + "st1d {za2h.d[w15, 1]}, p1, [x29]\n" + "smstop\n" + ".arch armv8-a\n" + ); +} + +int main(int argc, char **argv) { + run(); + show_state(); + return 0; +} +``` +2. Compile `test.bin` using this command: `aarch64-linux-gnu-gcc-12 -O2 -no-pie ./test.c -o ./test.bin`. +3. Run `QEMU` using this command: `qemu-aarch64 -L /usr/aarch64-linux-gnu/ -cpu max,sme256=on ./test.bin`. +4. The program, runs on top of the buggy QEMU, prints the first 8 bytes of `ZA2H` as `01 00 fe ff ff ff ff ff`. It should print `01 00 fe ff 00 00 00 00` after the bug is fixed. +Additional information: + diff --git a/results/classifier/semantic-bugs/other/2374 b/results/classifier/semantic-bugs/other/2374 new file mode 100644 index 00000000..676db53f --- /dev/null +++ b/results/classifier/semantic-bugs/other/2374 @@ -0,0 +1,124 @@ +other: 0.893 +instruction: 0.885 +device: 0.878 +graphic: 0.876 +vnc: 0.873 +semantic: 0.872 +assembly: 0.865 +boot: 0.833 +network: 0.812 +KVM: 0.804 +mistranslation: 0.792 +socket: 0.782 + +A bug in AArch64 FMOPA/FMOPS (non-widening) instruction +Description of problem: +fmopa computes the multiplication of two matrices in the source registers and accumulates the result to the destination register. Depending on the instruction encoding, the element size of operands is either 32 bits or 64 bits. When the computation produces a NaN as a result, the default NaN should be generated. + +However, the current implementation of 32-bit variant of this instruction does not generate default NaNs, because invalid float_status pointer is passed: +``` +// target/arm/tcg/sme_helper.c +void HELPER(sme_fmopa_s)(void *vza, void *vzn, void *vzm, void *vpn, + void *vpm, void *vst, uint32_t desc) +{ +... + float_status fpst; + + /* + * Make a copy of float_status because this operation does not + * update the cumulative fp exception status. It also produces + * default nans. + */ + fpst = *(float_status *)vst; + set_default_nan_mode(true, &fpst); + +... + *a = float32_muladd(n, *m, *a, 0, vst); // &fpst should be used +... +} +``` +Steps to reproduce: +1. Write `test.c`. +``` +#include <stdio.h> + +char i_P0[4] = { 0xff, 0xff, 0xff, 0xff }; +char i_P6[4] = { 0xff, 0xff, 0xff, 0xff }; +char i_Z9[32] = { // Set only the first element as NaN, but it is not default NaN. + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +}; +char i_Z27[32] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +}; +char i_ZA1H[128] = { 0x0, }; +char o_ZA1H[128]; + +void __attribute__ ((noinline)) show_state() { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 16; j++) { + printf("%02x ", o_ZA1H[16*i+j]); + } + printf("\n"); + } +} + +void __attribute__ ((noinline)) run() { + __asm__ ( + ".arch armv9.3-a+sme\n" + "smstart\n" + "adrp x29, i_P0\n" + "add x29, x29, :lo12:i_P0\n" + "ldr p0, [x29]\n" + "adrp x29, i_P6\n" + "add x29, x29, :lo12:i_P6\n" + "ldr p6, [x29]\n" + "adrp x29, i_Z9\n" + "add x29, x29, :lo12:i_Z9\n" + "ldr z9, [x29]\n" + "adrp x29, i_Z27\n" + "add x29, x29, :lo12:i_Z27\n" + "ldr z27, [x29]\n" + "adrp x29, i_ZA1H\n" + "add x29, x29, :lo12:i_ZA1H\n" + "mov x15, 0\n" + "ld1w {za1h.s[w15, 0]}, p0, [x29]\n" + "add x29, x29, 32\n" + "ld1w {za1h.s[w15, 1]}, p0, [x29]\n" + "add x29, x29, 32\n" + "mov x15, 2\n" + "ld1w {za1h.s[w15, 0]}, p0, [x29]\n" + "add x29, x29, 32\n" + "ld1w {za1h.s[w15, 1]}, p0, [x29]\n" + ".inst 0x809bc121\n" // fmopa za1.s, p0/m, p6/m, z9.s, z27.s + "adrp x29, o_ZA1H\n" + "add x29, x29, :lo12:o_ZA1H\n" + "mov x15, 0\n" + "st1w {za1h.s[w15, 0]}, p0, [x29]\n" + "add x29, x29, 32\n" + "st1w {za1h.s[w15, 1]}, p0, [x29]\n" + "add x29, x29, 32\n" + "mov x15, 2\n" + "st1w {za1h.s[w15, 0]}, p0, [x29]\n" + "add x29, x29, 32\n" + "st1w {za1h.s[w15, 1]}, p0, [x29]\n" + ".arch armv8-a\n" + ); +} + +int main(int argc, char **argv) { + run(); + show_state(); + return 0; +} +``` +2. Compile `test.bin` using this command: `aarch64-linux-gnu-gcc-12 -O2 -no-pie ./test.c -o ./test.bin`. +3. Run QEMU using this command: `qemu-aarch64 -L /usr/aarch64-linux-gnu/ -cpu max,sme256=on ./test.bin`. +4. The program, runs on top of the buggy QEMU, prints 8 non-default NaNs (ff ff ff ff). It should print 8 default NaNs (00 00 c0 7f) after the bug is fixed. +Additional information: + |