Skip to content

Commit 4c3792d

Browse files
committed
LRA, rs6000, Darwin: Amend lo_sum use for forced constants [PR104117].
Two issues resulted in this PR, which manifests when we force a constant into memory in LRA (in PIC code on Darwin). The presence of such forced constants is quite dependent on other RTL optimisations, and it is easy for the issue to become latent for a specific case. First, in the Darwin-specific rs6000 backend code, we were not being careful enough in rejecting invalid symbolic addresses. Specifically, when generating PIC code, we require a SYMBOL_REF to be wrapped in an UNSPEC_MACHOPIC_OFFSET. Second, LRA was attempting to load a register using an invalid lo_sum address. Signed-off-by: Iain Sandoe <[email protected]> Co-authored-by: Vladimir Makarov <[email protected]> PR target/104117 gcc/ChangeLog: * config/rs6000/rs6000.cc (darwin_rs6000_legitimate_lo_sum_const_p): Check for UNSPEC_MACHOPIC_OFFSET wrappers on symbolic addresses when emitting PIC code. (legitimate_lo_sum_address_p): Likewise. * lra-constraints.cc (process_address_1): Do not attempt to emit a reg load from an invalid lo_sum address.
1 parent 13caa02 commit 4c3792d

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

gcc/config/rs6000/rs6000.cc

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8317,8 +8317,14 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
83178317
if (GET_CODE (x) == CONST)
83188318
x = XEXP (x, 0);
83198319

8320+
/* If we are building PIC code, then any symbol must be wrapped in an
8321+
UNSPEC_MACHOPIC_OFFSET so that it will get the picbase subtracted. */
8322+
bool machopic_offs_p = false;
83208323
if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_MACHOPIC_OFFSET)
8321-
x = XVECEXP (x, 0, 0);
8324+
{
8325+
x = XVECEXP (x, 0, 0);
8326+
machopic_offs_p = true;
8327+
}
83228328

83238329
rtx sym = NULL_RTX;
83248330
unsigned HOST_WIDE_INT offset = 0;
@@ -8349,6 +8355,9 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
83498355
if (sym)
83508356
{
83518357
tree decl = SYMBOL_REF_DECL (sym);
8358+
/* As noted above, PIC code cannot use a bare SYMBOL_REF. */
8359+
if (TARGET_MACHO && flag_pic && !machopic_offs_p)
8360+
return false;
83528361
#if TARGET_MACHO
83538362
if (MACHO_SYMBOL_INDIRECTION_P (sym))
83548363
/* The decl in an indirection symbol is the original one, which might
@@ -8936,7 +8945,7 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
89368945
return false;
89378946
x = XEXP (x, 1);
89388947

8939-
if (TARGET_ELF || TARGET_MACHO)
8948+
if (TARGET_ELF)
89408949
{
89418950
bool large_toc_ok;
89428951

@@ -8962,7 +8971,32 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
89628971

89638972
return CONSTANT_P (x) || large_toc_ok;
89648973
}
8974+
else if (TARGET_MACHO)
8975+
{
8976+
if (GET_MODE_NUNITS (mode) != 1)
8977+
return false;
8978+
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
8979+
&& !(/* see above */
8980+
TARGET_HARD_FLOAT && (mode == DFmode || mode == DDmode)))
8981+
return false;
8982+
#if TARGET_MACHO
8983+
if (MACHO_DYNAMIC_NO_PIC_P || !flag_pic)
8984+
return CONSTANT_P (x);
8985+
#endif
8986+
/* Macho-O PIC code from here. */
8987+
if (GET_CODE (x) == CONST)
8988+
x = XEXP (x, 0);
8989+
8990+
/* SYMBOL_REFs need to be wrapped in an UNSPEC_MACHOPIC_OFFSET. */
8991+
if (SYMBOL_REF_P (x))
8992+
return false;
89658993

8994+
/* So this is OK if the wrapped object is const. */
8995+
if (GET_CODE (x) == UNSPEC
8996+
&& XINT (x, 1) == UNSPEC_MACHOPIC_OFFSET)
8997+
return CONSTANT_P (XVECEXP (x, 0, 0));
8998+
return CONSTANT_P (x);
8999+
}
89669000
return false;
89679001
}
89689002

gcc/lra-constraints.cc

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,21 +3625,8 @@ process_address_1 (int nop, bool check_only_p,
36253625
*ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
36263626
if (!valid_address_p (op, &ad, cn))
36273627
{
3628-
/* Try to put lo_sum into register. */
3629-
insn = emit_insn (gen_rtx_SET
3630-
(new_reg,
3631-
gen_rtx_LO_SUM (Pmode, new_reg, addr)));
3632-
code = recog_memoized (insn);
3633-
if (code >= 0)
3634-
{
3635-
*ad.inner = new_reg;
3636-
if (!valid_address_p (op, &ad, cn))
3637-
{
3638-
*ad.inner = addr;
3639-
code = -1;
3640-
}
3641-
}
3642-
3628+
*ad.inner = addr; /* Punt. */
3629+
code = -1;
36433630
}
36443631
}
36453632
if (code < 0)

0 commit comments

Comments
 (0)