On Sun, Oct 09, 2011 at 12:55:40PM +0200, Uros Bizjak wrote:
> BTW: No need to use %c modifier:
> 
> /* Meaning of CODE:
>    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
>    C -- print opcode suffix for set/cmov insn.
>    c -- like C, but print reversed condition
>    ...
> */

Well, something needs to be used there, because otherwise we get
addresses like (%rax, %ymm0, $4) instead of the needed (%rax, %ymm0, 4)

I've used %p6 instead of %c6 in the patch below.

On Mon, Oct 10, 2011 at 01:47:49PM -0700, Richard Henderson wrote:
> The use of match_dup in the clobber is wrong.  We should not be
> clobbering the user-visible copy of the operand.  That does not
> make sense when dealing with the user-visible builtin.

Ok.

> Instead, use (clobber (match_scratch)) and matching constraints with operand 
> 4.

Ok.

> I think that a (mem (scratch)) as input to the unspec is probably best.
> The exact memory usage is almost certainly too complex to describe
> in a useful way.

Ok, so how about this (so far untested, will bootstrap/regtest it soon)?

2011-10-12  Jakub Jelinek  <ja...@redhat.com>

        * config/i386/sse.md (avx2_gathersi<mode>,
        avx2_gatherdi<mode>, avx2_gatherdi<mode>256): Add clobber of
        match_scratch, change memory_operand to register_operand,
        add (mem:BLK (scratch)) use.
        (*avx2_gathersi<mode>, *avx2_gatherdi<mode>,
        *avx2_gatherdi<mode>256): Add clobber of match_scratch,
        add earlyclobber to the output operand and match_scratch,
        add (mem:BLK (scratch)) use, change the other mem to match_operand.
        Use %p6 instead of %c6 in the pattern.
        * config/i386/i386.c (ix86_expand_builtin): Adjust for
        operand 2 being a Pmode register_operand instead of memory_operand.

--- gcc/config/i386/i386.c.jj   2011-10-12 16:15:50.000000000 +0200
+++ gcc/config/i386/i386.c      2011-10-12 19:12:15.000000000 +0200
@@ -28862,7 +28862,6 @@ rdrand_step:
       op4 = expand_normal (arg4);
       /* Note the arg order is different from the operand order.  */
       mode0 = insn_data[icode].operand[1].mode;
-      mode1 = insn_data[icode].operand[2].mode;
       mode2 = insn_data[icode].operand[3].mode;
       mode3 = insn_data[icode].operand[4].mode;
       mode4 = insn_data[icode].operand[5].mode;
@@ -28876,12 +28875,11 @@ rdrand_step:
       if (GET_MODE (op1) != Pmode)
        op1 = convert_to_mode (Pmode, op1, 1);
       op1 = force_reg (Pmode, op1);
-      op1 = gen_rtx_MEM (mode1, op1);
 
       if (!insn_data[icode].operand[1].predicate (op0, mode0))
        op0 = copy_to_mode_reg (mode0, op0);
-      if (!insn_data[icode].operand[2].predicate (op1, mode1))
-       op1 = copy_to_mode_reg (mode1, op1);
+      if (!insn_data[icode].operand[2].predicate (op1, Pmode))
+       op1 = copy_to_mode_reg (Pmode, op1);
       if (!insn_data[icode].operand[3].predicate (op2, mode2))
        op2 = copy_to_mode_reg (mode2, op2);
       if (!insn_data[icode].operand[4].predicate (op3, mode3))
