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]

3.3: IA64 bug fixes


This is a grab bag of patches - all but one backports from mainline -
which improve the state of the testsuite on ia64-hp-hpux11.23 and I
would expect on other ia64 targets as well.  The overall difference is

(ILP32 mode)

-FAIL: gcc.c-torture/compile/930623-1.c,  -O0  
-FAIL: gcc.c-torture/compile/930623-1.c,  -O1  
-FAIL: gcc.c-torture/compile/930623-1.c,  -O2  
-FAIL: gcc.c-torture/compile/930623-1.c,  -O3 -fomit-frame-pointer  
-FAIL: gcc.c-torture/compile/930623-1.c,  -O3 -g  
-FAIL: gcc.c-torture/compile/930623-1.c,  -Os  
-XPASS: gcc.c-torture/compile/981223-1.c,  -O2  
-XPASS: gcc.c-torture/compile/981223-1.c,  -O3 -fomit-frame-pointer  
-XPASS: gcc.c-torture/compile/981223-1.c,  -O3 -g  
-XPASS: gcc.c-torture/compile/981223-1.c,  -Os  
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O0 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O1 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O2 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -fomit-frame-pointer 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -fomit-frame-pointer -f
unroll-loops 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -fomit-frame-pointer -f
unroll-all-loops -finline-functions 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -g 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -Os 
-FAIL: gcc.dg/ia64-sync-4.c (test for excess errors)
-FAIL: g++.dg/opt/cfg3.C (test for excess errors)

(LP64 mode)

-FAIL: gcc.c-torture/compile/930117-1.c,  -O1  
-FAIL: gcc.c-torture/compile/930117-1.c,  -O2  
-FAIL: gcc.c-torture/compile/930117-1.c,  -O3 -fomit-frame-pointer  
-FAIL: gcc.c-torture/compile/930117-1.c,  -O3 -g  
-FAIL: gcc.c-torture/compile/930117-1.c,  -Os  
-XPASS: gcc.c-torture/compile/981223-1.c,  -O2  
-XPASS: gcc.c-torture/compile/981223-1.c,  -O3 -fomit-frame-pointer  
-XPASS: gcc.c-torture/compile/981223-1.c,  -O3 -g  
-XPASS: gcc.c-torture/compile/981223-1.c,  -Os  
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O0 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O1 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O2 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -fomit-frame-pointer 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -fomit-frame-pointer -f
unroll-loops 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -fomit-frame-pointer -f
unroll-all-loops -finline-functions 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -O3 -g 
-FAIL: gcc.c-torture/execute/va-arg-22.c execution,  -Os 
-FAIL: g++.dg/opt/cfg3.C (test for excess errors)

There are still rather a lot of failures; I'll be looking at more of
them this week.

testsuite/gcc.c-torture/compile/981223-1.x has been deleted on the
mainline; perhaps that is the appropriate change for the branch as
well; I took the more conservative route of simply implementing the
suggestion in the .x file, since it might have been only a quirk of
the version of GAS I use that it didn't print the warning message.

The combine.c change is very large but that's because distribute_notes 
now takes two fewer arguments.  The substance of the change is the
much smaller bit 

-	  if (rtx_equal_p (XEXP (note, 0), elim_i2)
-	      || rtx_equal_p (XEXP (note, 0), elim_i1))
-	    break;
-

and the patch has been on mainline since May with no problems.

OK for 3.3 branch?

zw

