Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1693727 > unrolled thread

[PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation

Started byAleksandar Markovic <aleksandar.markovic@rt-rk.com>
First post2017-07-21 16:20 +0200
Last post2017-07-24 14:50 +0200
Articles 3 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation Aleksandar Markovic <aleksandar.markovic@rt-rk.com> - 2017-07-21 16:20 +0200
    Re: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN  propagation James Hogan <james.hogan@imgtec.com> - 2017-07-24 12:30 +0200
      RE: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN  propagation Aleksandar Markovic <Aleksandar.Markovic@imgtec.com> - 2017-07-24 14:50 +0200

#1693727 — [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation

FromAleksandar Markovic <aleksandar.markovic@rt-rk.com>
Date2017-07-21 16:20 +0200
Subject[PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
Message-ID<u5GWB-5Tl-15@gated-at.bofh.it>
From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

Fix the cases of <MADDF|MSUBF>.<D|S> when any of three inputs is any
NaN. Correct behavior of <MADDF|MSUBF>.<D|S> fd, fs, ft is following:

  - if any of inputs is sNaN, return a sNaN using following rules: if
    only one input is sNaN, return that one; if more than one input is
    sNaN, order of precedence for return value is fd, fs, ft
  - if no input is sNaN, but at least one of inputs is qNaN, return a
    qNaN using following rules: if only one input is qNaN, return that
    one; if more than one input is qNaN, order of precedence for
    return value is fd, fs, ft

The previous code contained handling of some above cases, but not all.
Also, such handling was scattered into various cases of
"switch (CLPAIR(xc, yc))" statement and elsewhere. With this patch,
this logic is placed in one place, and "switch (CLPAIR(xc, yc))" is
significantly simplified.

The relevant example:

MADDF.S fd,fs,ft:
  If fs contains qNaN1, ft contains qNaN2, and fd contains qNaN3, fd
  is going to contain qNaN3 (without this patch, it used to contain
  qNaN1).

Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 arch/mips/math-emu/dp_maddf.c | 71 ++++++++++++++-----------------------------
 arch/mips/math-emu/sp_maddf.c | 69 ++++++++++++++---------------------------
 2 files changed, 46 insertions(+), 94 deletions(-)

diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c
index caa62f2..4f2e783 100644
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -48,52 +48,35 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 
 	ieee754_clearcx();
 
-	switch (zc) {
-	case IEEE754_CLASS_SNAN:
-		ieee754_setcx(IEEE754_INVALID_OPERATION);
-		return ieee754dp_nanxcpt(z);
-	case IEEE754_CLASS_DNORM:
-		DPDNORMZ;
-	/* QNAN and ZERO cases are handled separately below */
-	}
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+	/* handle the cases when at least one of x, y or z is a NaN */
+	if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) ||
+	    ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) ||
+	    ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) {
+		/* order of precedence is z, x, y */
+		if (zc == IEEE754_CLASS_SNAN)
+			return ieee754dp_nanxcpt(z);
+		if (xc == IEEE754_CLASS_SNAN)
+			return ieee754dp_nanxcpt(x);
+		if (yc == IEEE754_CLASS_SNAN)
+			return ieee754dp_nanxcpt(y);
+		if (zc == IEEE754_CLASS_QNAN)
+			return z;
+		if (xc == IEEE754_CLASS_QNAN)
+			return x;
 		return y;
+	}
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
+	if (zc == IEEE754_CLASS_DNORM)
+		DPDNORMZ;
+	/* ZERO z cases are handled separately below */
 
+	switch (CLPAIR(xc, yc)) {
 
 	/*
 	 * Infinity handling
 	 */
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754dp_indef();
 
@@ -102,8 +85,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
 		return ieee754dp_inf(xs ^ ys);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -120,25 +101,19 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 		DPDNORMX;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
 		DPDNORMY;
 		break;
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
 		DPDNORMX;
 		break;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
 		/* fall through to real computations */
 	}
diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c
index c91d5e5..9fd2035 100644
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -48,51 +48,36 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 
 	ieee754_clearcx();
 
-	switch (zc) {
-	case IEEE754_CLASS_SNAN:
-		ieee754_setcx(IEEE754_INVALID_OPERATION);
-		return ieee754sp_nanxcpt(z);
-	case IEEE754_CLASS_DNORM:
-		SPDNORMZ;
-	/* QNAN and ZERO cases are handled separately below */
+	/* handle the cases when at least one of x, y or z is a NaN */
+	if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) ||
+	    ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) ||
+	    ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) {
+		/* order of precedence is z, x, y */
+		if (zc == IEEE754_CLASS_SNAN)
+			return ieee754sp_nanxcpt(z);
+		if (xc == IEEE754_CLASS_SNAN)
+			return ieee754sp_nanxcpt(x);
+		if (yc == IEEE754_CLASS_SNAN)
+			return ieee754sp_nanxcpt(y);
+		if (zc == IEEE754_CLASS_QNAN)
+			return z;
+		if (xc == IEEE754_CLASS_QNAN)
+			return x;
+		return y;
 	}
 
