Now that the documentation for partial modes says they have a known
number of bits of precision, would it make sense for extract_low_bits to
check this before attempting to extract the bits?

This would solve the problem we have been having with POImode and
extract_low_bits -- DSE tries to use it to extract part of a POImode
register used in a previous store. We do not want to supply any patterns
to make POImode (or OImode) used like a regular integer mode.

This patch adds such a check, and sets the precision of POImode to one
bit, which resolves the problems of PR/96791 for ppc64 target.

Bootstrap passes on ppc64le and x86_64.

Thanks,
   Aaron

gcc/ChangeLog:

        * config/rs6000/rs6000-modes.def (POImode): Change precision.
        * expmed.c (extract_low_bits): Check precision.
---
 gcc/config/rs6000/rs6000-modes.def | 2 +-
 gcc/expmed.c                       | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-modes.def 
b/gcc/config/rs6000/rs6000-modes.def
index ddb218b3fba..aa7d60dd835 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -90,5 +90,5 @@ INT_MODE (OI, 32);
 INT_MODE (XI, 64);
 
 /* Modes used by __vector_pair and __vector_quad.  */
-PARTIAL_INT_MODE (OI, 256, POI);       /* __vector_pair.  */
+PARTIAL_INT_MODE (OI, 1, POI); /* __vector_pair.  */
 PARTIAL_INT_MODE (XI, 512, PXI);       /* __vector_quad.  */
diff --git a/gcc/expmed.c b/gcc/expmed.c
index d34f0fb0b54..23ca181afa6 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2396,6 +2396,9 @@ extract_low_bits (machine_mode mode, machine_mode 
src_mode, rtx src)
   if (GET_MODE_CLASS (mode) == MODE_CC || GET_MODE_CLASS (src_mode) == MODE_CC)
     return NULL_RTX;
 
+  if (known_lt (GET_MODE_PRECISION (src_mode), GET_MODE_BITSIZE (mode)))
+    return NULL_RTX;
+
   if (known_eq (GET_MODE_BITSIZE (mode), GET_MODE_BITSIZE (src_mode))
       && targetm.modes_tieable_p (mode, src_mode))
     {
-- 
2.17.1

Reply via email to