This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] rs6000: Unaligned stfiwx on older CPUs (PR89746)
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dje dot gcc at gmail dot com, Segher Boessenkool <segher at kernel dot crashing dot org>
- Date: Tue, 19 Mar 2019 16:26:18 +0000
- Subject: [PATCH] rs6000: Unaligned stfiwx on older CPUs (PR89746)
The "classic" PowerPCs (6xx/7xx) are not STRICT_ALIGNMENT, but their
floating point units are. This is not normally a problem, the ABIs
make everything FP aligned. The RTL patterns converting FP to integer
however get a potentially unaligned destination, and we do not want to
do an stfiwx on that on such older CPUs.
This fixes it. It does not change anything for TARGET_MFCRF targets
(POWER4 and later). It also won't change anything for strict-alignment
targets, or CPUs without hardware FP of course, or CPUs that do not
implement stfiwx (older 4xx/5xx/8xx).
It does not change the correcponding fixuns* pattern, because that can
not be enabled on any CPU that cannot handle unaligned FP well.
Tested on powerpc64-linux {-m32,-m64}, committing to trunk. Will do
backports later, too.
Segher
2018-03-19 Segher Boessenkool <segher@kernel.crashing.org>
PR target/89746
* config/rs6000/rs6000.md (fix_trunc<mode>si2_stfiwx): If we have a
non-TARGET_MFCRF target, and the dest is memory but not 32-bit aligned,
go via a stack temporary.
---
gcc/config/rs6000/rs6000.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index aedba2c..e8885b6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5668,13 +5668,13 @@ (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
tmp = gen_reg_rtx (DImode);
emit_insn (gen_fctiwz_<mode> (tmp, src));
- if (MEM_P (dest))
+ if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
{
dest = rs6000_force_indexed_or_indirect_mem (dest);
emit_insn (gen_stfiwx (dest, tmp));
DONE;
}
- else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
+ else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
{
dest = gen_lowpart (DImode, dest);
emit_move_insn (dest, tmp);
--
1.8.3.1