This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
3.3: IA64 bug fixes
- From: "Zack Weinberg" <zack at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org, Gabriel Dos Reis<Gabriel dot Dos-Reis at cmla dot ens-cachan dot fr>
- Date: Tue, 16 Dec 2003 13:20:05 -0800
- Subject: 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