This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR24367 S/390 pic address handling
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Aug 2006 10:55:15 +0200
- Subject: [PATCH] PR24367 S/390 pic address handling
Hello,
this fixes an ICE on s390 31bit.
When loop-iv computes the noloop_assumption condition it uses the earliest
occurences of the values used in the condition drawing REQ_EQUAL notes into
account (simplify_using_assignment).
For the PR testcase a REQ_EQUAL note contains the following expression
(r12 is the s390 got pointer):
(plus:SI (reg:SI 12 %r12)
(const:SI (plus:SI (unspec:SI [
(symbol_ref:SI ("_ZZ4testPKcS0_E8rtn_path")] 112)
(const_int 1024)))))
The s390 legitimize_address function as well as the movsi and movdi expanders
force a (const (plus (unspec) (const_int))) into the literal pool. The expression
reappears here since loop-iv used the content of the REQ_EQUAL note for the
target register of the load address.
When the noloop_assumption condition of the loop is emitted force_operand is used
for all operands in the condition. Unfortunately force_operand fails to recognize
that the above expression is invalid to be used directly due to the following code:
/* Check for a PIC address load. */
if ((code == PLUS || code == MINUS)
&& XEXP (value, 0) == pic_offset_table_rtx
&& (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
|| GET_CODE (XEXP (value, 1)) == LABEL_REF
|| GET_CODE (XEXP (value, 1)) == CONST))
{
if (!subtarget)
subtarget = gen_reg_rtx (GET_MODE (value));
emit_move_insn (subtarget, value);
return subtarget;
This considers rtxs as: <pic register> +/- (SYMBOL_REF|LABEL_REF|CONST) as always
valid. This is - at least for s390 - not the case. So force_operand emits an INSN
loading r12 + (const ...) into a register which can't be recognized.
Although I don't think that the assumption in force_operand is always correct I've
tried to fix this in the back end. The attached patch makes the movsi and movdi
expanders to accept addresses of the form r12 + <contains a symbolic const>. The
address then gets fixed by legitimize_pic_address.
Bootstrapped on s390 and s390x with gcc 4.1 and mainline.
No testsuite regressions.
OK for mainline and 4.1 branch?
Bye,
-Andreas-
2006-08-28 Andreas Krebbel <krebbel1@de.ibm.com>
PR target/24367
* config/s390/s390.md ("movsi", "movdi" expander): Accept rtxes like
r12 + SYMBOLIC_CONST.
2006-08-28 Andreas Krebbel <krebbel1@de.ibm.com>
PR target/24367
* gcc.dg/pr24367.c: New testcase.
Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig 2006-08-28 10:38:37.000000000 +0200
--- gcc/config/s390/s390.md 2006-08-28 10:44:22.000000000 +0200
***************
*** 907,913 ****
""
{
/* Handle symbolic constants. */
! if (TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
emit_symbolic_move (operands);
})
--- 907,918 ----
""
{
/* Handle symbolic constants. */
! if (TARGET_64BIT
! && (SYMBOLIC_CONST (operands[1])
! || (GET_CODE (operands[1]) == PLUS
! && REG_P (XEXP (operands[1], 0))
! && XEXP (operands[1], 0) == pic_offset_table_rtx
! && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
emit_symbolic_move (operands);
})
***************
*** 1158,1164 ****
""
{
/* Handle symbolic constants. */
! if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
emit_symbolic_move (operands);
})
--- 1163,1174 ----
""
{
/* Handle symbolic constants. */
! if (!TARGET_64BIT
! && (SYMBOLIC_CONST (operands[1])
! || (GET_CODE (operands[1]) == PLUS
! && REG_P (XEXP (operands[1], 0))
! && XEXP (operands[1], 0) == pic_offset_table_rtx
! && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
emit_symbolic_move (operands);
})
Index: gcc/testsuite/gcc.dg/pr24367.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/pr24367.c 2006-08-28 10:43:37.000000000 +0200
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile { target fpic } } */
+ /* { dg-options "-O2 -fPIC -funroll-loops" } */
+
+ char *
+ test (const char *parent, const char *child)
+ {
+ static char rtn_path[1024];
+ char *s = rtn_path;
+ char *s_end = rtn_path + sizeof (rtn_path);
+ const char *s2 = child;
+
+ while (*s != '\0')
+ s++;
+ while ((s < s_end) && (*s2 != '\0'))
+ *s++ = *s2++;
+ return (rtn_path);
+ }