diff mbox

gcc/config/tilegx/tilegx.md: Compare only 32-bit values for 32-bit comparing

Message ID COL130-W35A9B107C7B25DA8EA549B9090@phx.gbl
State New
Headers show

Commit Message

Chen Gang Dec. 7, 2015, 2:53 p.m. UTC
From 358ae2453a4b965adaf9e684220b7461f719a568 Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Mon, 7 Dec 2015 21:29:20 +0800
Subject: [PATCH] gcc/config/tilegx/tilegx.md: Compare only 32-bit values for 32-bit comparing

For __buildin_mul_overflow(), it will really compare only 32-bit values
for 32-bit comparing. If compare 64-bit values instead of, it will cause
logical issue.

This fix will have low performance for 32-bit comparing (it has more
instructions, also without boundling), but it is correct and fix the
related issue.

2015-12-07  Chen Gang  <gang.chen.5i5j@gmail.com

	* config/tilegx/tilegx.md (insn_cmpne_): Compare only 32-bit
	values for 32-bit comparing.
	* config/tilegx/tilegx.md (insn_cmpeq_): Compare only 32-bit
	values for 32-bit comparing.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 gcc/config/tilegx/tilegx.md | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

-- 
1.9.3

Comments

Richard Henderson Dec. 7, 2015, 3:49 p.m. UTC | #1
On 12/07/2015 06:53 AM, Chen Gang wrote:
> -(define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
> -  [(set (match_operand:I48MODE2 0 "register_operand" "=r")
> -	(ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
> -		     (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
> +(define_insn "insn_cmpne_di<I48MODE:mode>"
> +  [(set (match_operand:I48MODE 0 "register_operand" "=r")
> +	(ne:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")
> +		     (match_operand:DI 2 "reg_or_cint_operand" "rO")))]
>    ""
>    "cmpne\t%0, %r1, %r2")
>   
> -(define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
> -  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
> -	(eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
> -		     (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
> +(define_insn "insn_cmpne_si<I48MODE:mode>"
> +  [(set (match_operand:I48MODE 0 "register_operand" "=r")
> +	(ne:I48MODE (match_operand:SI 1 "reg_or_0_operand" "rO")
> +		     (match_operand:SI 2 "reg_or_cint_operand" "rO")))]
> +  ""
> +  "xor\t%0, %r1, %r2; bfextu\t%0, %0, 0, 31; cmpne\t%0, %0, zero"
> +  [(set_attr "type" "cannot_bundle")])
> +

The preferred solution is to remove SImode comparisons entirely, so that the
middle-end extends the data itself.

In addition, you might experiment with removing the SImode result of the
comparisons here.  We don't have them for Alpha (only DImode result), and we
don't miss them; when SImode results are required they are created via subregs.


r~
diff mbox

Patch

diff --git a/gcc/config/tilegx/tilegx.md b/gcc/config/tilegx/tilegx.md
index 944953c..b694dbd 100644
--- a/gcc/config/tilegx/tilegx.md
+++ b/gcc/config/tilegx/tilegx.md
@@ -1650,22 +1650,40 @@ 
 })
 
  
-(define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
-  [(set (match_operand:I48MODE2 0 "register_operand" "=r")
-	(ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
-		     (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
+(define_insn "insn_cmpne_di<I48MODE:mode>"
+  [(set (match_operand:I48MODE 0 "register_operand" "=r")
+	(ne:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")
+		     (match_operand:DI 2 "reg_or_cint_operand" "rO")))]
   ""
   "cmpne\t%0, %r1, %r2")
  
-(define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
-  [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
-	(eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
-		     (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
+(define_insn "insn_cmpne_si<I48MODE:mode>"
+  [(set (match_operand:I48MODE 0 "register_operand" "=r")
+	(ne:I48MODE (match_operand:SI 1 "reg_or_0_operand" "rO")
+		     (match_operand:SI 2 "reg_or_cint_operand" "rO")))]
+  ""
+  "xor\t%0, %r1, %r2; bfextu\t%0, %0, 0, 31; cmpne\t%0, %0, zero"
+  [(set_attr "type" "cannot_bundle")])
+
+(define_insn "insn_cmpeq_di<I48MODE:mode>"
+  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+	(eq:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
+		     (match_operand:DI 2 "reg_or_cint_operand" "I,rO")))]
   ""
   "@
    cmpeqi\t%0, %r1, %2
    cmpeq\t%0, %r1, %r2")
 
+(define_insn "insn_cmpeq_si<I48MODE:mode>"
+  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+	(eq:I48MODE (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
+		     (match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
+  ""
+  "@
+   xori\t%0, %r1, %2; bfextu\t%0, %0, 0, 31; cmpeqi\t%0, %0, 0
+   xor\t%0, %r1, %r2; bfextu\t%0, %0, 0, 31; cmpeqi\t%0, %0, 0"
+  [(set_attr "type" "cannot_bundle")])
+
 (define_insn "insn_cmplts_<I48MODE:mode><I48MODE2:mode>"
   [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
 	(lt:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")