Message ID | 56efdbfb9f698d499feb87587d98c7cb47185d1b.1421482716.git.segher@kernel.crashing.org |
---|---|
State | New |
Headers | show |
On Sat, Jan 17, 2015 at 3:48 AM, Segher Boessenkool <segher@kernel.crashing.org> wrote: > This fixes 29 FAILs. > > The ld, lwa etc. insns do not encode the low two bits of the offset in > the opcode; those have to be zero. For -m64 this seemed to never matter, > datums are always aligned; but for -m32 -mpowerpc64 you can get symbols > that are not sufficiently aligned. So check for that. > > [ Hrm, I think this triggers for lwz as well? I'll investigate. ] > > > 2015-01-16 Segher Boessenkool <segher@kernel.crashing.org> > > gcc/ > * config/rs6000/rs6000.c (lo_sum_symbol_misaligned_p): New function. > (legitimate_lo_sum_address_p): Use it for TARGET_POWERPC64. Okay. Thanks, David
On Sat, Jan 17, 2015 at 09:30:07AM -0500, David Edelsohn wrote: > On Sat, Jan 17, 2015 at 3:48 AM, Segher Boessenkool > <segher@kernel.crashing.org> wrote: > > This fixes 29 FAILs. > > > > The ld, lwa etc. insns do not encode the low two bits of the offset in > > the opcode; those have to be zero. For -m64 this seemed to never matter, > > datums are always aligned; but for -m32 -mpowerpc64 you can get symbols > > that are not sufficiently aligned. So check for that. > > > > [ Hrm, I think this triggers for lwz as well? I'll investigate. ] > > > > > > 2015-01-16 Segher Boessenkool <segher@kernel.crashing.org> > > > > gcc/ > > * config/rs6000/rs6000.c (lo_sum_symbol_misaligned_p): New function. > > (legitimate_lo_sum_address_p): Use it for TARGET_POWERPC64. > > Okay. I'll hold off on this one until it's clear what it does for lwz, and -m64 performance too. It should do absolutely nothing for aligned accesses, so it cannot be all that bad, but I don't want to regress even a tiny little bit so late in the game. -m32 -mpowerpc64 hasn't worked properly for years, this series does not fix everything yet (it doesn't do anything specific to Darwin, too), and this patch fixes a relatively minor issue (not affecting too many programs). Segher
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 551181b..53bee13 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -6735,6 +6735,39 @@ macho_lo_sum_memory_operand (rtx x, machine_mode mode) return CONSTANT_P (x); } +/* Return true if X (which is the second operand of a LO_SUM) is a symbol + that is not sufficiently aligned for a DS-form instruction. */ +static bool +lo_sum_symbol_misaligned_p (rtx x) +{ + if (GET_CODE (x) == CONST) + x = XEXP (x, 0); + + if (GET_CODE (x) == PLUS) + x = XEXP (x, 0); + + if (GET_CODE (x) != SYMBOL_REF) + return false; + + tree decl = SYMBOL_REF_DECL (x); + if (decl) + return DECL_ALIGN_UNIT (decl) < 4; + + if (SYMBOL_REF_HAS_BLOCK_INFO_P (x) + && SYMBOL_REF_ANCHOR_P (x)) + { + struct object_block *block = SYMBOL_REF_BLOCK (x); + if (block) + return block->alignment < 32; + } + + if (CONSTANT_POOL_ADDRESS_P (x)) + return GET_MODE_ALIGNMENT (get_pool_mode (x)) < 32; + + /* Assume it's okay otherwise. */ + return false; +} + static bool legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict) { @@ -6774,6 +6807,10 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict) TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (mode == DFmode || mode == DDmode))) return false; + if (TARGET_POWERPC64 + && GET_MODE_SIZE (mode) >= 4 + && lo_sum_symbol_misaligned_p (x)) + return false; return CONSTANT_P (x) || large_toc_ok; }