+	if (zc == IEEE754_CLASS_DNORM)
+		SPDNORMZ;
+	/* ZERO z cases are handled separately below */
+
 	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
 
 	/*
 	 * Infinity handling
 	 */
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754sp_indef();
 
@@ -101,8 +86,6 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
 		return ieee754sp_inf(xs ^ ys);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -119,25 +102,19 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 		SPDNORMX;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754sp_inf(zs);
 		SPDNORMY;
 		break;
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754sp_inf(zs);
 		SPDNORMX;
 		break;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754sp_inf(zs);
 		/* fall through to real computations */
 	}
-- 
2.7.4

[toc] | [next] | [standalone]


#1694600 — Re: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation

FromJames Hogan <james.hogan@imgtec.com>
Date2017-07-24 12:30 +0200
SubjectRe: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
Message-ID<u6IMF-3rL-11@gated-at.bofh.it>
In reply to#1693727

[Multipart message — attachments visible in raw view] — view raw

On Fri, Jul 21, 2017 at 04:09:09PM +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> Fix the cases of <MADDF|MSUBF>.<D|S> when any of three inputs is any
> NaN. Correct behavior of <MADDF|MSUBF>.<D|S> fd, fs, ft is following:
> 
>   - if any of inputs is sNaN, return a sNaN using following rules: if
>     only one input is sNaN, return that one; if more than one input is
>     sNaN, order of precedence for return value is fd, fs, ft
>   - if no input is sNaN, but at least one of inputs is qNaN, return a
>     qNaN using following rules: if only one input is qNaN, return that
>     one; if more than one input is qNaN, order of precedence for
>     return value is fd, fs, ft
> 
> The previous code contained handling of some above cases, but not all.
> Also, such handling was scattered into various cases of
> "switch (CLPAIR(xc, yc))" statement and elsewhere. With this patch,
> this logic is placed in one place, and "switch (CLPAIR(xc, yc))" is
> significantly simplified.
> 
> The relevant example:
> 
> MADDF.S fd,fs,ft:
>   If fs contains qNaN1, ft contains qNaN2, and fd contains qNaN3, fd
>   is going to contain qNaN3 (without this patch, it used to contain
>   qNaN1).
> 

Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")

> Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
> Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

If backported, I suspect commits:
6162051e87f6 ("MIPS: math-emu: Unify ieee754sp_m{add,sub}f")
and
d728f6709bcc ("MIPS: math-emu: Unify ieee754dp_m{add,sub}f")
in 4.7 will require manual backporting between 4.3 and 4.7 (due to
separation of maddf/msubf before that point), so I suppose tagging
stable 4.7+ and backporting is best (assuming you consider this fix
worth backporting).

