Hi All,
The following patch has been bootstrapped and regtested on powerpc64le-linux. The existing smul<mode>3_highpart and umul<mode>3_highpart patterns incorrectly defined the high-part multiply by shifting both operands before multiplication. This does not match the semantics of the instructions vmulhs<wd> and vmulhu<wd>, which perform a widened multiplication and then return the high part. This patch replaces the incorrect patterns with UNSPEC_VMULHS and UNSPEC_VMULHU forms, and updates the predicate to use altivec_register_operand, since these instructions accept only Altivec registers. 2025-11-19 Jeevitha Palanisamy <[email protected]> gcc/ PR target/122665 * config/rs6000/vsx.md (UNSPEC_VMULHS, UNSPEC_VMULHU): New. (smul<mode>3_highpart): Use UNSPEC_VMULHS. (umul<mode>3_highpart): Use UNSPEC_VMULHU. diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index dd3573b8086..e66462f1c4b 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -362,6 +362,8 @@ UNSPEC_REPLACE_UN UNSPEC_VDIVES UNSPEC_VDIVEU + UNSPEC_VMULHS + UNSPEC_VMULHU UNSPEC_VMSUMCUD UNSPEC_XXEVAL UNSPEC_XXSPLTIW @@ -6546,25 +6548,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") + (unspec:VIlong [(match_operand:VIlong 1 "altivec_register_operand" "v") + (match_operand:VIlong 2 "altivec_register_operand" "v")] + UNSPEC_VMULHS))] "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") + (unspec:VIlong [(match_operand:VIlong 1 "altivec_register_operand" "v") + (match_operand:VIlong 2 "altivec_register_operand" "v")] + UNSPEC_VMULHU))] "TARGET_POWER10" "vmulhu<wd> %0,%1,%2" [(set_attr "type" "veccomplex")])
