This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[IA-64] Fix latent problem in FP div code


Hi,

a couple of years ago I submitted a fix for a problem we ran into in the FP 
div code on IA-64: http://gcc.gnu.org/ml/gcc-patches/2008-06/msg00904.html
It didn't get much attention and the problem is still visible as of today on 
the 4.3 branch with the testcase I provided.

The issue is mitigated by IRA these days but I think that it is still latent.
Moreover the new FP sqrt code suffers from the same problem because frsqrta, 
like frcpa, only sets one predicate register.

Hence the attached patch, tested on ia64-suse-linux, OK for mainline?


2010-08-18  Eric Botcazou  <ebotcazou@adacore.com>

	* config/ia64/ia64.h (HARD_REGNO_NREGS): Return 1 for CCImode in
	general purpose registers.
	(HARD_REGNO_MODE_OK): Accept CCImode in general purpose registers.
	* config/ia64/ia64.md (*movcci): Change to named pattern.  Deal
	with general purpose registers and memory operands.  Add associated
	CCImode post-reload splitter.
	* config/ia64/div.md: Change BImode to CCImode throughout.


-- 
Eric Botcazou
Index: config/ia64/div.md
===================================================================
--- config/ia64/div.md	(revision 163220)
+++ config/ia64/div.md	(working copy)
@@ -37,7 +37,7 @@
 
 (define_insn "addrf3_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (plus:RF
             (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG,fG")
@@ -52,7 +52,7 @@ (define_insn "addrf3_cond"
 
 (define_insn "subrf3_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (minus:RF
             (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG,fG")
@@ -67,7 +67,7 @@ (define_insn "subrf3_cond"
 
 (define_insn "mulrf3_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (mult:RF
             (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG,fG")
@@ -84,7 +84,7 @@ (define_insn "mulrf3_cond"
 
 (define_insn "nmulrf3_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (neg:RF (mult:RF
             (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG,fG")
@@ -101,7 +101,7 @@ (define_insn "nmulrf3_cond"
 
 (define_insn "m1addrf4_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (plus:RF
             (mult:RF
@@ -118,7 +118,7 @@ (define_insn "m1addrf4_cond"
 
 (define_insn "m1subrf4_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (minus:RF
             (mult:RF
@@ -137,7 +137,7 @@ (define_insn "m1subrf4_cond"
 
 (define_insn "m2addrf4_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (plus:RF
             (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG,fG")
@@ -154,7 +154,7 @@ (define_insn "m2addrf4_cond"
 
 (define_insn "m2subrf4_cond"
   [(set (match_operand:RF 0 "fr_register_operand" "=f,f")
-        (if_then_else:RF (ne:RF (match_operand:BI 1 "register_operand"  "c,c")
+        (if_then_else:RF (ne:RF (match_operand:CCI 1 "register_operand"  "c,c")
                                 (const_int 0))
           (minus:RF
             (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG,fG")
@@ -255,8 +255,8 @@ (define_insn "recip_approx_rf"
         (unspec:RF [(match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")
 		    (match_operand:RF 2 "fr_reg_or_fp01_operand" "fG")]
 		   UNSPEC_FR_RECIP_APPROX_RES))
-   (set (match_operand:BI 3 "register_operand" "=c")
-        (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX))
+   (set (match_operand:CCI 3 "register_operand" "=c")
+        (unspec:CCI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX))
    (use (match_operand:SI 4 "const_int_operand" ""))]
   ""
   "frcpa.s%4 %0, %3 = %F1, %F2"
@@ -297,7 +297,7 @@ (define_expand "divsf3_internal_thr"
   rtx q     = gen_reg_rtx (RFmode);
   rtx r     = gen_reg_rtx (RFmode);
   rtx q_res = gen_reg_rtx (RFmode);
-  rtx cond  = gen_reg_rtx (BImode);
+  rtx cond  = gen_reg_rtx (CCImode);
   rtx zero    = CONST0_RTX (RFmode);
   rtx one     = CONST1_RTX (RFmode);
   rtx status0 = CONST0_RTX (SImode);
@@ -345,7 +345,7 @@ (define_expand "divsf3_internal_lat"
   rtx q1        = gen_reg_rtx (RFmode);
   rtx r         = gen_reg_rtx (RFmode);
   rtx q_res     = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx status0   = CONST0_RTX (SImode);
@@ -414,7 +414,7 @@ (define_expand "divdf3_internal_thr"
   rtx y3    = gen_reg_rtx (RFmode);
   rtx q     = gen_reg_rtx (RFmode);
   rtx r     = gen_reg_rtx (RFmode);
-  rtx cond  = gen_reg_rtx (BImode);
+  rtx cond  = gen_reg_rtx (CCImode);
   rtx zero    = CONST0_RTX (RFmode);
   rtx one     = CONST1_RTX (RFmode);
   rtx status0 = CONST0_RTX (SImode);
@@ -471,7 +471,7 @@ (define_expand "divdf3_internal_lat"
   rtx e3        = gen_reg_rtx (RFmode);
   rtx q         = gen_reg_rtx (RFmode);
   rtx r1        = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx status0   = CONST0_RTX (SImode);
@@ -535,7 +535,7 @@ (define_expand "divxf3"
   rtx q         = gen_reg_rtx (RFmode);
   rtx r         = gen_reg_rtx (RFmode);
   rtx r1        = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx status0   = CONST0_RTX (SImode);
@@ -702,7 +702,7 @@ (define_expand "divsi3_internal"
   rtx e1        = gen_reg_rtx (RFmode);
   rtx q         = gen_reg_rtx (RFmode);
   rtx q1        = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx status1   = CONST1_RTX (SImode);
@@ -844,7 +844,7 @@ (define_expand "divdi3_internal_lat"
   rtx q1        = gen_reg_rtx (RFmode);
   rtx q2        = gen_reg_rtx (RFmode);
   rtx r         = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx status1   = CONST1_RTX (SImode);
@@ -888,7 +888,7 @@ (define_expand "divdi3_internal_thr"
   rtx e1        = gen_reg_rtx (RFmode);
   rtx q2        = gen_reg_rtx (RFmode);
   rtx r         = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx status1   = CONST1_RTX (SImode);
@@ -920,8 +920,8 @@ (define_insn "sqrt_approx_rf"
   [(set (match_operand:RF 0 "fr_register_operand" "=f")
                 (unspec:RF [(match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")]
 			   UNSPEC_FR_SQRT_RECIP_APPROX_RES))
-   (set (match_operand:BI 2 "register_operand" "=c")
-        (unspec:BI [(match_dup 1)] UNSPEC_FR_SQRT_RECIP_APPROX))
+   (set (match_operand:CCI 2 "register_operand" "=c")
+        (unspec:CCI [(match_dup 1)] UNSPEC_FR_SQRT_RECIP_APPROX))
    (use (match_operand:SI 3 "const_int_operand" ""))]
   ""
   "frsqrta.s%3 %0, %2 = %F1"
@@ -958,7 +958,7 @@ (define_expand "sqrtsf2_internal_thr"
   rtx h         = gen_reg_rtx (RFmode);
   rtx d         = gen_reg_rtx (RFmode);
   rtx g2        = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx c1        = ia64_dconst_0_5();
@@ -1021,7 +1021,7 @@ (define_expand "sqrtsf2_internal_lat"
   rtx h         = gen_reg_rtx (RFmode);
   rtx h1        = gen_reg_rtx (RFmode);
   rtx d         = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx one       = CONST1_RTX (RFmode);
   rtx c1        = ia64_dconst_0_5();
@@ -1104,7 +1104,7 @@ (define_expand "sqrtdf2_internal_thr"
   rtx h2        = gen_reg_rtx (RFmode);
   rtx d         = gen_reg_rtx (RFmode);
   rtx d1        = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx c1        = ia64_dconst_0_5();
   rtx reg_df_c1	= gen_reg_rtx (DFmode);
@@ -1171,7 +1171,7 @@ (define_expand "sqrtxf2"
   rtx h3        = gen_reg_rtx (RFmode);
   rtx d         = gen_reg_rtx (RFmode);
   rtx d1        = gen_reg_rtx (RFmode);
-  rtx cond      = gen_reg_rtx (BImode);
+  rtx cond      = gen_reg_rtx (CCImode);
   rtx zero      = CONST0_RTX (RFmode);
   rtx c1        = ia64_dconst_0_5();
   rtx reg_df_c1	= gen_reg_rtx (DFmode);
Index: config/ia64/ia64.h
===================================================================
--- config/ia64/ia64.h	(revision 163220)
+++ config/ia64/ia64.h	(working copy)
@@ -646,7 +646,7 @@ while (0)
 #define HARD_REGNO_NREGS(REGNO, MODE)					\
   ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64			\
    : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2				\
-   : PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1			\
+   : (PR_REGNO_P (REGNO) || GR_REGNO_P (REGNO)) && (MODE) == CCImode ? 1\
    : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1				\
    : FR_REGNO_P (REGNO) && (MODE) == RFmode ? 1				\
    : FR_REGNO_P (REGNO) && (MODE) == XCmode ? 2				\
@@ -664,7 +664,7 @@ while (0)
    : PR_REGNO_P (REGNO) ?					\
      (MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC	\
    : GR_REGNO_P (REGNO) ?					\
-     (MODE) != CCImode && (MODE) != XFmode && (MODE) != XCmode && (MODE) != RFmode \
+     (MODE) != XFmode && (MODE) != XCmode && (MODE) != RFmode	\
    : AR_REGNO_P (REGNO) ? (MODE) == DImode			\
    : BR_REGNO_P (REGNO) ? (MODE) == DImode			\
    : 0)
Index: config/ia64/ia64.md
===================================================================
--- config/ia64/ia64.md	(revision 163220)
+++ config/ia64/ia64.md	(working copy)
@@ -217,17 +217,34 @@ (define_attr "speculable2" "no,yes" (con
 ;; Set of a single predicate register.  This is only used to implement
 ;; pr-to-pr move and complement.
 
-(define_insn "*movcci"
-  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
-	(match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
+(define_insn "movcci"
+  [(set (match_operand:CCI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*m,*r")
+	(match_operand:CCI 1 "move_operand"        " O,n, c,  c,*r,*m,*r,*r"))]
   ""
   "@
    cmp.ne %0, p0 = r0, r0
    cmp.eq %0, p0 = r0, r0
-   (%1) cmp.eq.unc %0, p0 = r0, r0"
-  [(set_attr "itanium_class" "icmp")
+   (%1) cmp.eq.unc %0, p0 = r0, r0
+   #
+   tbit.nz %0, p0 = %1, 0
+   ld1%O1 %0 = %1%P1
+   st1%Q0 %0 = %1%P0
+   mov %0 = %1"
+  [(set_attr "itanium_class" "icmp,icmp,icmp,unknown,tbit,ld,st,ialu")
    (set_attr "predicable" "no")])
 
+(define_split
+  [(set (match_operand:CCI 0 "register_operand" "")
+	(match_operand:CCI 1 "register_operand" ""))]
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
+  [(set (match_dup 2) (const_int 0))
+   (cond_exec (ne (match_dup 3) (const_int 0))
+     (set (match_dup 2) (const_int 1)))]
+  "operands[2] = gen_rtx_REG (BImode, REGNO (operands[0]));
+   operands[3] = gen_rtx_REG (BImode, REGNO (operands[1]));")
+
 (define_insn "movbi"
   [(set (match_operand:BI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
 	(match_operand:BI 1 "move_operand"        " O,n, c,  c,*r, n,*m,*r,*r"))]

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]