--- gcc/config/i386/sse.md.jj   2011-10-12 16:16:49.000000000 +0200
+++ gcc/config/i386/sse.md      2011-10-12 19:19:55.000000000 +0200
@@ -12582,55 +12582,61 @@ (define_mode_attr VEC_GATHER_MODE
                       (V8SI "V8SI") (V8SF "V8SI")])
 
 (define_expand "avx2_gathersi<mode>"
-  [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "")
-       (unspec:VEC_GATHER_MODE
-         [(match_operand:VEC_GATHER_MODE 1 "register_operand" "")
-          (match_operand:<ssescalarmode> 2 "memory_operand" "")
-          (match_operand:<VEC_GATHER_MODE> 3 "register_operand" "")
-          (match_operand:VEC_GATHER_MODE 4 "register_operand" "")
-          (match_operand:SI 5 "const1248_operand " "")]
-         UNSPEC_GATHER))]
+  [(parallel [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "")
+                  (unspec:VEC_GATHER_MODE
+                    [(match_operand:VEC_GATHER_MODE 1 "register_operand" "")
+                     (match_operand 2 "register_operand" "")
+                     (mem:BLK (scratch))
+                     (match_operand:<VEC_GATHER_MODE> 3 "register_operand" "")
+                     (match_operand:VEC_GATHER_MODE 4 "register_operand" "")
+                     (match_operand:SI 5 "const1248_operand " "")]
+                    UNSPEC_GATHER))
+             (clobber (match_scratch:VEC_GATHER_MODE 6 ""))])]
   "TARGET_AVX2")
 
 (define_insn "*avx2_gathersi<mode>"
-  [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=x")
+  [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=&x")
        (unspec:VEC_GATHER_MODE
-         [(match_operand:VEC_GATHER_MODE 1 "register_operand" "0")
-          (mem:<ssescalarmode>
-            (match_operand:P 2 "register_operand" "r"))
-          (match_operand:<VEC_GATHER_MODE> 3 "register_operand" "x")
-          (match_operand:VEC_GATHER_MODE 4 "register_operand" "x")
-          (match_operand:SI 5 "const1248_operand" "n")]
-         UNSPEC_GATHER))]
+         [(match_operand:VEC_GATHER_MODE 2 "register_operand" "0")
+          (match_operand:P 3 "register_operand" "r")
+          (mem:BLK (scratch))
+          (match_operand:<VEC_GATHER_MODE> 4 "register_operand" "x")
+          (match_operand:VEC_GATHER_MODE 5 "register_operand" "1")
+          (match_operand:SI 6 "const1248_operand" "n")]
+         UNSPEC_GATHER))
+   (clobber (match_scratch:VEC_GATHER_MODE 1 "=&x"))]
   "TARGET_AVX2"
-  "v<gthrfirstp>gatherd<gthrlastp>\t{%4, (%2, %3, %c5), %0|%0, (%2, %3, %c5), 
%4}"
+  "v<gthrfirstp>gatherd<gthrlastp>\t{%1, (%3, %4, %p6), %0|%0, (%3, %4, %p6), 
%1}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
 (define_expand "avx2_gatherdi<mode>"
-  [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "")
-       (unspec:VEC_GATHER_MODE
-         [(match_operand:VEC_GATHER_MODE 1 "register_operand" "")
-          (match_operand:<ssescalarmode> 2 "memory_operand" "")
-          (match_operand:<AVXMODE48P_DI> 3 "register_operand" "")
-          (match_operand:VEC_GATHER_MODE 4 "register_operand" "")
-          (match_operand:SI 5 "const1248_operand " "")]
-         UNSPEC_GATHER))]
+  [(parallel [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "")
+                  (unspec:VEC_GATHER_MODE
+                    [(match_operand:VEC_GATHER_MODE 1 "register_operand" "")
+                     (match_operand 2 "register_operand" "")
+                     (mem:BLK (scratch))
+                     (match_operand:<AVXMODE48P_DI> 3 "register_operand" "")
+                     (match_operand:VEC_GATHER_MODE 4 "register_operand" "")
+                     (match_operand:SI 5 "const1248_operand " "")]
+                    UNSPEC_GATHER))
+             (clobber (match_scratch:VEC_GATHER_MODE 6 ""))])]
   "TARGET_AVX2")
 
 (define_insn "*avx2_gatherdi<mode>"
-  [(set (match_operand:AVXMODE48P_DI 0 "register_operand" "=x")
+  [(set (match_operand:AVXMODE48P_DI 0 "register_operand" "=&x")
        (unspec:AVXMODE48P_DI
-         [(match_operand:AVXMODE48P_DI 1 "register_operand" "0")
-          (mem:<ssescalarmode>
-            (match_operand:P 2 "register_operand" "r"))
-          (match_operand:<AVXMODE48P_DI> 3 "register_operand" "x")
-          (match_operand:AVXMODE48P_DI 4 "register_operand" "x")
-          (match_operand:SI 5 "const1248_operand" "n")]
-         UNSPEC_GATHER))]
+         [(match_operand:AVXMODE48P_DI 2 "register_operand" "0")
+          (match_operand:P 3 "register_operand" "r")
+          (mem:BLK (scratch))
+          (match_operand:<AVXMODE48P_DI> 4 "register_operand" "x")
+          (match_operand:AVXMODE48P_DI 5 "register_operand" "1")
+          (match_operand:SI 6 "const1248_operand" "n")]
+         UNSPEC_GATHER))
+   (clobber (match_scratch:AVXMODE48P_DI 1 "=&x"))]
   "TARGET_AVX2"
