diff options
author | Aaron Sawdey <acsawdey@linux.ibm.com> | 2020-05-29 16:19:10 -0500 |
---|---|---|
committer | Aaron Sawdey <acsawdey@linux.ibm.com> | 2020-06-02 11:27:46 -0500 |
commit | 85bce484d37fdda9c7eadb9bdcdb1ded891462bb (patch) | |
tree | 5c3fb388953bf3016ad91e4ea9885e38a1dc95f0 | |
parent | 34e5efa10a7b514238ed9a914b802898d2d8cb36 (diff) | |
download | gcc-85bce484d37fdda9c7eadb9bdcdb1ded891462bb.zip gcc-85bce484d37fdda9c7eadb9bdcdb1ded891462bb.tar.gz gcc-85bce484d37fdda9c7eadb9bdcdb1ded891462bb.tar.bz2 |
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.
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 8435bc1..ba9069e 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 |