> ---
>  arch/mips/math-emu/dp_maddf.c | 71 ++++++++++++++-----------------------------
>  arch/mips/math-emu/sp_maddf.c | 69 ++++++++++++++---------------------------
>  2 files changed, 46 insertions(+), 94 deletions(-)
> 
> diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c
> index caa62f2..4f2e783 100644
> --- a/arch/mips/math-emu/dp_maddf.c
> +++ b/arch/mips/math-emu/dp_maddf.c
> @@ -48,52 +48,35 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
>  
>  	ieee754_clearcx();
>  
> -	switch (zc) {
> -	case IEEE754_CLASS_SNAN:
> -		ieee754_setcx(IEEE754_INVALID_OPERATION);
> -		return ieee754dp_nanxcpt(z);
> -	case IEEE754_CLASS_DNORM:
> -		DPDNORMZ;
> -	/* QNAN and ZERO cases are handled separately below */
> -	}
> -
> -	switch (CLPAIR(xc, yc)) {
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
> -		return ieee754dp_nanxcpt(y);
> -
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
> -		return ieee754dp_nanxcpt(x);
> -
> -	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
> +	/* handle the cases when at least one of x, y or z is a NaN */
> +	if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) ||
> +	    ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) ||
> +	    ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) {

This condition basically covers all of the cases below. Any particular
reason not to skip it ...

> +		/* order of precedence is z, x, y */
> +		if (zc == IEEE754_CLASS_SNAN)
> +			return ieee754dp_nanxcpt(z);
> +		if (xc == IEEE754_CLASS_SNAN)
> +			return ieee754dp_nanxcpt(x);
> +		if (yc == IEEE754_CLASS_SNAN)
> +			return ieee754dp_nanxcpt(y);
> +		if (zc == IEEE754_CLASS_QNAN)
> +			return z;
> +		if (xc == IEEE754_CLASS_QNAN)
> +			return x;
>  		return y;

... and make this return conditional on (yc == IEEE754_CLASS_QNAN)?

Same for sp_maddf.c too.

Otherwise:
Reviewed-by: James Hogan <james.hogan@imgtec.com>

Cheers
James

> +	}
>  
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
> -		return x;
> +	if (zc == IEEE754_CLASS_DNORM)
> +		DPDNORMZ;
> +	/* ZERO z cases are handled separately below */
>  
> +	switch (CLPAIR(xc, yc)) {
>  
>  	/*
>  	 * Infinity handling
>  	 */
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
>  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
>  		ieee754_setcx(IEEE754_INVALID_OPERATION);
>  		return ieee754dp_indef();
>  
> @@ -102,8 +85,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
>  		return ieee754dp_inf(xs ^ ys);
>  
>  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
> @@ -120,25 +101,19 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
>  		DPDNORMX;
>  
>  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
> -		else if (zc == IEEE754_CLASS_INF)
> +		if (zc == IEEE754_CLASS_INF)
>  			return ieee754dp_inf(zs);
>  		DPDNORMY;
>  		break;
>  
>  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
> -		else if (zc == IEEE754_CLASS_INF)
> +		if (zc == IEEE754_CLASS_INF)
>  			return ieee754dp_inf(zs);
>  		DPDNORMX;
>  		break;
>  
>  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
> -		else if (zc == IEEE754_CLASS_INF)
> +		if (zc == IEEE754_CLASS_INF)
>  			return ieee754dp_inf(zs);
>  		/* fall through to real computations */
>  	}
> diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c
> index c91d5e5..9fd2035 100644
> --- a/arch/mips/math-emu/sp_maddf.c
> +++ b/arch/mips/math-emu/sp_maddf.c
> @@ -48,51 +48,36 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
>  
>  	ieee754_clearcx();
>  
> -	switch (zc) {
> -	case IEEE754_CLASS_SNAN:
> -		ieee754_setcx(IEEE754_INVALID_OPERATION);
> -		return ieee754sp_nanxcpt(z);
> -	case IEEE754_CLASS_DNORM:
> -		SPDNORMZ;
> -	/* QNAN and ZERO cases are handled separately below */
> +	/* handle the cases when at least one of x, y or z is a NaN */
> +	if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) ||
> +	    ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) ||
> +	    ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) {
> +		/* order of precedence is z, x, y */
> +		if (zc == IEEE754_CLASS_SNAN)
> +			return ieee754sp_nanxcpt(z);
> +		if (xc == IEEE754_CLASS_SNAN)
> +			return ieee754sp_nanxcpt(x);
> +		if (yc == IEEE754_CLASS_SNAN)
> +			return ieee754sp_nanxcpt(y);
> +		if (zc == IEEE754_CLASS_QNAN)
> +			return z;
> +		if (xc == IEEE754_CLASS_QNAN)
> +			return x;
> +		return y;
>  	}
>  
> +	if (zc == IEEE754_CLASS_DNORM)
> +		SPDNORMZ;
> +	/* ZERO z cases are handled separately below */
> +
>  	switch (CLPAIR(xc, yc)) {
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
> -		return ieee754sp_nanxcpt(y);
> -
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
> -	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
> -		return ieee754sp_nanxcpt(x);
> -
> -	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
> -		return y;
>  
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
> -	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
> -		return x;
>  
>  	/*
>  	 * Infinity handling
>  	 */
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
>  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
>  		ieee754_setcx(IEEE754_INVALID_OPERATION);
>  		return ieee754sp_indef();
>  
> @@ -101,8 +86,6 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
>  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
>  		return ieee754sp_inf(xs ^ ys);
>  
>  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
> @@ -119,25 +102,19 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
>  		SPDNORMX;
>  
>  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
> -		else if (zc == IEEE754_CLASS_INF)
> +		if (zc == IEEE754_CLASS_INF)
>  			return ieee754sp_inf(zs);
>  		SPDNORMY;
>  		break;
>  
>  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
> -		else if (zc == IEEE754_CLASS_INF)
> +		if (zc == IEEE754_CLASS_INF)
>  			return ieee754sp_inf(zs);
>  		SPDNORMX;
>  		break;
>  
>  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
> -		if (zc == IEEE754_CLASS_QNAN)
> -			return z;
> -		else if (zc == IEEE754_CLASS_INF)
> +		if (zc == IEEE754_CLASS_INF)
>  			return ieee754sp_inf(zs);
>  		/* fall through to real computations */
>  	}
> -- 
> 2.7.4
> 

