This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] aarch64 sim fp min/max number bug fix
- From: Jim Wilson <jim dot wilson at linaro dot org>
- To: gdb-patches at sourceware dot org
- Cc: Nick Clifton <nickc at redhat dot com>
- Date: Sun, 1 Jan 2017 09:16:12 -0800
- Subject: [PATCH] aarch64 sim fp min/max number bug fix
- Authentication-results: sourceware.org; auth=none
The fp min/max number routines are using fpclassify to try to
distinguish between a nan and a number, but this is handling zero,
inf, and subnormals incorrectly. We get the right result if we just
use isnan.
The testcase works with the patch, and fails without the patch. The
patch also reduces GCC C testsuite failures from 2416 to 2407.
Jim
sim/aarch64/
* simulator.c (fmaxnm): Use isnan instead of fpclassify.
(fminnm, dmaxnm, dminnm): Likewise.
sim/testsuite/sim/aarch64/
* fminnm.s: New.
diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index be3d6c7..cf65a51 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -3831,13 +3831,13 @@ do_vec_MLA (sim_cpu *cpu)
static float
fmaxnm (float a, float b)
{
- if (fpclassify (a) == FP_NORMAL)
+ if (! isnan (a))
{
- if (fpclassify (b) == FP_NORMAL)
+ if (! isnan (b))
return a > b ? a : b;
return a;
}
- else if (fpclassify (b) == FP_NORMAL)
+ else if (! isnan (b))
return b;
return a;
}
@@ -3845,13 +3845,13 @@ fmaxnm (float a, float b)
static float
fminnm (float a, float b)
{
- if (fpclassify (a) == FP_NORMAL)
+ if (! isnan (a))
{
- if (fpclassify (b) == FP_NORMAL)
+ if (! isnan (b))
return a < b ? a : b;
return a;
}
- else if (fpclassify (b) == FP_NORMAL)
+ else if (! isnan (b))
return b;
return a;
}
@@ -3859,13 +3859,13 @@ fminnm (float a, float b)
static double
dmaxnm (double a, double b)
{
- if (fpclassify (a) == FP_NORMAL)
+ if (! isnan (a))
{
- if (fpclassify (b) == FP_NORMAL)
+ if (! isnan (b))
return a > b ? a : b;
return a;
}
- else if (fpclassify (b) == FP_NORMAL)
+ else if (! isnan (b))
return b;
return a;
}
@@ -3873,13 +3873,13 @@ dmaxnm (double a, double b)
static double
dminnm (double a, double b)
{
- if (fpclassify (a) == FP_NORMAL)
+ if (! isnan (a))
{
- if (fpclassify (b) == FP_NORMAL)
+ if (! isnan (b))
return a < b ? a : b;
return a;
}
- else if (fpclassify (b) == FP_NORMAL)
+ else if (! isnan (b))
return b;
return a;
}
diff --git a/sim/testsuite/sim/aarch64/fminnm.s b/sim/testsuite/sim/aarch64/fminnm.s
new file mode 100644
index 0000000..43ccd7c
--- /dev/null
+++ b/sim/testsuite/sim/aarch64/fminnm.s
@@ -0,0 +1,82 @@
+# mach: aarch64
+
+# Check the FP min/max number instructions: fminnm, fmaxnm, dminnm, dmaxnm.
+# For min, check 2/1, 1/0, -1/-Inf.
+# For max, check 1/2, -1/0, 1/+inf.
+
+.include "testutils.inc"
+
+ start
+ fmov s0, #2.0
+ fmov s1, #1.0
+ fminnm s2, s0, s1
+ fcmp s2, s1
+ bne .Lfailure
+ fmov d0, #2.0
+ fmov d1, #1.0
+ fminnm d2, d0, d1
+ fcmp d2, d1
+ bne .Lfailure
+
+ fmov s0, #1.0
+ fmov s1, wzr
+ fminnm s2, s0, s1
+ fcmp s2, s1
+ bne .Lfailure
+ fmov d0, #1.0
+ fmov d1, xzr
+ fminnm d2, d0, d1
+ fcmp d2, d1
+ bne .Lfailure
+
+ fmov s0, #-1.0
+ fmov s1, wzr
+ fdiv s1, s0, s1
+ fminnm s2, s0, s1
+ fcmp s2, s1
+ bne .Lfailure
+ fmov d0, #-1.0
+ fmov d1, xzr
+ fdiv d1, d0, d1
+ fminnm d1, d0, d1
+ fcmp d0, d0
+ bne .Lfailure
+
+ fmov s0, #1.0
+ fmov s1, #2.0
+ fmaxnm s2, s0, s1
+ fcmp s2, s1
+ bne .Lfailure
+ fmov d0, #1.0
+ fmov d1, #2.0
+ fmaxnm d2, d0, d1
+ fcmp d2, d1
+ bne .Lfailure
+
+ fmov s0, #-1.0
+ fmov s1, wzr
+ fmaxnm s2, s0, s1
+ fcmp s2, s1
+ bne .Lfailure
+ fmov d0, #-1.0
+ fmov d1, xzr
+ fmaxnm d2, d0, d1
+ fcmp d2, d1
+ bne .Lfailure
+
+ fmov s0, #1.0
+ fmov s1, wzr
+ fdiv s1, s0, s1
+ fmaxnm s2, s0, s1
+ fcmp s2, s1
+ bne .Lfailure
+ fmov d0, #1.0
+ fmov d1, xzr
+ fdiv d1, d0, d1
+ fmaxnm d1, d0, d1
+ fcmp d0, d0
+ bne .Lfailure
+
+ pass
+.Lfailure:
+ fail