rs6000: Fix some issues related to Power10 fusion [PR104024]

Message ID 009fda27-7119-6de8-8dbe-51126bdfca12@linux.ibm.com
State New
Headers
Series rs6000: Fix some issues related to Power10 fusion [PR104024] |

Commit Message

Kewen.Lin Nov. 30, 2022, 8:30 a.m. UTC
  Hi,

As PR104024 shows, the option -mpower10-fusion isn't guarded by
-mcpu=power10, it causes compiler to fuse for some patterns
even without power10 support and then causes ICE unexpectedly,
this patch is to simply unmask it without power10 support, not
emit any warnings as this option is undocumented.

Besides, for some define_insns in fusion.md which use constraint
v, it requires the condition VECTOR_UNIT_ALTIVEC_OR_VSX_P
(<MODE>mode), otherwise it can cause ICE in reload, see test
case pr104024-2.c.

Bootstrapped and regtested on powerpc64-linux-gnu P8,
powerpc64le-linux-gnu P9 and P10.

Is it ok for trunk?

BR,
Kewen
-----
	PR target/104024

gcc/ChangeLog:

	* config/rs6000/rs6000.cc (rs6000_option_override_internal): Disable
	TARGET_P10_FUSION if !TARGET_POWER10.
	* config/rs6000/fusion.md: Regenerate.
	* config/rs6000/genfusion.pl: Add the check for define_insns
	with constraint v.

gcc/testsuite/ChangeLog:

	* gcc.target/powerpc/pr104024-1.c: New test.
	* gcc.target/powerpc/pr104024-2.c: New test.
---
 gcc/config/rs6000/fusion.md                   | 130 +++++++++---------
 gcc/config/rs6000/genfusion.pl                |  12 +-
 gcc/config/rs6000/rs6000.cc                   |  11 +-
 gcc/testsuite/gcc.target/powerpc/pr104024-1.c |  16 +++
 gcc/testsuite/gcc.target/powerpc/pr104024-2.c |  18 +++
 5 files changed, 113 insertions(+), 74 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr104024-1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr104024-2.c

--
2.27.0
  

Comments

Kewen.Lin Dec. 14, 2022, 11:25 a.m. UTC | #1
Hi,

Gentle ping: https://gcc.gnu.org/pipermail/gcc-patches/2022-November/607526.html

BR,
Kewen