gcc:
2003-12-16  Zack Weinberg  <zack@codesourcery.com>

	Backport the following patches from mainline.

    2003-12-05  Mark Mitchell  <mark@codesourcery.com>

	* config/ia64/ia64.h (MUST_PASS_IN_STACK): Define.

    2003-12-01  James E Wilson  <wilson@specifixinc.com>

	* config/ia64/ia64.h (FUNCTION_ARG_REGNO_P): Use AR_REG_FIRST not
	GR_ARG_FIRST.

    2003-10-21  Zack Weinberg  <zack@codesourcery.com>

	* config/ia64/ia64.md (cmpxchg_acq_si): Mark operand 3 as DImode.
	* config/ia64/ia64.c (ia64_expand_fetch_and_op,
	ia64_expand_op_and_fetch): Make sure the REG for ar.ccv is
	DImode.   Use convert_move to load ar.ccv.
	(ia64_expand_compare_and_swap): Likewise.
	If expand_expr doesn't put 'old' and 'new' in the proper
	modes, run them through convert_to_mode.

    2003-10-14  Steve Ellcey  <sje@cup.hp.com>

	* config/ia64/ia64.c (ia64_expand_call): Force function address
	to DImode.
	* config/ia64/ia64.md (call_gp): Put DImode on operand 0.

    2003-06-11  Richard Henderson  <rth@redhat.com>

	* config/ia64/ia64.md (call_gp): Fix memory mode.

    2003-05-14  Eric Christopher  <echristo@redhat.com>

	* combine.c: Fix header comments.
	(distribute_notes): Remove usage of elim_i1, elim_i2. Propagate
	to all calls and prototype.

gcc/testsuite:
2003-12-16  Zack Weinberg  <zack@codesourcery.com>

	* gcc.c-torture/compile/981223-1.x: Add -mb-step to command line
	options on ia64-*-* instead of XFAILing the test case.

===================================================================
Index: combine.c
--- combine.c	6 Oct 2003 08:58:54 -0000	1.325.2.14
+++ combine.c	16 Dec 2003 21:15:17 -0000
@@ -53,10 +53,6 @@ Software Foundation, 59 Temple Place - S
    flow.c aren't completely updated:
 
    - reg_live_length is not updated
-   - reg_n_refs is not adjusted in the rare case when a register is
-     no longer required in a computation
-   - there are extremely rare cases (see distribute_regnotes) when a
-     REG_DEAD note is lost
    - a LOG_LINKS entry that refers to an insn with multiple SETs may be
      removed because there is no way to know which register it was
      linking
@@ -417,7 +413,7 @@ static void reg_dead_at_p_1	PARAMS ((rtx
 static int reg_dead_at_p	PARAMS ((rtx, rtx));
 static void move_deaths		PARAMS ((rtx, rtx, int, rtx, rtx *));
 static int reg_bitfield_target_p  PARAMS ((rtx, rtx));
-static void distribute_notes	PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
+static void distribute_notes	PARAMS ((rtx, rtx, rtx, rtx));
 static void distribute_links	PARAMS ((rtx));
 static void mark_used_regs_combine PARAMS ((rtx));
 static int insn_cuid		PARAMS ((rtx));
@@ -2562,7 +2558,7 @@ try_combine (i3, i2, i1, new_direct_jump
 	  REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
 
       distribute_notes (new_other_notes, undobuf.other_insn,
-			undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
+			undobuf.other_insn, NULL_RTX);
     }
 #ifdef HAVE_cc0
   /* If I2 is the setter CC0 and I3 is the user CC0 then check whether
@@ -2586,15 +2582,6 @@ try_combine (i3, i2, i1, new_direct_jump
     rtx i3links, i2links, i1links = 0;
     rtx midnotes = 0;
     unsigned int regno;
-    /* Compute which registers we expect to eliminate.  newi2pat may be setting
-       either i3dest or i2dest, so we must check it.  Also, i1dest may be the
-       same as i3dest, in which case newi2pat may be setting i1dest.  */
-    rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
-		   || i2dest_in_i2src || i2dest_in_i1src
-		   ? 0 : i2dest);
-    rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
-		   || (newi2pat && reg_set_p (i1dest, newi2pat))
-		   ? 0 : i1dest);
 
     /* Get the old REG_NOTES and LOG_LINKS from all our insns and
        clear them.  */
