This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RS6000] Fix PR52107, TFmode constant load.
- From: Alan Modra <amodra at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Edelsohn <dje dot gcc at gmail dot com>
- Date: Sat, 4 Feb 2012 16:16:52 +1030
- Subject: [RS6000] Fix PR52107, TFmode constant load.
http://gcc.gnu.org/ml/gcc-patches/2007-01/msg01835.html changed the
code I'm tweaking here to use DFmode subregs when loading a TFmode
constant into regs for e500. This just extends that change to all
rs6000 targets, the simplest fix I found for PR52107, a problem I
discovered when looking at powerpc64-linux libgcc.
If we leave these constant loads as DImode, here's what happens at
various stages of rtl optimisation:
.expand
(insn 7 6 8 (set (reg:DI 35 3)
(mem/u/c:DI (unspec:DI [
(symbol_ref/u:DI ("*.LC1") [flags 0x2])
(reg:DI 2 2)
] UNSPEC_TOCREL) [5 S8 A8])) /src/tmp/floatconst.c:10 -1
(nil))
.cse1
(insn 7 6 8 2 (set (reg:DI 35 3)
(const_int 4318952042648305664 [0x3bf0000000000000])) /src/tmp/floatconst.c:10 401 {*movdi_internal64}
(nil))
.split1
(insn 21 3 22 2 (set (reg:DI 35 3)
(mem/u/c:DI (unspec:DI [
(symbol_ref/u:DI ("*.LC3") [flags 0x2])
(reg:DI 2 2)
] UNSPEC_TOCREL) [5 S8 A8])) /src/tmp/floatconst.c:10 -1
(expr_list:REG_EQUAL (const_int 1005584384 [0x3bf00000])
(nil)))
(insn 22 21 8 2 (set (reg:DI 35 3)
(ashift:DI (reg:DI 35 3)
(const_int 32 [0x20]))) /src/tmp/floatconst.c:10 -1
(expr_list:REG_EQUAL (const_int 4318952042648305664 [0x3bf0000000000000])
(nil)))
It would also be possible to fix this in the rs6000.md movdi splitter
dealing with large constants, at least for this testcase when we know
we are dealing with a hard float reg. However, I think it's better
not to generate DImode fp values in the first place. Bootstrapped and
regression tested powerpc64-linux. OK to apply everywhere?
Note that the comment I remove is no longer true.
PR target/52107
* config/rs6000/rs6000.c (rs6000_emit_move): Don't create DImode
subregs of TFmode.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 183781)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -7006,17 +7006,14 @@ rs6000_emit_move (rtx dest, rtx source,
if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
&& mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
{
- /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
- know how to get a DFmode SUBREG of a TFmode. */
- enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
- rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
- simplify_gen_subreg (imode, operands[1], mode, 0),
- imode);
- rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
- GET_MODE_SIZE (imode)),
- simplify_gen_subreg (imode, operands[1], mode,
- GET_MODE_SIZE (imode)),
- imode);
+ rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode, 0),
+ simplify_gen_subreg (DFmode, operands[1], mode, 0),
+ DFmode);
+ rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode,
+ GET_MODE_SIZE (DFmode)),
+ simplify_gen_subreg (DFmode, operands[1], mode,
+ GET_MODE_SIZE (DFmode)),
+ DFmode);
return;
}
--
Alan Modra
Australia Development Lab, IBM