rs6000: Replace UNSPECS with ss_plus/us_plus and ss_minus/us_minus
authorXionghu Luo <luoxhu@linux.ibm.com>
Tue, 21 Dec 2021 03:02:50 +0000 (21:02 -0600)
committerXionghu Luo <luoxhu@linux.ibm.com>
Tue, 21 Dec 2021 03:02:50 +0000 (21:02 -0600)
commit460d53f816fe30093653cb22ef0feeb4bddc0895
treea8bd971c4f6179ee7c798cc12ec7011d5317c2b4
parent7631a4d1de0e7105be5de29766454270b9820448
rs6000: Replace UNSPECS with ss_plus/us_plus and ss_minus/us_minus

These four UNSPECS seems could be replaced with native RTL.

For
"(set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))":

Quoted David's explanation:

"The design came from the early implementation of Altivec:

https://gcc.gnu.org/pipermail/gcc-patches/2002-May/077409.html

If one later checks for saturation (reads VSCR), one needs a
corresponding SET of the value.  It's set in an architecture-specific
manner that isn't described to GCC, but it's set, not just clobbered
and in an undefined state.

The RTL does not describe that VSCR is set to the value 0.  The
(const_int 0) is not the value set.  You can think of the (const_int
0) as a dummy RTL argument to the VSCR UNSPEC.  UNSPEC requires at
least one argument and the pattern doesn't try to express the
argument, so it uses a dummy RTL constant.  It's part of a PARALLEL
and the plus or minus already expresses the data dependency of the
pattern on the input operands."

gcc/ChangeLog:

2021-12-21  Xionghu Luo  <luoxhu@linux.ibm.com>

* config/rs6000/altivec.md (altivec_vaddu<VI_char>s): Replace
UNSPEC_VADDU with us_plus.
(altivec_vadds<VI_char>s): Replace UNSPEC_VADDS with ss_plus.
(altivec_vsubu<VI_char>s): Replace UNSPEC_VSUBU with us_minus.
(altivec_vsubs<VI_char>s): Replace UNSPEC_VSUBS with ss_minus.
(altivec_abss_<mode>): Likewise.
gcc/config/rs6000/altivec.md