[V3] rs6000: Fix [su]mul<mode>3_highpart patterns to use RTL codes [PR122665]

Message ID dea07838-b266-47d4-8a74-54e3f9facfc7@linux.ibm.com
State New
Headers
Series [V3] rs6000: Fix [su]mul<mode>3_highpart patterns to use RTL codes [PR122665] |

Commit Message

jeevitha May 6, 2026, 1:15 p.m. UTC
  Hi All,

The following patch to fix PR122665 has been bootstrapped and regtested
on powerpc64-linux-gnu and powerpc64le-linux-gnu with no regressions.

Changes from V2:
  * Instead of using unspec, changed to proper smul_highpart and
    umul_highpart RTL codes.
Changes from V1:
  * Moved the unspec declarations from vsx.md to rs6000.md, as these
    will be reused in future RFC implementation.

The existing smul<mode>3_highpart and umul<mode>3_highpart patterns
incorrectly defined the high-part multiply by shifting both operands
right by 32 before multiplication. This does not match the semantics
of the instructions vmulhs<wd> and vmulhu<wd>, which perform a widened
multiplication and return the high part of the result.

This patch replaces the incorrect shift-based patterns with the proper
smul_highpart and umul_highpart RTL codes, and updates the operand
predicate from vsx_register_operand to altivec_register_operand, since
these instructions only accept Altivec registers.

2025-05-06  Jeevitha Palanisamy  <jeevitha@linux.ibm.com>

gcc/
	PR target/122665
	* config/rs6000/vsx.md (smul<mode>3_highpart, umul<mode>3_highpart):
	Replace shift-based patterns with smul_highpart and umul_highpart RTL
	codes and use altivec_register_operand.
  

Comments

jeevitha May 11, 2026, 12:24 p.m. UTC | #1
Gentle Ping!

Is it okay for trunk?

Thanks & Regards
Jeevitha


On 06/05/26 6:45 pm, jeevitha wrote:
> Hi All,
> 
> The following patch to fix PR122665 has been bootstrapped and regtested
> on powerpc64-linux-gnu and powerpc64le-linux-gnu with no regressions.
> 
> Changes from V2:
>   * Instead of using unspec, changed to proper smul_highpart and
>     umul_highpart RTL codes.
> Changes from V1:
>   * Moved the unspec declarations from vsx.md to rs6000.md, as these
>     will be reused in future RFC implementation.
> 
> The existing smul<mode>3_highpart and umul<mode>3_highpart patterns
> incorrectly defined the high-part multiply by shifting both operands
> right by 32 before multiplication. This does not match the semantics
> of the instructions vmulhs<wd> and vmulhu<wd>, which perform a widened
> multiplication and return the high part of the result.
> 
> This patch replaces the incorrect shift-based patterns with the proper
> smul_highpart and umul_highpart RTL codes, and updates the operand
> predicate from vsx_register_operand to altivec_register_operand, since
> these instructions only accept Altivec registers.
> 
> 2025-05-06  Jeevitha Palanisamy  <jeevitha@linux.ibm.com>
> 
> gcc/
> 	PR target/122665
> 	* config/rs6000/vsx.md (smul<mode>3_highpart, umul<mode>3_highpart):
> 	Replace shift-based patterns with smul_highpart and umul_highpart RTL
> 	codes and use altivec_register_operand.
> 
> diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
> index cfad9b8c6d5..f5ace28ea93 100644
> --- a/gcc/config/rs6000/vsx.md
> +++ b/gcc/config/rs6000/vsx.md
> @@ -6547,25 +6547,19 @@
>     (set_attr "size" "<bits>")])
>  
>  (define_insn "smul<mode>3_highpart"
> -  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
> -	(mult:VIlong (ashiftrt
> -		       (match_operand:VIlong 1 "vsx_register_operand" "v")
> -		       (const_int 32))
> -		     (ashiftrt
> -		       (match_operand:VIlong 2 "vsx_register_operand" "v")
> -		       (const_int 32))))]
> +  [(set (match_operand:VIlong 0 "altivec_register_operand" "=v")
> +	(smul_highpart:VIlong
> +	  (match_operand:VIlong 1 "altivec_register_operand" "v")
> +	  (match_operand:VIlong 2 "altivec_register_operand" "v")))]
>    "TARGET_POWER10"
>    "vmulhs<wd> %0,%1,%2"
>    [(set_attr "type" "veccomplex")])
>  
>  (define_insn "umul<mode>3_highpart"
> -  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
> -	(us_mult:VIlong (ashiftrt
> -			  (match_operand:VIlong 1 "vsx_register_operand" "v")
> -			  (const_int 32))
> -			(ashiftrt
> -			  (match_operand:VIlong 2 "vsx_register_operand" "v")
> -			  (const_int 32))))]
> +  [(set (match_operand:VIlong 0 "altivec_register_operand" "=v")
> +	(umul_highpart:VIlong
> +	  (match_operand:VIlong 1 "altivec_register_operand" "v")
> +	  (match_operand:VIlong 2 "altivec_register_operand" "v")))]
>    "TARGET_POWER10"
>    "vmulhu<wd> %0,%1,%2"
>    [(set_attr "type" "veccomplex")])
  
