[gcc(refs/users/aoliva/heads/testme)] Correctly identify stfs if prefixed
Alexandre Oliva
aoliva@gcc.gnu.org
Thu Jun 4 07:36:16 GMT 2020
https://gcc.gnu.org/g:85bce484d37fdda9c7eadb9bdcdb1ded891462bb
commit 85bce484d37fdda9c7eadb9bdcdb1ded891462bb
Author: Aaron Sawdey <acsawdey@linux.ibm.com>
Date: Fri May 29 16:19:10 2020 -0500
Correctly identify stfs if prefixed
Because reg_to_non_prefixed() only looks at the register being used, it
doesn't get the right answer for stfs, which leads to us not seeing
that it has a PCREL symbol ref. This patch works around this by
introducing a helper function that inspects the insn to see if it is in
fact a stfs. Then if we use NON_PREFIXED_DEFAULT, address_to_insn_form()
can see that it has the PCREL symbol ref.
gcc/ChangeLog:
PR target/95347
* config/rs6000/rs6000.c (prefixed_store_p): Add special case
for stfs.
(is_stfs_insn): New helper function.
Diff:
---
gcc/config/rs6000/rs6000.c | 55 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8435bc15d72..ba9069ecc3b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -24980,6 +24980,51 @@ address_to_insn_form (rtx addr,
return INSN_FORM_BAD;
}
+/* Helper function to see if we're potentially looking at stfs.
+ - PARALLEL containing a SET and a CLOBBER
+ - SET is from UNSPEC_SI_FROM_SF to MEM:SI
+ - CLOBBER is a V4SF
+ */
+
+static bool
+is_stfs_insn (rtx_insn *insn)
+{
+ rtx pattern = PATTERN (insn);
+ if (GET_CODE (pattern) != PARALLEL)
+ return false;
+
+ /* This should be a parallel with exactly one set and one clobber. */
+ if (XVECLEN (pattern, 0) != 2)
+ return false;
+
+ rtx set = XVECEXP (pattern, 0, 0);
+ if (GET_CODE (set) != SET)
+ return false;
+
+ rtx clobber = XVECEXP (pattern, 0, 1);
+ if (GET_CODE (clobber) != CLOBBER)
+ return false;
+
+ /* All we care is that the destination of the SET is a mem:SI,
+ the source should be an UNSPEC_SI_FROM_SF, and the clobber
+ should be a scratch:V4SF. */
+
+ rtx dest = SET_DEST (set);
+ rtx src = SET_SRC (set);
+ rtx scratch = SET_DEST (clobber);
+
+ if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_SI_FROM_SF)
+ return false;
+
+ if (GET_CODE (dest) != MEM || GET_MODE (dest) != SImode)
+ return false;
+
+ if (GET_CODE (scratch) != SCRATCH || GET_MODE (scratch) != V4SFmode)
+ return false;
+
+ return true;
+}
+
/* Helper function to take a REG and a MODE and turn it into the non-prefixed
instruction format (D/DS/DQ) used for offset memory. */
@@ -25119,8 +25164,16 @@ prefixed_store_p (rtx_insn *insn)
return false;
machine_mode mem_mode = GET_MODE (mem);
+ rtx addr = XEXP (mem, 0);
enum non_prefixed_form non_prefixed = reg_to_non_prefixed (reg, mem_mode);
- return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed);
+
+ /* Need to make sure we aren't looking at a stfs which doesn't look
+ like the other things reg_to_non_prefixed/address_is_prefixed
+ looks for. */
+ if (non_prefixed == NON_PREFIXED_X && is_stfs_insn (insn))
+ return address_is_prefixed (addr, mem_mode, NON_PREFIXED_DEFAULT);
+ else
+ return address_is_prefixed (addr, mem_mode, non_prefixed);
}
/* Whether a load immediate or add instruction is a prefixed instruction. This
More information about the Gcc-cvs
mailing list