-  "v<gthrfirstp>gatherq<gthrlastp>\t{%4, (%2, %3, %c5), %0|%0, (%2, %3, %c5), 
%4}"
+  "v<gthrfirstp>gatherq<gthrlastp>\t{%1, (%3, %4, %p6), %0|%0, (%3, %4, %p6), 
%1}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
@@ -12638,28 +12644,31 @@ (define_insn "*avx2_gatherdi<mode>"
 ;; Special handling for VEX.256 with float arguments
 ;; since there're still xmms as operands
 (define_expand "avx2_gatherdi<mode>256"
-  [(set (match_operand:VI4F_128 0 "register_operand" "")
-       (unspec:VI4F_128
-         [(match_operand:VI4F_128 1 "register_operand" "")
-          (match_operand:<ssescalarmode> 2 "memory_operand" "")
-          (match_operand:V4DI 3 "register_operand" "")
-          (match_operand:VI4F_128 4 "register_operand" "")
-          (match_operand:SI 5 "const1248_operand " "")]
-         UNSPEC_GATHER))]
+  [(parallel [(set (match_operand:VI4F_128 0 "register_operand" "")
+                  (unspec:VI4F_128
+                    [(match_operand:VI4F_128 1 "register_operand" "")
+                     (match_operand 2 "register_operand" "")
+                     (mem:BLK (scratch))
+                     (match_operand:V4DI 3 "register_operand" "")
+                     (match_operand:VI4F_128 4 "register_operand" "")
+                     (match_operand:SI 5 "const1248_operand " "")]
+                    UNSPEC_GATHER))
+             (clobber (match_scratch:VI4F_128 6 ""))])]
   "TARGET_AVX2")
 
 (define_insn "*avx2_gatherdi<mode>256"
   [(set (match_operand:VI4F_128 0 "register_operand" "=x")
        (unspec:VI4F_128
-         [(match_operand:VI4F_128 1 "register_operand" "0")
-          (mem:<ssescalarmode>
-            (match_operand:P 2 "register_operand" "r"))
-          (match_operand:V4DI 3 "register_operand" "x")
-          (match_operand:VI4F_128 4 "register_operand" "x")
-          (match_operand:SI 5 "const1248_operand" "n")]
-         UNSPEC_GATHER))]
+         [(match_operand:VI4F_128 2 "register_operand" "0")
+          (match_operand:P 3 "register_operand" "r")
+          (mem:BLK (scratch))
+          (match_operand:V4DI 4 "register_operand" "x")
+          (match_operand:VI4F_128 5 "register_operand" "1")
+          (match_operand:SI 6 "const1248_operand" "n")]
+         UNSPEC_GATHER)) 
+   (clobber (match_scratch:VI4F_128 1 "=&x"))]
   "TARGET_AVX2"
-  "v<gthrfirstp>gatherq<gthrlastp>\t{%4, (%2, %3, %c5), %0|%0, (%2, %3, %c5), 
%4}"
+  "v<gthrfirstp>gatherq<gthrlastp>\t{%1, (%3, %4, %p6), %0|%0, (%3, %4, %p6), 
%1}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])

        Jakub

Reply via email to