Michael Meissner May 11, 2026, 11:57 p.m. UTC | #2
On Mon, May 11, 2026 at 05:54:31PM +0530, jeevitha wrote:
> Gentle Ping!
> 
> Is it okay for trunk?

Yes, it looks fine.

> Thanks & Regards
> Jeevitha
> 
> 
> On 06/05/26 6:45 pm, jeevitha wrote:
> > Hi All,
> > 
> > The following patch to fix PR122665 has been bootstrapped and regtested
> > on powerpc64-linux-gnu and powerpc64le-linux-gnu with no regressions.
> > 
> > Changes from V2:
> >   * Instead of using unspec, changed to proper smul_highpart and
> >     umul_highpart RTL codes.
> > Changes from V1:
> >   * Moved the unspec declarations from vsx.md to rs6000.md, as these
> >     will be reused in future RFC implementation.
> > 
> > The existing smul<mode>3_highpart and umul<mode>3_highpart patterns
> > incorrectly defined the high-part multiply by shifting both operands
> > right by 32 before multiplication. This does not match the semantics
> > of the instructions vmulhs<wd> and vmulhu<wd>, which perform a widened
> > multiplication and return the high part of the result.
> > 
> > This patch replaces the incorrect shift-based patterns with the proper
> > smul_highpart and umul_highpart RTL codes, and updates the operand
> > predicate from vsx_register_operand to altivec_register_operand, since
> > these instructions only accept Altivec registers.
> > 
> > 2025-05-06  Jeevitha Palanisamy  <jeevitha@linux.ibm.com>
> > 
> > gcc/
> > 	PR target/122665
> > 	* config/rs6000/vsx.md (smul<mode>3_highpart, umul<mode>3_highpart):
> > 	Replace shift-based patterns with smul_highpart and umul_highpart RTL
> > 	codes and use altivec_register_operand.
  

Patch

diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index cfad9b8c6d5..f5ace28ea93 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -6547,25 +6547,19 @@ 
    (set_attr "size" "<bits>")])
 
 (define_insn "smul<mode>3_highpart"
-  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
-	(mult:VIlong (ashiftrt
-		       (match_operand:VIlong 1 "vsx_register_operand" "v")
-		       (const_int 32))
-		     (ashiftrt
-		       (match_operand:VIlong 2 "vsx_register_operand" "v")
-		       (const_int 32))))]
+  [(set (match_operand:VIlong 0 "altivec_register_operand" "=v")
+	(smul_highpart:VIlong
+	  (match_operand:VIlong 1 "altivec_register_operand" "v")
+	  (match_operand:VIlong 2 "altivec_register_operand" "v")))]
   "TARGET_POWER10"
   "vmulhs<wd> %0,%1,%2"
   [(set_attr "type" "veccomplex")])
 
 (define_insn "umul<mode>3_highpart"
-  [(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
-	(us_mult:VIlong (ashiftrt
-			  (match_operand:VIlong 1 "vsx_register_operand" "v")
-			  (const_int 32))
-			(ashiftrt
-			  (match_operand:VIlong 2 "vsx_register_operand" "v")
-			  (const_int 32))))]
+  [(set (match_operand:VIlong 0 "altivec_register_operand" "=v")
+	(umul_highpart:VIlong
+	  (match_operand:VIlong 1 "altivec_register_operand" "v")
+	  (match_operand:VIlong 2 "altivec_register_operand" "v")))]
   "TARGET_POWER10"
   "vmulhu<wd> %0,%1,%2"
   [(set_attr "type" "veccomplex")])