on 2022/11/30 16:30, Kewen.Lin via Gcc-patches wrote:
> Hi,
> 
> As PR104024 shows, the option -mpower10-fusion isn't guarded by
> -mcpu=power10, it causes compiler to fuse for some patterns
> even without power10 support and then causes ICE unexpectedly,
> this patch is to simply unmask it without power10 support, not
> emit any warnings as this option is undocumented.
> 
> Besides, for some define_insns in fusion.md which use constraint
> v, it requires the condition VECTOR_UNIT_ALTIVEC_OR_VSX_P
> (<MODE>mode), otherwise it can cause ICE in reload, see test
> case pr104024-2.c.
> 
> Bootstrapped and regtested on powerpc64-linux-gnu P8,
> powerpc64le-linux-gnu P9 and P10.
> 
> Is it ok for trunk?
> 
> BR,
> Kewen
> -----
> 	PR target/104024
> 
> gcc/ChangeLog:
> 
> 	* config/rs6000/rs6000.cc (rs6000_option_override_internal): Disable
> 	TARGET_P10_FUSION if !TARGET_POWER10.
> 	* config/rs6000/fusion.md: Regenerate.
> 	* config/rs6000/genfusion.pl: Add the check for define_insns
> 	with constraint v.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/powerpc/pr104024-1.c: New test.
> 	* gcc.target/powerpc/pr104024-2.c: New test.
> ---
>  gcc/config/rs6000/fusion.md                   | 130 +++++++++---------
>  gcc/config/rs6000/genfusion.pl                |  12 +-
>  gcc/config/rs6000/rs6000.cc                   |  11 +-
>  gcc/testsuite/gcc.target/powerpc/pr104024-1.c |  16 +++
>  gcc/testsuite/gcc.target/powerpc/pr104024-2.c |  18 +++
>  5 files changed, 113 insertions(+), 74 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/pr104024-1.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/pr104024-2.c
> 
> diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
> index 15f0c16f705..c504f65a045 100644
> --- a/gcc/config/rs6000/fusion.md
> +++ b/gcc/config/rs6000/fusion.md
> @@ -1875,7 +1875,7 @@ (define_insn "*fuse_vand_vand"
>                            (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vand %3,%3,%2
>     vand %3,%1,%0\;vand %3,%3,%2
> @@ -1893,7 +1893,7 @@ (define_insn "*fuse_vandc_vand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vand %3,%3,%2
>     vandc %3,%1,%0\;vand %3,%3,%2
> @@ -1911,7 +1911,7 @@ (define_insn "*fuse_veqv_vand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vand %3,%3,%2
>     veqv %3,%1,%0\;vand %3,%3,%2
> @@ -1929,7 +1929,7 @@ (define_insn "*fuse_vnand_vand"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vand %3,%3,%2
>     vnand %3,%1,%0\;vand %3,%3,%2
> @@ -1947,7 +1947,7 @@ (define_insn "*fuse_vnor_vand"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vand %3,%3,%2
>     vnor %3,%1,%0\;vand %3,%3,%2
> @@ -1965,7 +1965,7 @@ (define_insn "*fuse_vor_vand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vand %3,%3,%2
>     vor %3,%1,%0\;vand %3,%3,%2
> @@ -1983,7 +1983,7 @@ (define_insn "*fuse_vorc_vand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vand %3,%3,%2
>     vorc %3,%1,%0\;vand %3,%3,%2
> @@ -2001,7 +2001,7 @@ (define_insn "*fuse_vxor_vand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vand %3,%3,%2
>     vxor %3,%1,%0\;vand %3,%3,%2
> @@ -2019,7 +2019,7 @@ (define_insn "*fuse_vand_vandc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vandc %3,%3,%2
>     vand %3,%1,%0\;vandc %3,%3,%2
> @@ -2037,7 +2037,7 @@ (define_insn "*fuse_vandc_vandc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vandc %3,%3,%2
>     vandc %3,%1,%0\;vandc %3,%3,%2
> @@ -2055,7 +2055,7 @@ (define_insn "*fuse_veqv_vandc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vandc %3,%3,%2
>     veqv %3,%1,%0\;vandc %3,%3,%2
> @@ -2073,7 +2073,7 @@ (define_insn "*fuse_vnand_vandc"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vandc %3,%3,%2
>     vnand %3,%1,%0\;vandc %3,%3,%2
> @@ -2091,7 +2091,7 @@ (define_insn "*fuse_vnor_vandc"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vandc %3,%3,%2
>     vnor %3,%1,%0\;vandc %3,%3,%2
> @@ -2109,7 +2109,7 @@ (define_insn "*fuse_vor_vandc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vandc %3,%3,%2
>     vor %3,%1,%0\;vandc %3,%3,%2
> @@ -2127,7 +2127,7 @@ (define_insn "*fuse_vorc_vandc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vandc %3,%3,%2
>     vorc %3,%1,%0\;vandc %3,%3,%2
> @@ -2145,7 +2145,7 @@ (define_insn "*fuse_vxor_vandc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vandc %3,%3,%2
>     vxor %3,%1,%0\;vandc %3,%3,%2
> @@ -2163,7 +2163,7 @@ (define_insn "*fuse_vand_veqv"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;veqv %3,%3,%2
>     vand %3,%1,%0\;veqv %3,%3,%2
> @@ -2181,7 +2181,7 @@ (define_insn "*fuse_vandc_veqv"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;veqv %3,%3,%2
>     vandc %3,%1,%0\;veqv %3,%3,%2
> @@ -2199,7 +2199,7 @@ (define_insn "*fuse_veqv_veqv"
>                            (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;veqv %3,%3,%2
>     veqv %3,%1,%0\;veqv %3,%3,%2
> @@ -2217,7 +2217,7 @@ (define_insn "*fuse_vnand_veqv"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;veqv %3,%3,%2
>     vnand %3,%1,%0\;veqv %3,%3,%2
> @@ -2235,7 +2235,7 @@ (define_insn "*fuse_vnor_veqv"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;veqv %3,%3,%2
>     vnor %3,%1,%0\;veqv %3,%3,%2
> @@ -2253,7 +2253,7 @@ (define_insn "*fuse_vor_veqv"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;veqv %3,%3,%2
>     vor %3,%1,%0\;veqv %3,%3,%2
> @@ -2271,7 +2271,7 @@ (define_insn "*fuse_vorc_veqv"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;veqv %3,%3,%2
>     vorc %3,%1,%0\;veqv %3,%3,%2
> @@ -2289,7 +2289,7 @@ (define_insn "*fuse_vxor_veqv"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;veqv %3,%3,%2
>     vxor %3,%1,%0\;veqv %3,%3,%2
> @@ -2307,7 +2307,7 @@ (define_insn "*fuse_vand_vnand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vnand %3,%3,%2
>     vand %3,%1,%0\;vnand %3,%3,%2
> @@ -2325,7 +2325,7 @@ (define_insn "*fuse_vandc_vnand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vnand %3,%3,%2
>     vandc %3,%1,%0\;vnand %3,%3,%2
> @@ -2343,7 +2343,7 @@ (define_insn "*fuse_veqv_vnand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vnand %3,%3,%2
>     veqv %3,%1,%0\;vnand %3,%3,%2
> @@ -2361,7 +2361,7 @@ (define_insn "*fuse_vnand_vnand"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vnand %3,%3,%2
>     vnand %3,%1,%0\;vnand %3,%3,%2
> @@ -2379,7 +2379,7 @@ (define_insn "*fuse_vnor_vnand"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vnand %3,%3,%2
>     vnor %3,%1,%0\;vnand %3,%3,%2
> @@ -2397,7 +2397,7 @@ (define_insn "*fuse_vor_vnand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vnand %3,%3,%2
>     vor %3,%1,%0\;vnand %3,%3,%2
> @@ -2415,7 +2415,7 @@ (define_insn "*fuse_vorc_vnand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vnand %3,%3,%2
>     vorc %3,%1,%0\;vnand %3,%3,%2
> @@ -2433,7 +2433,7 @@ (define_insn "*fuse_vxor_vnand"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vnand %3,%3,%2
>     vxor %3,%1,%0\;vnand %3,%3,%2
> @@ -2451,7 +2451,7 @@ (define_insn "*fuse_vand_vnor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vnor %3,%3,%2
>     vand %3,%1,%0\;vnor %3,%3,%2
> @@ -2469,7 +2469,7 @@ (define_insn "*fuse_vandc_vnor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vnor %3,%3,%2
>     vandc %3,%1,%0\;vnor %3,%3,%2
> @@ -2487,7 +2487,7 @@ (define_insn "*fuse_veqv_vnor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vnor %3,%3,%2
>     veqv %3,%1,%0\;vnor %3,%3,%2
> @@ -2505,7 +2505,7 @@ (define_insn "*fuse_vnand_vnor"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vnor %3,%3,%2
>     vnand %3,%1,%0\;vnor %3,%3,%2
> @@ -2523,7 +2523,7 @@ (define_insn "*fuse_vnor_vnor"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vnor %3,%3,%2
>     vnor %3,%1,%0\;vnor %3,%3,%2
> @@ -2541,7 +2541,7 @@ (define_insn "*fuse_vor_vnor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vnor %3,%3,%2
>     vor %3,%1,%0\;vnor %3,%3,%2
> @@ -2559,7 +2559,7 @@ (define_insn "*fuse_vorc_vnor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vnor %3,%3,%2
>     vorc %3,%1,%0\;vnor %3,%3,%2
> @@ -2577,7 +2577,7 @@ (define_insn "*fuse_vxor_vnor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vnor %3,%3,%2
>     vxor %3,%1,%0\;vnor %3,%3,%2
> @@ -2595,7 +2595,7 @@ (define_insn "*fuse_vand_vor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vor %3,%3,%2
>     vand %3,%1,%0\;vor %3,%3,%2
> @@ -2613,7 +2613,7 @@ (define_insn "*fuse_vandc_vor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vor %3,%3,%2
>     vandc %3,%1,%0\;vor %3,%3,%2
> @@ -2631,7 +2631,7 @@ (define_insn "*fuse_veqv_vor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vor %3,%3,%2
>     veqv %3,%1,%0\;vor %3,%3,%2
> @@ -2649,7 +2649,7 @@ (define_insn "*fuse_vnand_vor"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vor %3,%3,%2
>     vnand %3,%1,%0\;vor %3,%3,%2
> @@ -2667,7 +2667,7 @@ (define_insn "*fuse_vnor_vor"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vor %3,%3,%2
>     vnor %3,%1,%0\;vor %3,%3,%2
> @@ -2685,7 +2685,7 @@ (define_insn "*fuse_vor_vor"
>                            (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vor %3,%3,%2
>     vor %3,%1,%0\;vor %3,%3,%2
> @@ -2703,7 +2703,7 @@ (define_insn "*fuse_vorc_vor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vor %3,%3,%2
>     vorc %3,%1,%0\;vor %3,%3,%2
> @@ -2721,7 +2721,7 @@ (define_insn "*fuse_vxor_vor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vor %3,%3,%2
>     vxor %3,%1,%0\;vor %3,%3,%2
> @@ -2739,7 +2739,7 @@ (define_insn "*fuse_vand_vorc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vorc %3,%3,%2
>     vand %3,%1,%0\;vorc %3,%3,%2
> @@ -2757,7 +2757,7 @@ (define_insn "*fuse_vandc_vorc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vorc %3,%3,%2
>     vandc %3,%1,%0\;vorc %3,%3,%2
> @@ -2775,7 +2775,7 @@ (define_insn "*fuse_veqv_vorc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vorc %3,%3,%2
>     veqv %3,%1,%0\;vorc %3,%3,%2
> @@ -2793,7 +2793,7 @@ (define_insn "*fuse_vnand_vorc"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vorc %3,%3,%2
>     vnand %3,%1,%0\;vorc %3,%3,%2
> @@ -2811,7 +2811,7 @@ (define_insn "*fuse_vnor_vorc"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vorc %3,%3,%2
>     vnor %3,%1,%0\;vorc %3,%3,%2
> @@ -2829,7 +2829,7 @@ (define_insn "*fuse_vor_vorc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vorc %3,%3,%2
>     vor %3,%1,%0\;vorc %3,%3,%2
> @@ -2847,7 +2847,7 @@ (define_insn "*fuse_vorc_vorc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vorc %3,%3,%2
>     vorc %3,%1,%0\;vorc %3,%3,%2
> @@ -2865,7 +2865,7 @@ (define_insn "*fuse_vxor_vorc"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vorc %3,%3,%2
>     vxor %3,%1,%0\;vorc %3,%3,%2
> @@ -2883,7 +2883,7 @@ (define_insn "*fuse_vand_vxor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vand %3,%1,%0\;vxor %3,%3,%2
>     vand %3,%1,%0\;vxor %3,%3,%2
> @@ -2901,7 +2901,7 @@ (define_insn "*fuse_vandc_vxor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vandc %3,%1,%0\;vxor %3,%3,%2
>     vandc %3,%1,%0\;vxor %3,%3,%2
> @@ -2919,7 +2919,7 @@ (define_insn "*fuse_veqv_vxor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     veqv %3,%1,%0\;vxor %3,%3,%2
>     veqv %3,%1,%0\;vxor %3,%3,%2
> @@ -2937,7 +2937,7 @@ (define_insn "*fuse_vnand_vxor"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnand %3,%1,%0\;vxor %3,%3,%2
>     vnand %3,%1,%0\;vxor %3,%3,%2
> @@ -2955,7 +2955,7 @@ (define_insn "*fuse_vnor_vxor"
>                            (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vnor %3,%1,%0\;vxor %3,%3,%2
>     vnor %3,%1,%0\;vxor %3,%3,%2
> @@ -2973,7 +2973,7 @@ (define_insn "*fuse_vor_vxor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vor %3,%1,%0\;vxor %3,%3,%2
>     vor %3,%1,%0\;vxor %3,%3,%2
> @@ -2991,7 +2991,7 @@ (define_insn "*fuse_vorc_vxor"
>                            (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vorc %3,%1,%0\;vxor %3,%3,%2
>     vorc %3,%1,%0\;vxor %3,%3,%2
> @@ -3009,7 +3009,7 @@ (define_insn "*fuse_vxor_vxor"
>                            (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
>                   (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
>    "@
>     vxor %3,%1,%0\;vxor %3,%3,%2
>     vxor %3,%1,%0\;vxor %3,%3,%2
> @@ -3045,7 +3045,7 @@ (define_insn "*fuse_vaddudm_vaddudm"
>                       (match_operand:V2DI 1 "altivec_register_operand" "%v,v,v,v"))
>             (match_operand:V2DI 2 "altivec_register_operand" "v,v,v,v")))
>     (clobber (match_scratch:V2DI 4 "=X,X,X,&v"))]
> -  "(TARGET_P10_FUSION)"
> +  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode) && TARGET_P10_FUSION)"
>    "@
>     vaddudm %3,%1,%0\;vaddudm %3,%3,%2
>     vaddudm %3,%1,%0\;vaddudm %3,%3,%2
> diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
> index 81cc2255f53..6fb9b784655 100755
> --- a/gcc/config/rs6000/genfusion.pl
> +++ b/gcc/config/rs6000/genfusion.pl
> @@ -167,7 +167,7 @@ sub gen_logical_addsubf
>  	$inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
>  	$bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
>  	$ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
> -	$fuse_type);
> +	$fuse_type, $constraint_cond);
>    KIND: foreach $kind ('scalar','vector') {
>        @outer_ops = @logicals;
>        if ( $kind eq 'vector' ) {
> @@ -176,12 +176,14 @@ sub gen_logical_addsubf
>  	  $pred = "altivec_register_operand";
>  	  $constraint = "v";
>  	  $fuse_type = "fused_vector";
> +	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && ";
>        } else {
>  	  $vchr = "";
>  	  $mode = "GPR";
>  	  $pred = "gpc_reg_operand";
>  	  $constraint = "r";
>  	  $fuse_type = "fused_arith_logical";
> +	  $constraint_cond = "";
>  	  push (@outer_ops, @addsub);
>  	  push (@outer_ops, ( "rsubf" ));
>        }
> @@ -263,7 +265,7 @@ sub gen_logical_addsubf
>    [(set (match_operand:${mode} 3 "${pred}" "=&0,&1,&${constraint},${constraint}")
>          ${outer_exp})
>     (clobber (match_scratch:${mode} 4 "=X,X,X,&${constraint}"))]
> -  "(TARGET_P10_FUSION)"
> +  "(${constraint_cond}TARGET_P10_FUSION)"
>    "@
>     ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
>     ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
> @@ -282,7 +284,7 @@ EOF
> 
>  sub gen_addadd
>  {
> -    my ($kind, $vchr, $op, $type, $mode, $pred, $constraint);
> +    my ($kind, $vchr, $op, $type, $mode, $pred, $constraint, $constraint_cond);
>      foreach $kind ('scalar','vector') {
>        if ( $kind eq 'vector' ) {
>  	  $vchr = "v";
> @@ -291,6 +293,7 @@ sub gen_addadd
>  	  $mode = "V2DI";
>  	  $pred = "altivec_register_operand";
>  	  $constraint = "v";
> +	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode) && ";
>        } else {
>  	  $vchr = "";
>  	  $op = "add";
> @@ -298,6 +301,7 @@ sub gen_addadd
>  	  $mode = "GPR";
>  	  $pred = "gpc_reg_operand";
>  	  $constraint = "r";
> +	  $constraint_cond = "";
>        }
>      my $c4 = "${constraint},${constraint},${constraint},${constraint}";
>      print <<"EOF";
> @@ -310,7 +314,7 @@ sub gen_addadd
>                       (match_operand:${mode} 1 "${pred}" "%${c4}"))
>             (match_operand:${mode} 2 "${pred}" "${c4}")))
>     (clobber (match_scratch:${mode} 4 "=X,X,X,&${constraint}"))]
> -  "(TARGET_P10_FUSION)"
> +  "(${constraint_cond}TARGET_P10_FUSION)"
>    "@
>     ${op} %3,%1,%0\\;${op} %3,%3,%2
>     ${op} %3,%1,%0\\;${op} %3,%3,%2
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index eb7ad5e954f..737e7b3e15e 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -4368,11 +4368,6 @@ rs6000_option_override_internal (bool global_init_p)
>    /* Enable -mmma by default on power10 systems.  */
>    if (TARGET_POWER10 && (rs6000_isa_flags_explicit & OPTION_MASK_MMA) == 0)
>      rs6000_isa_flags |= OPTION_MASK_MMA;
> -
> -  if (TARGET_POWER10
> -      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
> -    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
> -
>    /* Turn off vector pair/mma options on non-power10 systems.  */
>    else if (!TARGET_POWER10 && TARGET_MMA)
>      {
> @@ -4382,6 +4377,12 @@ rs6000_option_override_internal (bool global_init_p)
>        rs6000_isa_flags &= ~OPTION_MASK_MMA;
>      }
> 
> +  if (TARGET_POWER10
> +      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
> +    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
> +  else if (!TARGET_POWER10 && TARGET_P10_FUSION)
> +    rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
> +
>    /* MMA requires SIMD support as ISA 3.1 claims and our implementation
>       such as "*movoo" uses vector pair access which use VSX registers.
>       So make MMA require VSX support here.  */
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr104024-1.c b/gcc/testsuite/gcc.target/powerpc/pr104024-1.c
> new file mode 100644
> index 00000000000..19575627342
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/pr104024-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-require-effective-target int128 } */
> +/* { dg-options "-O1 -mdejagnu-cpu=power6 -mpower10-fusion" } */
> +
> +/* Verify there is no ICE.  */
> +
> +int v;
> +
> +__attribute__((noinline, noclone)) void bar(void) { v++; }
> +
> +__attribute__((noinline, noclone)) signed __int128
> +t100_1add(signed __int128 x, signed __int128 y) {
> +  signed __int128 r;
> +  if (__builtin_add_overflow(x, y, &r))
> +    bar();
> +  return r;
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr104024-2.c b/gcc/testsuite/gcc.target/powerpc/pr104024-2.c
> new file mode 100644
> index 00000000000..f16f6465121
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/pr104024-2.c
> @@ -0,0 +1,18 @@
> +/* { dg-require-effective-target int128 } */
> +/* -w disable the warning that '-mno-altivec' disables vsx.  */
> +/* { dg-options "-O1 -mdejagnu-cpu=power10 -mno-altivec -w" } */
> +
> +/* Verify there is no ICE.  */
> +
> +int v;
> +
> +__attribute__((noinline, noclone)) void bar(void) { v++; }
> +
> +__attribute__((noinline, noclone)) signed __int128
> +t100_1add(signed __int128 x, signed __int128 y) {
> +  signed __int128 r;
> +  if (__builtin_add_overflow(x, y, &r))
> +    bar();
> +  return r;
> +}
> +
> --
> 2.27.0
>
  
Segher Boessenkool Dec. 14, 2022, 10:29 p.m. UTC | #2
On Wed, Nov 30, 2022 at 04:30:13PM +0800, Kewen.Lin wrote:
> As PR104024 shows, the option -mpower10-fusion isn't guarded by
> -mcpu=power10, it causes compiler to fuse for some patterns
> even without power10 support and then causes ICE unexpectedly,
> this patch is to simply unmask it without power10 support, not
> emit any warnings as this option is undocumented.

Yes, it mostly exists for debugging purposes (and also for testcase).

> Besides, for some define_insns in fusion.md which use constraint
> v, it requires the condition VECTOR_UNIT_ALTIVEC_OR_VSX_P
> (<MODE>mode), otherwise it can cause ICE in reload, see test
> case pr104024-2.c.

Please don't two separate things in one patch.  It makes bisecting
harder than necessary, and perhaps more interesting to you: it makes
writing good changelog entries and commit messages harder.

> --- a/gcc/config/rs6000/genfusion.pl
> +++ b/gcc/config/rs6000/genfusion.pl
> @@ -167,7 +167,7 @@ sub gen_logical_addsubf
>  	$inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
>  	$bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
>  	$ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
> -	$fuse_type);
> +	$fuse_type, $constraint_cond);
>    KIND: foreach $kind ('scalar','vector') {
>        @outer_ops = @logicals;
>        if ( $kind eq 'vector' ) {
> @@ -176,12 +176,14 @@ sub gen_logical_addsubf
>  	  $pred = "altivec_register_operand";
>  	  $constraint = "v";
>  	  $fuse_type = "fused_vector";
> +	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && ";
>        } else {
>  	  $vchr = "";
>  	  $mode = "GPR";
>  	  $pred = "gpc_reg_operand";
>  	  $constraint = "r";
>  	  $fuse_type = "fused_arith_logical";
> +	  $constraint_cond = "";
>  	  push (@outer_ops, @addsub);
>  	  push (@outer_ops, ( "rsubf" ));
>        }

I don't like this at all.  Please use the "isa" attribute where needed?
Or do you need more in some cases?  But, again, separate patch.

> +  if (TARGET_POWER10
> +      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
> +    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
> +  else if (!TARGET_POWER10 && TARGET_P10_FUSION)
> +    rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;

That's not right.  If you want something like this you should check for
TARGET_POWER10 whenever you check for TARGET_P10_FUSION; but there
really is no reason at all to disable P10 fusion on other CPUs (neither
newer nor older!).

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/pr104024-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-require-effective-target int128 } */
> +/* { dg-options "-O1 -mdejagnu-cpu=power6 -mpower10-fusion" } */

Does this need -O1?  If not, use -O2 please; if so, document it.


Segher
  
Kewen.Lin Dec. 19, 2022, 6:13 a.m. UTC | #3
Hi Segher,

Thanks for the review comments!

on 2022/12/15 06:29, Segher Boessenkool wrote:
> On Wed, Nov 30, 2022 at 04:30:13PM +0800, Kewen.Lin wrote:
>> As PR104024 shows, the option -mpower10-fusion isn't guarded by
>> -mcpu=power10, it causes compiler to fuse for some patterns
>> even without power10 support and then causes ICE unexpectedly,
>> this patch is to simply unmask it without power10 support, not
>> emit any warnings as this option is undocumented.
> 
> Yes, it mostly exists for debugging purposes (and also for testcase).
> 
>> Besides, for some define_insns in fusion.md which use constraint
>> v, it requires the condition VECTOR_UNIT_ALTIVEC_OR_VSX_P
>> (<MODE>mode), otherwise it can cause ICE in reload, see test
>> case pr104024-2.c.
> 
> Please don't two separate things in one patch.  It makes bisecting
> harder than necessary, and perhaps more interesting to you: it makes
> writing good changelog entries and commit messages harder.

OK, will do.

> 
>> --- a/gcc/config/rs6000/genfusion.pl
>> +++ b/gcc/config/rs6000/genfusion.pl
>> @@ -167,7 +167,7 @@ sub gen_logical_addsubf
>>  	$inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
>>  	$bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
>>  	$ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
>> -	$fuse_type);
>> +	$fuse_type, $constraint_cond);
>>    KIND: foreach $kind ('scalar','vector') {
>>        @outer_ops = @logicals;
>>        if ( $kind eq 'vector' ) {
>> @@ -176,12 +176,14 @@ sub gen_logical_addsubf
>>  	  $pred = "altivec_register_operand";
>>  	  $constraint = "v";
>>  	  $fuse_type = "fused_vector";
>> +	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && ";
>>        } else {
>>  	  $vchr = "";
>>  	  $mode = "GPR";
>>  	  $pred = "gpc_reg_operand";
>>  	  $constraint = "r";
>>  	  $fuse_type = "fused_arith_logical";
>> +	  $constraint_cond = "";
>>  	  push (@outer_ops, @addsub);
>>  	  push (@outer_ops, ( "rsubf" ));
>>        }
> 
> I don't like this at all.  Please use the "isa" attribute where needed?
> Or do you need more in some cases?  But, again, separate patch.

This is to add one more condition for those define_insns, for example:

@@ -1875,7 +1875,7 @@ (define_insn "*fuse_vand_vand"
                           (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vand %3,%3,%2
    vand %3,%1,%0\;vand %3,%3,%2

It's to avoid the pseudo whose mode isn't available for register constraint v
causes ICE during reload.  I'm not sure how the "isa" attribute helps here,
could you elaborate it?

> 
>> +  if (TARGET_POWER10
>> +      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
>> +    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
>> +  else if (!TARGET_POWER10 && TARGET_P10_FUSION)
>> +    rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
> 
> That's not right.  If you want something like this you should check for
> TARGET_POWER10 whenever you check for TARGET_P10_FUSION; but there
> really is no reason at all to disable P10 fusion on other CPUs (neither
> newer nor older!).

Good point, and I just noticed that we should check tune setting instead
of TARGET_POWER10 here?  Something like:

if (!(rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION))
  {
    if (processor_target_table[tune_index].processor == PROCESSOR_POWER10)
      rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
    else
      rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
  }

> 
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/pr104024-1.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-require-effective-target int128 } */
>> +/* { dg-options "-O1 -mdejagnu-cpu=power6 -mpower10-fusion" } */
> 
> Does this need -O1?  If not, use -O2 please; if so, document it.
> 

No, it doesn't, will use -O2 instead.

BR,
Kewen
  
Segher Boessenkool Dec. 20, 2022, 1:19 p.m. UTC | #4
Hi!

On Mon, Dec 19, 2022 at 02:13:49PM +0800, Kewen.Lin wrote:
> on 2022/12/15 06:29, Segher Boessenkool wrote:
> > On Wed, Nov 30, 2022 at 04:30:13PM +0800, Kewen.Lin wrote:
> >> --- a/gcc/config/rs6000/genfusion.pl
> >> +++ b/gcc/config/rs6000/genfusion.pl
> >> @@ -167,7 +167,7 @@ sub gen_logical_addsubf
> >>  	$inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
> >>  	$bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
> >>  	$ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
> >> -	$fuse_type);
> >> +	$fuse_type, $constraint_cond);
> >>    KIND: foreach $kind ('scalar','vector') {
> >>        @outer_ops = @logicals;
> >>        if ( $kind eq 'vector' ) {
> >> @@ -176,12 +176,14 @@ sub gen_logical_addsubf
> >>  	  $pred = "altivec_register_operand";
> >>  	  $constraint = "v";
> >>  	  $fuse_type = "fused_vector";
> >> +	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && ";
> >>        } else {
> >>  	  $vchr = "";
> >>  	  $mode = "GPR";
> >>  	  $pred = "gpc_reg_operand";
> >>  	  $constraint = "r";
> >>  	  $fuse_type = "fused_arith_logical";
> >> +	  $constraint_cond = "";
> >>  	  push (@outer_ops, @addsub);
> >>  	  push (@outer_ops, ( "rsubf" ));
> >>        }
> > 
> > I don't like this at all.  Please use the "isa" attribute where needed?
> > Or do you need more in some cases?  But, again, separate patch.
> 
> This is to add one more condition for those define_insns, for example:

Sure, I understand that.  What I don't like is the generator program is
much too big and unstructured already, and this doesn't help at all; it
makes it quite a bit worse even.

> It's to avoid the pseudo whose mode isn't available for register constraint v
> causes ICE during reload.  I'm not sure how the "isa" attribute helps here,
> could you elaborate it?

Yeah, it doesn't help.  The condition implied by the isa attribute is
not added to the insn condition automatically; doing that could be too
expensive, and disruptive as well.  Something for stage 1 :-)

> >> +  if (TARGET_POWER10
> >> +      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
> >> +    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
> >> +  else if (!TARGET_POWER10 && TARGET_P10_FUSION)
> >> +    rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
> > 
> > That's not right.  If you want something like this you should check for
> > TARGET_POWER10 whenever you check for TARGET_P10_FUSION; but there
> > really is no reason at all to disable P10 fusion on other CPUs (neither
> > newer nor older!).
> 
> Good point, and I just noticed that we should check tune setting instead
> of TARGET_POWER10 here?  Something like:
> 
> if (!(rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION))
>   {
>     if (processor_target_table[tune_index].processor == PROCESSOR_POWER10)
>       rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
>     else
>       rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
>   }

Yeah that looks better :-)

Maybe you can restructure the Perl code a bit in a first patch, and then
add the insn condition?  If you're not comfortable with Perl, I'll deal
with it, just update the patch.

Thanks,


Segher
  
Kewen.Lin Dec. 21, 2022, 3:41 a.m. UTC | #5
Hi Segher,

on 2022/12/20 21:19, Segher Boessenkool wrote:
> Hi!
> 
> On Mon, Dec 19, 2022 at 02:13:49PM +0800, Kewen.Lin wrote:
>> on 2022/12/15 06:29, Segher Boessenkool wrote:
>>> On Wed, Nov 30, 2022 at 04:30:13PM +0800, Kewen.Lin wrote:
>>>> --- a/gcc/config/rs6000/genfusion.pl
>>>> +++ b/gcc/config/rs6000/genfusion.pl
>>>> @@ -167,7 +167,7 @@ sub gen_logical_addsubf
>>>>  	$inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
>>>>  	$bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
>>>>  	$ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
>>>> -	$fuse_type);
>>>> +	$fuse_type, $constraint_cond);
>>>>    KIND: foreach $kind ('scalar','vector') {
>>>>        @outer_ops = @logicals;
>>>>        if ( $kind eq 'vector' ) {
>>>> @@ -176,12 +176,14 @@ sub gen_logical_addsubf
>>>>  	  $pred = "altivec_register_operand";
>>>>  	  $constraint = "v";
>>>>  	  $fuse_type = "fused_vector";
>>>> +	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && ";
>>>>        } else {
>>>>  	  $vchr = "";
>>>>  	  $mode = "GPR";
>>>>  	  $pred = "gpc_reg_operand";
>>>>  	  $constraint = "r";
>>>>  	  $fuse_type = "fused_arith_logical";
>>>> +	  $constraint_cond = "";
>>>>  	  push (@outer_ops, @addsub);
>>>>  	  push (@outer_ops, ( "rsubf" ));
>>>>        }
>>>
>>> I don't like this at all.  Please use the "isa" attribute where needed?
>>> Or do you need more in some cases?  But, again, separate patch.
>>
>> This is to add one more condition for those define_insns, for example:
> 
> Sure, I understand that.  What I don't like is the generator program is
> much too big and unstructured already, and this doesn't help at all; it
> makes it quite a bit worse even.

OK.

> 
>> It's to avoid the pseudo whose mode isn't available for register constraint v
>> causes ICE during reload.  I'm not sure how the "isa" attribute helps here,
>> could you elaborate it?
> 
> Yeah, it doesn't help.  The condition implied by the isa attribute is
> not added to the insn condition automatically; doing that could be too
> expensive, and disruptive as well.  Something for stage 1 :-)
> 

OK, thanks for the clarification.  :)

>>>> +  if (TARGET_POWER10
>>>> +      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
>>>> +    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
>>>> +  else if (!TARGET_POWER10 && TARGET_P10_FUSION)
>>>> +    rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
>>>
>>> That's not right.  If you want something like this you should check for
>>> TARGET_POWER10 whenever you check for TARGET_P10_FUSION; but there
>>> really is no reason at all to disable P10 fusion on other CPUs (neither
>>> newer nor older!).
>>
>> Good point, and I just noticed that we should check tune setting instead
>> of TARGET_POWER10 here?  Something like:
>>
>> if (!(rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION))
>>   {
>>     if (processor_target_table[tune_index].processor == PROCESSOR_POWER10)
>>       rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
>>     else
>>       rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
>>   }
> 
> Yeah that looks better :-)
> 

I'm going to test this and commit it first.  :)

> Maybe you can restructure the Perl code a bit in a first patch, and then
> add the insn condition?  If you're not comfortable with Perl, I'll deal
> with it, just update the patch.

OK, I'll give it a try, TBH I just fixed the place for insn condition, didn't
look into this script, with a quick look, I'm going to factor out the main
body from the multiple level loop, do you have some suggestions on which other
candidates to be restructured?

BR,
Kewen
  
Segher Boessenkool Dec. 22, 2022, 6:53 p.m. UTC | #6
On Wed, Dec 21, 2022 at 11:41:58AM +0800, Kewen.Lin wrote:
> on 2022/12/20 21:19, Segher Boessenkool wrote:
> > Sure, I understand that.  What I don't like is the generator program is
> > much too big and unstructured already, and this doesn't help at all; it
> > makes it quite a bit worse even.

> >> Good point, and I just noticed that we should check tune setting instead
> >> of TARGET_POWER10 here?  Something like:
> >>
> >> if (!(rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION))
> >>   {
> >>     if (processor_target_table[tune_index].processor == PROCESSOR_POWER10)
> >>       rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
> >>     else
> >>       rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
> >>   }
> > 
> > Yeah that looks better :-)
> 
> I'm going to test this and commit it first.  :)

Thanks!

> > Maybe you can restructure the Perl code a bit in a first patch, and then
> > add the insn condition?  If you're not comfortable with Perl, I'll deal
> > with it, just update the patch.
> 
> OK, I'll give it a try, TBH I just fixed the place for insn condition, didn't
> look into this script, with a quick look, I'm going to factor out the main
> body from the multiple level loop, do you have some suggestions on which other
> candidates to be restructured?

Anything that makes the code easier to understand, basically.

This stuff is by nature pretty hard to read, but making the code shorter
and/or less nested should make it easier to understand.  You will need
to have fewer local variables per function than there are total now,
that will help.

Btw, this script isn't so big at all, but the patches are hard to review
without converting this to a side-by-side comparison first.  There must
be some way to improve that, that is what I'm looking for :-)


Segher
  

Patch

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index 15f0c16f705..c504f65a045 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -1875,7 +1875,7 @@  (define_insn "*fuse_vand_vand"
                           (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vand %3,%3,%2
    vand %3,%1,%0\;vand %3,%3,%2
@@ -1893,7 +1893,7 @@  (define_insn "*fuse_vandc_vand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vand %3,%3,%2
    vandc %3,%1,%0\;vand %3,%3,%2
@@ -1911,7 +1911,7 @@  (define_insn "*fuse_veqv_vand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vand %3,%3,%2
    veqv %3,%1,%0\;vand %3,%3,%2
@@ -1929,7 +1929,7 @@  (define_insn "*fuse_vnand_vand"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vand %3,%3,%2
    vnand %3,%1,%0\;vand %3,%3,%2
@@ -1947,7 +1947,7 @@  (define_insn "*fuse_vnor_vand"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vand %3,%3,%2
    vnor %3,%1,%0\;vand %3,%3,%2
@@ -1965,7 +1965,7 @@  (define_insn "*fuse_vor_vand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vand %3,%3,%2
    vor %3,%1,%0\;vand %3,%3,%2
@@ -1983,7 +1983,7 @@  (define_insn "*fuse_vorc_vand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vand %3,%3,%2
    vorc %3,%1,%0\;vand %3,%3,%2
@@ -2001,7 +2001,7 @@  (define_insn "*fuse_vxor_vand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vand %3,%3,%2
    vxor %3,%1,%0\;vand %3,%3,%2
@@ -2019,7 +2019,7 @@  (define_insn "*fuse_vand_vandc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vandc %3,%3,%2
    vand %3,%1,%0\;vandc %3,%3,%2
@@ -2037,7 +2037,7 @@  (define_insn "*fuse_vandc_vandc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vandc %3,%3,%2
    vandc %3,%1,%0\;vandc %3,%3,%2
@@ -2055,7 +2055,7 @@  (define_insn "*fuse_veqv_vandc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vandc %3,%3,%2
    veqv %3,%1,%0\;vandc %3,%3,%2
@@ -2073,7 +2073,7 @@  (define_insn "*fuse_vnand_vandc"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vandc %3,%3,%2
    vnand %3,%1,%0\;vandc %3,%3,%2
@@ -2091,7 +2091,7 @@  (define_insn "*fuse_vnor_vandc"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vandc %3,%3,%2
    vnor %3,%1,%0\;vandc %3,%3,%2
@@ -2109,7 +2109,7 @@  (define_insn "*fuse_vor_vandc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vandc %3,%3,%2
    vor %3,%1,%0\;vandc %3,%3,%2
@@ -2127,7 +2127,7 @@  (define_insn "*fuse_vorc_vandc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vandc %3,%3,%2
    vorc %3,%1,%0\;vandc %3,%3,%2
@@ -2145,7 +2145,7 @@  (define_insn "*fuse_vxor_vandc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vandc %3,%3,%2
    vxor %3,%1,%0\;vandc %3,%3,%2
@@ -2163,7 +2163,7 @@  (define_insn "*fuse_vand_veqv"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;veqv %3,%3,%2
    vand %3,%1,%0\;veqv %3,%3,%2
@@ -2181,7 +2181,7 @@  (define_insn "*fuse_vandc_veqv"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;veqv %3,%3,%2
    vandc %3,%1,%0\;veqv %3,%3,%2
@@ -2199,7 +2199,7 @@  (define_insn "*fuse_veqv_veqv"
                           (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;veqv %3,%3,%2
    veqv %3,%1,%0\;veqv %3,%3,%2
@@ -2217,7 +2217,7 @@  (define_insn "*fuse_vnand_veqv"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;veqv %3,%3,%2
    vnand %3,%1,%0\;veqv %3,%3,%2
@@ -2235,7 +2235,7 @@  (define_insn "*fuse_vnor_veqv"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;veqv %3,%3,%2
    vnor %3,%1,%0\;veqv %3,%3,%2
@@ -2253,7 +2253,7 @@  (define_insn "*fuse_vor_veqv"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;veqv %3,%3,%2
    vor %3,%1,%0\;veqv %3,%3,%2
@@ -2271,7 +2271,7 @@  (define_insn "*fuse_vorc_veqv"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;veqv %3,%3,%2
    vorc %3,%1,%0\;veqv %3,%3,%2
@@ -2289,7 +2289,7 @@  (define_insn "*fuse_vxor_veqv"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;veqv %3,%3,%2
    vxor %3,%1,%0\;veqv %3,%3,%2
@@ -2307,7 +2307,7 @@  (define_insn "*fuse_vand_vnand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vnand %3,%3,%2
    vand %3,%1,%0\;vnand %3,%3,%2
@@ -2325,7 +2325,7 @@  (define_insn "*fuse_vandc_vnand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vnand %3,%3,%2
    vandc %3,%1,%0\;vnand %3,%3,%2
@@ -2343,7 +2343,7 @@  (define_insn "*fuse_veqv_vnand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vnand %3,%3,%2
    veqv %3,%1,%0\;vnand %3,%3,%2
@@ -2361,7 +2361,7 @@  (define_insn "*fuse_vnand_vnand"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vnand %3,%3,%2
    vnand %3,%1,%0\;vnand %3,%3,%2
@@ -2379,7 +2379,7 @@  (define_insn "*fuse_vnor_vnand"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vnand %3,%3,%2
    vnor %3,%1,%0\;vnand %3,%3,%2
@@ -2397,7 +2397,7 @@  (define_insn "*fuse_vor_vnand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vnand %3,%3,%2
    vor %3,%1,%0\;vnand %3,%3,%2
@@ -2415,7 +2415,7 @@  (define_insn "*fuse_vorc_vnand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vnand %3,%3,%2
    vorc %3,%1,%0\;vnand %3,%3,%2
@@ -2433,7 +2433,7 @@  (define_insn "*fuse_vxor_vnand"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vnand %3,%3,%2
    vxor %3,%1,%0\;vnand %3,%3,%2
@@ -2451,7 +2451,7 @@  (define_insn "*fuse_vand_vnor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vnor %3,%3,%2
    vand %3,%1,%0\;vnor %3,%3,%2
@@ -2469,7 +2469,7 @@  (define_insn "*fuse_vandc_vnor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vnor %3,%3,%2
    vandc %3,%1,%0\;vnor %3,%3,%2
@@ -2487,7 +2487,7 @@  (define_insn "*fuse_veqv_vnor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vnor %3,%3,%2
    veqv %3,%1,%0\;vnor %3,%3,%2
@@ -2505,7 +2505,7 @@  (define_insn "*fuse_vnand_vnor"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vnor %3,%3,%2
    vnand %3,%1,%0\;vnor %3,%3,%2
@@ -2523,7 +2523,7 @@  (define_insn "*fuse_vnor_vnor"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vnor %3,%3,%2
    vnor %3,%1,%0\;vnor %3,%3,%2
@@ -2541,7 +2541,7 @@  (define_insn "*fuse_vor_vnor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vnor %3,%3,%2
    vor %3,%1,%0\;vnor %3,%3,%2
@@ -2559,7 +2559,7 @@  (define_insn "*fuse_vorc_vnor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vnor %3,%3,%2
    vorc %3,%1,%0\;vnor %3,%3,%2
@@ -2577,7 +2577,7 @@  (define_insn "*fuse_vxor_vnor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vnor %3,%3,%2
    vxor %3,%1,%0\;vnor %3,%3,%2
@@ -2595,7 +2595,7 @@  (define_insn "*fuse_vand_vor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vor %3,%3,%2
    vand %3,%1,%0\;vor %3,%3,%2
@@ -2613,7 +2613,7 @@  (define_insn "*fuse_vandc_vor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vor %3,%3,%2
    vandc %3,%1,%0\;vor %3,%3,%2
@@ -2631,7 +2631,7 @@  (define_insn "*fuse_veqv_vor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vor %3,%3,%2
    veqv %3,%1,%0\;vor %3,%3,%2
@@ -2649,7 +2649,7 @@  (define_insn "*fuse_vnand_vor"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vor %3,%3,%2
    vnand %3,%1,%0\;vor %3,%3,%2
@@ -2667,7 +2667,7 @@  (define_insn "*fuse_vnor_vor"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vor %3,%3,%2
    vnor %3,%1,%0\;vor %3,%3,%2
@@ -2685,7 +2685,7 @@  (define_insn "*fuse_vor_vor"
                           (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vor %3,%3,%2
    vor %3,%1,%0\;vor %3,%3,%2
@@ -2703,7 +2703,7 @@  (define_insn "*fuse_vorc_vor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vor %3,%3,%2
    vorc %3,%1,%0\;vor %3,%3,%2
@@ -2721,7 +2721,7 @@  (define_insn "*fuse_vxor_vor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vor %3,%3,%2
    vxor %3,%1,%0\;vor %3,%3,%2
@@ -2739,7 +2739,7 @@  (define_insn "*fuse_vand_vorc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vorc %3,%3,%2
    vand %3,%1,%0\;vorc %3,%3,%2
@@ -2757,7 +2757,7 @@  (define_insn "*fuse_vandc_vorc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vorc %3,%3,%2
    vandc %3,%1,%0\;vorc %3,%3,%2
@@ -2775,7 +2775,7 @@  (define_insn "*fuse_veqv_vorc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vorc %3,%3,%2
    veqv %3,%1,%0\;vorc %3,%3,%2
@@ -2793,7 +2793,7 @@  (define_insn "*fuse_vnand_vorc"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vorc %3,%3,%2
    vnand %3,%1,%0\;vorc %3,%3,%2
@@ -2811,7 +2811,7 @@  (define_insn "*fuse_vnor_vorc"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vorc %3,%3,%2
    vnor %3,%1,%0\;vorc %3,%3,%2
@@ -2829,7 +2829,7 @@  (define_insn "*fuse_vor_vorc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vorc %3,%3,%2
    vor %3,%1,%0\;vorc %3,%3,%2
@@ -2847,7 +2847,7 @@  (define_insn "*fuse_vorc_vorc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vorc %3,%3,%2
    vorc %3,%1,%0\;vorc %3,%3,%2
@@ -2865,7 +2865,7 @@  (define_insn "*fuse_vxor_vorc"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vorc %3,%3,%2
    vxor %3,%1,%0\;vorc %3,%3,%2
@@ -2883,7 +2883,7 @@  (define_insn "*fuse_vand_vxor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vxor %3,%3,%2
    vand %3,%1,%0\;vxor %3,%3,%2
@@ -2901,7 +2901,7 @@  (define_insn "*fuse_vandc_vxor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vxor %3,%3,%2
    vandc %3,%1,%0\;vxor %3,%3,%2
@@ -2919,7 +2919,7 @@  (define_insn "*fuse_veqv_vxor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vxor %3,%3,%2
    veqv %3,%1,%0\;vxor %3,%3,%2
@@ -2937,7 +2937,7 @@  (define_insn "*fuse_vnand_vxor"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vxor %3,%3,%2
    vnand %3,%1,%0\;vxor %3,%3,%2
@@ -2955,7 +2955,7 @@  (define_insn "*fuse_vnor_vxor"
                           (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vxor %3,%3,%2
    vnor %3,%1,%0\;vxor %3,%3,%2
@@ -2973,7 +2973,7 @@  (define_insn "*fuse_vor_vxor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vxor %3,%3,%2
    vor %3,%1,%0\;vxor %3,%3,%2
@@ -2991,7 +2991,7 @@  (define_insn "*fuse_vorc_vxor"
                           (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vxor %3,%3,%2
    vorc %3,%1,%0\;vxor %3,%3,%2
@@ -3009,7 +3009,7 @@  (define_insn "*fuse_vxor_vxor"
                           (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v"))
                  (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vxor %3,%3,%2
    vxor %3,%1,%0\;vxor %3,%3,%2
@@ -3045,7 +3045,7 @@  (define_insn "*fuse_vaddudm_vaddudm"
                      (match_operand:V2DI 1 "altivec_register_operand" "%v,v,v,v"))
            (match_operand:V2DI 2 "altivec_register_operand" "v,v,v,v")))
    (clobber (match_scratch:V2DI 4 "=X,X,X,&v"))]
-  "(TARGET_P10_FUSION)"
+  "(VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode) && TARGET_P10_FUSION)"
   "@
    vaddudm %3,%1,%0\;vaddudm %3,%3,%2
    vaddudm %3,%1,%0\;vaddudm %3,%3,%2
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 81cc2255f53..6fb9b784655 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -167,7 +167,7 @@  sub gen_logical_addsubf
 	$inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
 	$bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
 	$ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
-	$fuse_type);
+	$fuse_type, $constraint_cond);
   KIND: foreach $kind ('scalar','vector') {
       @outer_ops = @logicals;
       if ( $kind eq 'vector' ) {
@@ -176,12 +176,14 @@  sub gen_logical_addsubf
 	  $pred = "altivec_register_operand";
 	  $constraint = "v";
 	  $fuse_type = "fused_vector";
+	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && ";
       } else {
 	  $vchr = "";
 	  $mode = "GPR";
 	  $pred = "gpc_reg_operand";
 	  $constraint = "r";
 	  $fuse_type = "fused_arith_logical";
+	  $constraint_cond = "";
 	  push (@outer_ops, @addsub);
 	  push (@outer_ops, ( "rsubf" ));
       }
@@ -263,7 +265,7 @@  sub gen_logical_addsubf
   [(set (match_operand:${mode} 3 "${pred}" "=&0,&1,&${constraint},${constraint}")
         ${outer_exp})
    (clobber (match_scratch:${mode} 4 "=X,X,X,&${constraint}"))]
-  "(TARGET_P10_FUSION)"
+  "(${constraint_cond}TARGET_P10_FUSION)"
   "@
    ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
    ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
@@ -282,7 +284,7 @@  EOF

 sub gen_addadd
 {
-    my ($kind, $vchr, $op, $type, $mode, $pred, $constraint);
+    my ($kind, $vchr, $op, $type, $mode, $pred, $constraint, $constraint_cond);
     foreach $kind ('scalar','vector') {
       if ( $kind eq 'vector' ) {
 	  $vchr = "v";
@@ -291,6 +293,7 @@  sub gen_addadd
 	  $mode = "V2DI";
 	  $pred = "altivec_register_operand";
 	  $constraint = "v";
+	  $constraint_cond = "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode) && ";
       } else {
 	  $vchr = "";
 	  $op = "add";
@@ -298,6 +301,7 @@  sub gen_addadd
 	  $mode = "GPR";
 	  $pred = "gpc_reg_operand";
 	  $constraint = "r";
+	  $constraint_cond = "";
       }
     my $c4 = "${constraint},${constraint},${constraint},${constraint}";
     print <<"EOF";
@@ -310,7 +314,7 @@  sub gen_addadd
                      (match_operand:${mode} 1 "${pred}" "%${c4}"))
            (match_operand:${mode} 2 "${pred}" "${c4}")))
    (clobber (match_scratch:${mode} 4 "=X,X,X,&${constraint}"))]
-  "(TARGET_P10_FUSION)"
+  "(${constraint_cond}TARGET_P10_FUSION)"
   "@
    ${op} %3,%1,%0\\;${op} %3,%3,%2
    ${op} %3,%1,%0\\;${op} %3,%3,%2
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index eb7ad5e954f..737e7b3e15e 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4368,11 +4368,6 @@  rs6000_option_override_internal (bool global_init_p)
   /* Enable -mmma by default on power10 systems.  */
   if (TARGET_POWER10 && (rs6000_isa_flags_explicit & OPTION_MASK_MMA) == 0)
     rs6000_isa_flags |= OPTION_MASK_MMA;
-
-  if (TARGET_POWER10
-      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
-    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
-
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -4382,6 +4377,12 @@  rs6000_option_override_internal (bool global_init_p)
       rs6000_isa_flags &= ~OPTION_MASK_MMA;
     }

+  if (TARGET_POWER10
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_FUSION;
+  else if (!TARGET_POWER10 && TARGET_P10_FUSION)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_FUSION;
+
   /* MMA requires SIMD support as ISA 3.1 claims and our implementation
      such as "*movoo" uses vector pair access which use VSX registers.
      So make MMA require VSX support here.  */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104024-1.c b/gcc/testsuite/gcc.target/powerpc/pr104024-1.c
new file mode 100644
index 00000000000..19575627342
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104024-1.c
@@ -0,0 +1,16 @@ 
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O1 -mdejagnu-cpu=power6 -mpower10-fusion" } */
+
+/* Verify there is no ICE.  */
+
+int v;
+
+__attribute__((noinline, noclone)) void bar(void) { v++; }
+
+__attribute__((noinline, noclone)) signed __int128
+t100_1add(signed __int128 x, signed __int128 y) {
+  signed __int128 r;
+  if (__builtin_add_overflow(x, y, &r))
+    bar();
+  return r;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104024-2.c b/gcc/testsuite/gcc.target/powerpc/pr104024-2.c
new file mode 100644
index 00000000000..f16f6465121
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104024-2.c
@@ -0,0 +1,18 @@ 
+/* { dg-require-effective-target int128 } */
+/* -w disable the warning that '-mno-altivec' disables vsx.  */
+/* { dg-options "-O1 -mdejagnu-cpu=power10 -mno-altivec -w" } */
+
+/* Verify there is no ICE.  */
+
+int v;
+
+__attribute__((noinline, noclone)) void bar(void) { v++; }
+
+__attribute__((noinline, noclone)) signed __int128
+t100_1add(signed __int128 x, signed __int128 y) {
+  signed __int128 r;
+  if (__builtin_add_overflow(x, y, &r))
+    bar();
+  return r;
+}
+