@@ -2725,17 +2712,13 @@ try_combine (i3, i2, i1, new_direct_jump
 
     /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3.  */
     if (i3notes)
-      distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
-			elim_i2, elim_i1);
+      distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX);
     if (i2notes)
-      distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
-			elim_i2, elim_i1);
+      distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX);
     if (i1notes)
-      distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
-			elim_i2, elim_i1);
+      distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX);
     if (midnotes)
-      distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
-			elim_i2, elim_i1);
+      distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
 
     /* Distribute any notes added to I2 or I3 by recog_for_combine.  We
        know these are REG_UNUSED and want them to go to the desired insn,
@@ -2748,7 +2731,7 @@ try_combine (i3, i2, i1, new_direct_jump
 	  if (GET_CODE (XEXP (temp, 0)) == REG)
 	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
 
-	distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
+	distribute_notes (new_i2_notes, i2, i2, NULL_RTX);
       }
 
     if (new_i3_notes)
@@ -2757,7 +2740,7 @@ try_combine (i3, i2, i1, new_direct_jump
 	  if (GET_CODE (XEXP (temp, 0)) == REG)
 	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
 
-	distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
+	distribute_notes (new_i3_notes, i3, i3, NULL_RTX);
       }
 
     /* If I3DEST was used in I3SRC, it really died in I3.  We may need to
@@ -2775,12 +2758,11 @@ try_combine (i3, i2, i1, new_direct_jump
 	if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
 	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
 					       NULL_RTX),
-			    NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
+			    NULL_RTX, i2, NULL_RTX);
 	else
 	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
 					       NULL_RTX),
-			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
-			    elim_i2, elim_i1);
+			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
       }
 
     if (i2dest_in_i2src)
@@ -2790,11 +2772,10 @@ try_combine (i3, i2, i1, new_direct_jump
 
 	if (newi2pat && reg_set_p (i2dest, newi2pat))
 	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
-			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
+			    NULL_RTX, i2, NULL_RTX);
 	else
 	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
-			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
-			    NULL_RTX, NULL_RTX);
+			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
       }
 
     if (i1dest_in_i1src)
@@ -2804,11 +2785,10 @@ try_combine (i3, i2, i1, new_direct_jump
 
 	if (newi2pat && reg_set_p (i1dest, newi2pat))
 	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
-			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
+			    NULL_RTX, i2, NULL_RTX);
 	else
 	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
-			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
-			    NULL_RTX, NULL_RTX);
+			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
       }
 
     distribute_links (i3links);
@@ -12532,19 +12512,14 @@ reg_bitfield_target_p (x, body)
    as appropriate.  I3 and I2 are the insns resulting from the combination
    insns including FROM (I2 may be zero).
 
-   ELIM_I2 and ELIM_I1 are either zero or registers that we know will
-   not need REG_DEAD notes because they are being substituted for.  This
-   saves searching in the most common cases.
-
    Each note in the list is either ignored or placed on some insns, depending
    on the type of note.  */
 
 static void
-distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
+distribute_notes (notes, from_insn, i3, i2)
      rtx notes;
      rtx from_insn;
      rtx i3, i2;