[toc] | [prev] | [next] | [standalone]


#1694684 — RE: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation

FromAleksandar Markovic <Aleksandar.Markovic@imgtec.com>
Date2017-07-24 14:50 +0200
SubjectRE: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
Message-ID<u6KYa-4Ul-27@gated-at.bofh.it>
In reply to#1694600
> _______________________________________
> From: James Hogan
> Sent: Monday, July 24, 2017 3:24 AM
> To: Aleksandar Markovic
> Cc: linux-mips@linux-mips.org; Aleksandar Markovic; Miodrag Dinic; Goran Ferenc; Douglas Leung; linux-> kernel@vger.kernel.org; Paul Burton; Petar Jovanovic; Raghu Gandham; Ralf Baechle
> Subject: Re: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
> 
> On Fri, Jul 21, 2017 at 04:09:09PM +0200, Aleksandar Markovic wrote:
> > From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> >
> > Fix the cases of <MADDF|MSUBF>.<D|S> when any of three inputs is any
> > NaN. Correct behavior of <MADDF|MSUBF>.<D|S> fd, fs, ft is following:
> >
> >   - if any of inputs is sNaN, return a sNaN using following rules: if
> >     only one input is sNaN, return that one; if more than one input is
> >     sNaN, order of precedence for return value is fd, fs, ft
> >   - if no input is sNaN, but at least one of inputs is qNaN, return a
> >     qNaN using following rules: if only one input is qNaN, return that
> >     one; if more than one input is qNaN, order of precedence for
> >     return value is fd, fs, ft
> >
> > The previous code contained handling of some above cases, but not all.
> > Also, such handling was scattered into various cases of
> > "switch (CLPAIR(xc, yc))" statement and elsewhere. With this patch,
> > this logic is placed in one place, and "switch (CLPAIR(xc, yc))" is
> > significantly simplified.
> >
> > The relevant example:
> >
> > MADDF.S fd,fs,ft:
> >   If fs contains qNaN1, ft contains qNaN2, and fd contains qNaN3, fd
> >   is going to contain qNaN3 (without this patch, it used to contain
> >   qNaN1).
> >
> 
> Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
> Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")
> 

In v4, I will add these lines to commit messages of all MADDF/MSUBF patches from this series.

> > Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
> > Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> > If backported, I suspect commits:
> > 6162051e87f6 ("MIPS: math-emu: Unify ieee754sp_m{add,sub}f")
> > and
> > d728f6709bcc ("MIPS: math-emu: Unify ieee754dp_m{add,sub}f")
> > in 4.7 will require manual backporting between 4.3 and 4.7 (due to
> > separation of maddf/msubf before that point), so I suppose tagging
> > stable 4.7+ and backporting is best (assuming you consider this fix
> > worth backporting).

I am going to tag all MADDF/MSUBF patches "stable 4.7+" and all MIN/MAX/MINA/MAXA patches "stable 4.3+" in v4.

> > ---
> >  arch/mips/math-emu/dp_maddf.c | 71 ++++++++++++++-----------------------------
> >  arch/mips/math-emu/sp_maddf.c | 69 ++++++++++++++---------------------------
> >  2 files changed, 46 insertions(+), 94 deletions(-)
> ...
> > +     /* handle the cases when at least one of x, y or z is a NaN */
> > +     if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) ||
> > +         ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) ||
> > +         ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) {
> 
> This condition basically covers all of the cases below. Any particular
> reason not to skip it ...
> > +             /* order of precedence is z, x, y */
> > +             if (zc == IEEE754_CLASS_SNAN)
> > +                     return ieee754dp_nanxcpt(z);
> > +             if (xc == IEEE754_CLASS_SNAN)
> > +                     return ieee754dp_nanxcpt(x);
> > +             if (yc == IEEE754_CLASS_SNAN)
> > +                     return ieee754dp_nanxcpt(y);
> > +             if (zc == IEEE754_CLASS_QNAN)
> > +                     return z;
> > +             if (xc == IEEE754_CLASS_QNAN)
> > +                     return x;
> >               return y;
> 
> ... and make this return conditional on (yc == IEEE754_CLASS_QNAN)?

You are right. I am going to reorganize the code as you suggested in v4.

Regards,
Aleksandar

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web