Backport PR target/93932 (variable vec_extract) to GCC 9 This patch backports the fix for PR target/93932 from the current master branch to GCC 9. The patch for the master branch had to be adjusted due to using different constraints (GCC 10 uses the enabled attribute to eliminate alternatives, while GCC 9 uses special constraints). I have tested this on a little endian power8 system running Linux. The bootstrap and make check had no regressions.
This patch does fix the following test cases on power8 code: gcc.target/powerpc/fold-vec-extract-double.p8.c gcc.target/powerpc/fold-vec-extract-longlong.p8.c gcc.target/powerpc/fold-vec-extract-longlong.p9.c Can I check this patch into the gcc 9 branch? 2020-04-09 Michael Meissner <meiss...@linux.ibm.com> Back port from trunk 2020-02-26 Michael Meissner <meiss...@linux.ibm.com> PR target/93932 * config/rs6000/vsx.md (vsx_extract_<mode>_var, VSX_D iterator): Split the insn into two parts. This insn only does variable extract from a register. (vsx_extract_<mode>_var_load, VSX_D iterator): New insn, do variable extract from memory. (vsx_extract_v4sf_var): Split the insn into two parts. This insn only does variable extract from a register. (vsx_extract_v4sf_var_load): New insn, do variable extract from memory. (vsx_extract_<mode>_var, VSX_EXTRACT_I iterator): Split the insn into two parts. This insn only does variable extract from a register. (vsx_extract_<mode>_var_load, VSX_EXTRACT_I iterator): New insn, do variable extract from memory. --- /tmp/t3Q8FG_vsx.md 2020-04-09 02:18:54.436474001 -0500 +++ gcc/config/rs6000/vsx.md 2020-04-09 02:03:31.998405325 -0500 @@ -3292,14 +3292,14 @@ (define_insn "vsx_vslo_<mode>" "vslo %0,%1,%2" [(set_attr "type" "vecperm")]) -;; Variable V2DI/V2DF extract +;; Variable V2DI/V2DF extract from a register (define_insn_and_split "vsx_extract_<mode>_var" - [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v,<VSa>,r") - (unspec:<VS_scalar> [(match_operand:VSX_D 1 "input_operand" "v,m,m") - (match_operand:DI 2 "gpc_reg_operand" "r,r,r")] + [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v") + (unspec:<VS_scalar> [(match_operand:VSX_D 1 "gpc_reg_operand" "v") + (match_operand:DI 2 "gpc_reg_operand" "r")] UNSPEC_VSX_EXTRACT)) - (clobber (match_scratch:DI 3 "=r,&b,&b")) - (clobber (match_scratch:V2DI 4 "=&v,X,X"))] + (clobber (match_scratch:DI 3 "=r")) + (clobber (match_scratch:V2DI 4 "=&v"))] "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT" "#" "&& reload_completed" @@ -3310,6 +3310,23 @@ (define_insn_and_split "vsx_extract_<mod DONE; }) +;; Variable V2DI/V2DF extract from memory +(define_insn_and_split "*vsx_extract_<mode>_var_load" + [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=wa,r") + (unspec:<VS_scalar> [(match_operand:VSX_D 1 "memory_operand" "Q,Q") + (match_operand:DI 2 "gpc_reg_operand" "r,r")] + UNSPEC_VSX_EXTRACT)) + (clobber (match_scratch:DI 3 "=&b,&b"))] + "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 4))] +{ + operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], operands[2], + operands[3], <VS_scalar>mode); +} + [(set_attr "type" "fpload,load")]) + ;; Extract a SF element from V4SF (define_insn_and_split "vsx_extract_v4sf" [(set (match_operand:SF 0 "vsx_register_operand" "=ww") @@ -3361,14 +3378,14 @@ (define_insn_and_split "*vsx_extract_v4s [(set_attr "type" "fpload,fpload,fpload,load") (set_attr "length" "8")]) -;; Variable V4SF extract +;; Variable V4SF extract from a register (define_insn_and_split "vsx_extract_v4sf_var" - [(set (match_operand:SF 0 "gpc_reg_operand" "=ww,ww,?r") - (unspec:SF [(match_operand:V4SF 1 "input_operand" "v,m,m") - (match_operand:DI 2 "gpc_reg_operand" "r,r,r")] + [(set (match_operand:SF 0 "gpc_reg_operand" "=wa") + (unspec:SF [(match_operand:V4SF 1 "gpc_reg_operand" "v") + (match_operand:DI 2 "gpc_reg_operand" "r")] UNSPEC_VSX_EXTRACT)) - (clobber (match_scratch:DI 3 "=r,&b,&b")) - (clobber (match_scratch:V2DI 4 "=&v,X,X"))] + (clobber (match_scratch:DI 3 "=r")) + (clobber (match_scratch:V2DI 4 "=&v"))] "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_DIRECT_MOVE_64BIT" "#" "&& reload_completed" @@ -3379,6 +3396,23 @@ (define_insn_and_split "vsx_extract_v4sf DONE; }) +;; Variable V4SF extract from memory +(define_insn_and_split "*vsx_extract_v4sf_var_load" + [(set (match_operand:SF 0 "gpc_reg_operand" "=wa,?r") + (unspec:SF [(match_operand:V4SF 1 "memory_operand" "Q,Q") + (match_operand:DI 2 "gpc_reg_operand" "r,r")] + UNSPEC_VSX_EXTRACT)) + (clobber (match_scratch:DI 3 "=&b,&b"))] + "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_DIRECT_MOVE_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 4))] +{ + operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], operands[2], + operands[3], SFmode); +} + [(set_attr "type" "fpload,load")]) + ;; Expand the builtin form of xxpermdi to canonical rtl. (define_expand "vsx_xxpermdi_<mode>" [(match_operand:VSX_L 0 "vsx_register_operand") @@ -3720,15 +3754,15 @@ (define_insn_and_split "*vsx_extract_<mo [(set_attr "type" "load") (set_attr "length" "8")]) -;; Variable V16QI/V8HI/V4SI extract +;; Variable V16QI/V8HI/V4SI extract from a register (define_insn_and_split "vsx_extract_<mode>_var" - [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r,r,r") + [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r,r") (unspec:<VS_scalar> - [(match_operand:VSX_EXTRACT_I 1 "input_operand" "wK,v,m") - (match_operand:DI 2 "gpc_reg_operand" "r,r,r")] + [(match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "wK,v") + (match_operand:DI 2 "gpc_reg_operand" "r,r")] UNSPEC_VSX_EXTRACT)) - (clobber (match_scratch:DI 3 "=r,r,&b")) - (clobber (match_scratch:V2DI 4 "=X,&v,X"))] + (clobber (match_scratch:DI 3 "=r,r")) + (clobber (match_scratch:V2DI 4 "=X,&v"))] "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT" "#" "&& reload_completed" @@ -3739,6 +3773,24 @@ (define_insn_and_split "vsx_extract_<mod DONE; }) +;; Variable V16QI/V8HI/V4SI extract from memory +(define_insn_and_split "*vsx_extract_<mode>_var_load" + [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r") + (unspec:<VS_scalar> + [(match_operand:VSX_EXTRACT_I 1 "memory_operand" "Q") + (match_operand:DI 2 "gpc_reg_operand" "r")] + UNSPEC_VSX_EXTRACT)) + (clobber (match_scratch:DI 3 "=&b"))] + "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 4))] +{ + operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], operands[2], + operands[3], <VS_scalar>mode); +} + [(set_attr "type" "load")]) + (define_insn_and_split "*vsx_extract_<mode>_<VS_scalar>mode_var" [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r,r,r") (zero_extend:<VS_scalar> -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797