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

Reply via email to