This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] lower-subreg and IBM long double
- From: Alan Modra <amodra at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 Aug 2013 16:17:42 +0930
- Subject: [PATCH] lower-subreg and IBM long double
- References: <20130611002611 dot GS6878 at bubble dot grove dot modra dot org>
On Tue, Jun 11, 2013 at 09:56:11AM +0930, Alan Modra wrote:
>[snip]
> It isn't hard to see why we are going wrong. IBM long double is
> really a two element array of double, and the rs6000 backend uses
> subregs to access the elements. The problem is that lower-subreg
> lowers to word_mode, so we get DImode. word_mode makes sense for most
> targets where subregs of FP modes might be used to narrow an access
> for bit-twiddling operations on the sign bit. It doesn't make sense
> for us. We want DFmode for FP operations. An example is the expander
> used by the testcase.
This is a repost of http://gcc.gnu.org/ml/gcc/2013-06/msg00053.html,
taking into account Joseph's doc review comments and adding a
testcase. David has already acked the rs6000.c changes. Bootstrapped
and regression tested powerpc64-linux. OK to apply?
gcc/
* rs6000.c (TARGET_INIT_LOWER_SUBREG): Define.
(rs6000_init_lower_subreg): New function.
* lower-subreg.c (init_lower_subreg): Call targetm.init_lower_subreg.
* target.def (init_lower_subreg): New.
* doc/tm.texi.in (TARGET_INIT_LOWER_SUBREG): Document.
* doc/tm.texi: Regenerate.
gcc/testsuite/
* gcc.target/powerpc/fabsl.c: New test.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 201834)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -59,6 +59,7 @@
#include "opts.h"
#include "tree-vectorizer.h"
#include "dumpfile.h"
+#include "lower-subreg.h"
#if TARGET_XCOFF
#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
#endif
@@ -1364,6 +1365,8 @@ static const struct attribute_spec rs6000_attribut
#define TARGET_RTX_COSTS rs6000_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
+#undef TARGET_INIT_LOWER_SUBREG
+#define TARGET_INIT_LOWER_SUBREG rs6000_init_lower_subreg
#undef TARGET_DWARF_REGISTER_SPAN
#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
@@ -27971,6 +27974,20 @@ rs6000_memory_move_cost (enum machine_mode mode, r
return ret;
}
+static void
+rs6000_init_lower_subreg (void *data)
+{
+ if (!TARGET_IEEEQUAD
+ && TARGET_HARD_FLOAT
+ && (TARGET_FPRS || TARGET_E500_DOUBLE)
+ && TARGET_LONG_DOUBLE_128)
+ {
+ struct target_lower_subreg *info = (struct target_lower_subreg *) data;
+ info->x_choices[0].move_modes_to_split[TFmode] = false;
+ info->x_choices[1].move_modes_to_split[TFmode] = false;
+ }
+}
+
/* Returns a code for a target-specific builtin that implements
reciprocal of the function, or NULL_TREE if not available. */
Index: gcc/lower-subreg.c
===================================================================
--- gcc/lower-subreg.c (revision 201834)
+++ gcc/lower-subreg.c (working copy)
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "df.h"
#include "lower-subreg.h"
+#include "target.h"
#ifdef STACK_GROWS_DOWNWARD
# undef STACK_GROWS_DOWNWARD
@@ -287,6 +288,9 @@ init_lower_subreg (void)
if (LOG_COSTS)
fprintf (stderr, "\nSpeed costs\n===========\n\n");
compute_costs (true, &rtxes);
+
+ if (targetm.init_lower_subreg)
+ targetm.init_lower_subreg (this_target_lower_subreg);
}
static bool
Index: gcc/target.def
===================================================================
--- gcc/target.def (revision 201834)
+++ gcc/target.def (working copy)
@@ -5110,6 +5110,14 @@ comparison code or operands.",
void, (int *code, rtx *op0, rtx *op1, bool op0_preserve_value),
default_canonicalize_comparison)
+/* Allow modification of subreg choices. */
+DEFHOOK
+(init_lower_subreg,
+ "This hook allows modification of the choices the lower_subreg pass \
+will make for particular subreg modes. @var{data} is a pointer to a \
+@code{struct target_lower_subreg}.",
+ void, (void *data), NULL)
+
DEFHOOKPOD
(atomic_test_and_set_trueval,
"This value should be set if the result written by\
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in (revision 201834)
+++ gcc/doc/tm.texi.in (working copy)
@@ -4939,6 +4939,8 @@ Define this macro if a non-short-circuit operation
@hook TARGET_ADDRESS_COST
+@hook TARGET_INIT_LOWER_SUBREG
+
@node Scheduling
@section Adjusting the Instruction Scheduler
--
Alan Modra
Australia Development Lab, IBM