-     rtx elim_i2, elim_i1;
 {
   rtx note, next_note;
   rtx tem;
@@ -12807,10 +12782,6 @@ distribute_notes (notes, from_insn, i3, 
 		   && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
 	    place = i2;
 
-	  if (rtx_equal_p (XEXP (note, 0), elim_i2)
-	      || rtx_equal_p (XEXP (note, 0), elim_i1))
-	    break;
-
 	  if (place == 0)
 	    {
 	      basic_block bb = this_basic_block;
@@ -12868,7 +12839,7 @@ distribute_notes (notes, from_insn, i3, 
 			  PATTERN (tem) = pc_rtx;
 
 			  distribute_notes (REG_NOTES (tem), tem, tem,
-					    NULL_RTX, NULL_RTX, NULL_RTX);
+					    NULL_RTX);
 			  distribute_links (LOG_LINKS (tem));
 
 			  PUT_CODE (tem, NOTE);
@@ -12883,7 +12854,7 @@ distribute_notes (notes, from_insn, i3, 
 
 			      distribute_notes (REG_NOTES (cc0_setter),
 						cc0_setter, cc0_setter,
-						NULL_RTX, NULL_RTX, NULL_RTX);
+						NULL_RTX);
 			      distribute_links (LOG_LINKS (cc0_setter));
 
 			      PUT_CODE (cc0_setter, NOTE);
@@ -13037,7 +13008,7 @@ distribute_notes (notes, from_insn, i3, 
 				= gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX);
 
 			      distribute_notes (new_note, place, place,
-						NULL_RTX, NULL_RTX, NULL_RTX);
+						NULL_RTX);
 			    }
 			  else if (! refers_to_regno_p (i, i + 1,
 							PATTERN (place), 0)
===================================================================
Index: config/ia64/ia64.c
--- config/ia64/ia64.c	4 Dec 2003 04:47:15 -0000	1.198.2.17
+++ config/ia64/ia64.c	16 Dec 2003 21:15:18 -0000
@@ -1431,6 +1431,7 @@ ia64_expand_call (retval, addr, nextarg,
   rtx insn, b0;
 
   addr = XEXP (addr, 0);
+  addr = convert_memory_address (DImode, addr);
   b0 = gen_rtx_REG (DImode, R_BR (0));
 
   /* ??? Should do this for functions known to bind local too.  */
@@ -7880,13 +7881,14 @@ ia64_expand_fetch_and_op (binoptab, mode
     }
 
   tmp = gen_reg_rtx (mode);
-  ccv = gen_rtx_REG (mode, AR_CCV_REGNUM);
+  /* ar.ccv must always be loaded with a zero-extended DImode value.  */
+  ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
   emit_move_insn (tmp, mem);
 
   label = gen_label_rtx ();
   emit_label (label);
   emit_move_insn (ret, tmp);
-  emit_move_insn (ccv, tmp);
+  convert_move (ccv, tmp, /*unsignedp=*/1);
 
   /* Perform the specific operation.  Special case NAND by noticing
      one_cmpl_optab instead.  */
@@ -7949,14 +7951,15 @@ ia64_expand_op_and_fetch (binoptab, mode
   emit_insn (gen_mf ());
   tmp = gen_reg_rtx (mode);
   old = gen_reg_rtx (mode);
-  ccv = gen_rtx_REG (mode, AR_CCV_REGNUM);
+  /* ar.ccv must always be loaded with a zero-extended DImode value.  */        
+  ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
 
   emit_move_insn (tmp, mem);
 
   label = gen_label_rtx ();
   emit_label (label);
   emit_move_insn (old, tmp);
-  emit_move_insn (ccv, tmp);
+  convert_move (ccv, tmp, /*unsignedp=*/1);
 
   /* Perform the specific operation.  Special case NAND by noticing
      one_cmpl_optab instead.  */
@@ -8009,6 +8012,11 @@ ia64_expand_compare_and_swap (rmode, mod
   mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
   MEM_VOLATILE_P (mem) = 1;
 
+  if (GET_MODE (old) != mode)
+    old = convert_to_mode (mode, old, /*unsignedp=*/1);
+  if (GET_MODE (new) != mode)
+    new = convert_to_mode (mode, new, /*unsignedp=*/1);
+
   if (! register_operand (old, mode))
     old = copy_to_mode_reg (mode, old);
   if (! register_operand (new, mode))
@@ -8020,14 +8028,7 @@ ia64_expand_compare_and_swap (rmode, mod
     tmp = gen_reg_rtx (mode);
 
   ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
-  if (mode == DImode)
-    emit_move_insn (ccv, old);
-  else
-    {
-      rtx ccvtmp = gen_reg_rtx (DImode);
-      emit_insn (gen_zero_extendsidi2 (ccvtmp, old));
-      emit_move_insn (ccv, ccvtmp);
-    }
+  convert_move (ccv, old, /*unsignedp=*/1);
   emit_insn (gen_mf ());
   if (mode == SImode)
     insn = gen_cmpxchg_acq_si (tmp, mem, new, ccv);
===================================================================
Index: config/ia64/ia64.h
--- config/ia64/ia64.h	4 Dec 2003 04:47:17 -0000	1.135.2.6
+++ config/ia64/ia64.h	16 Dec 2003 21:15:18 -0000
@@ -1289,6 +1289,13 @@ enum reg_class
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
   ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
 
+/* Nonzero if we do not know how to pass TYPE solely in registers.  */
+
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+  ((TYPE) != 0							\
+   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST		\
+       || TREE_ADDRESSABLE (TYPE)))
+
 /* A C type for declaring a variable that is used as the first argument of
    `FUNCTION_ARG' and other related values.  For some target machines, the type
    `int' suffices and can hold the number of bytes of argument so far.  */
@@ -1353,7 +1360,7 @@ do {									\
    On many machines, no registers can be used for this purpose since all
    function arguments are pushed on the stack.  */
 #define FUNCTION_ARG_REGNO_P(REGNO) \
-(((REGNO) >= GR_ARG_FIRST && (REGNO) < (GR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \
+(((REGNO) >= AR_ARG_FIRST && (REGNO) < (AR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \
  || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS)))
 
 /* Implement `va_arg'.  */
===================================================================
Index: config/ia64/ia64.md
--- config/ia64/ia64.md	8 Aug 2003 22:07:14 -0000	1.94.4.8
+++ config/ia64/ia64.md	16 Dec 2003 21:15:20 -0000
@@ -4802,7 +4802,7 @@
   [(set_attr "itanium_class" "br,scall")])
 
 (define_insn "call_gp"
-  [(call (mem (match_operand 0 "call_operand" "?r,i"))
+  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
 	 (const_int 1))
    (clobber (match_operand:DI 1 "register_operand" "=b,b"))
    (clobber (match_scratch:DI 2 "=&r,X"))
@@ -5451,7 +5451,7 @@
    (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
         (unspec:SI [(match_dup 1)
                     (match_operand:SI 2 "gr_register_operand" "r")
-		    (match_operand 3 "ar_ccv_reg_operand" "")]
+		    (match_operand:DI 3 "ar_ccv_reg_operand" "")]
 		   UNSPEC_CMPXCHG_ACQ))]
   ""
   "cmpxchg4.acq %0 = %1, %2, %3"
===================================================================
Index: testsuite/gcc.c-torture/compile/981223-1.x
--- testsuite/gcc.c-torture/compile/981223-1.x	1 Mar 2002 18:39:21 -0000	1.2
+++ testsuite/gcc.c-torture/compile/981223-1.x	16 Dec 2003 21:15:23 -0000
@@ -1,20 +1,14 @@
-# The problem on IA-64 is that the assembler emits
+# On IA-64 the assembler may emit
 #
 # Warning: Additional NOP may be necessary to workaround Itanium
 # processor A/B step errata
 #
 # This can be fixed by adding "-mb-step" to the command line, which
-# does in fact add the extra nop, if someone can tell me how to do
-# that for a c-torture compile test.
+# does in fact add the extra nop.
 
-set torture_eval_before_compile {
-
-    set compiler_conditional_xfail_data {
-        "need -mb-step" \
-        "ia64-*-*" \
-        { "-O2" "-O3" "-Os" } \
-        { "" }
+if [istarget "ia64-*-*"] {
+    set torture_eval_before_compile {
+        set option "$option -mb-step"
     }
 }
-
 return 0


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