The problem is that %g0 is used as destination register of the instruction and 
the CSE passes happily substitute it for the value it's supposed to contain...

Tested on SPARC/Solaris, applied on all active branches.


2016-10-15  Eric Botcazou  <ebotca...@adacore.com>

        * config/sparc/sparc.c (sparc_expand_vec_perm_bmask): Use a scratch
        register as destination of bmask.
        (vector_init_bshuffle): Likewise.
        * config/sparc/sparc.md (vec_perm_constv8qi): Likewise.
        (bmaskdi_vis): Enable only in 64-bit mode.


2016-10-15  Eric Botcazou  <ebotca...@adacore.com>

        * gcc.target/sparc/bmaskbshuf-2.c: New test.

-- 
Eric Botcazou
/* { dg-do run } */
/* { dg-require-effective-target ultrasparc_vis2_hw } */
/* { dg-options "-mcpu=ultrasparc3 -O" } */

typedef unsigned int Vect __attribute__((vector_size(8)));

extern void abort (void);

Vect a, b, c, d;

__attribute__((noinline, noclone)) void test (void)
{
  Vect mask = { 2, 2 };
  int i;

  c = __builtin_shuffle (a, mask);
  d = __builtin_shuffle (a, b, mask);

  __asm__ ("" : : "r" (&c), "r" (&d) : "memory");

  for (i = 0; i < 2; ++i)
    if (c[i] != a[mask[i] & 1])
      abort ();
    else if (mask[i] & 2)
      {
	if (d[i] != b[mask[i] & 1])
	  abort ();
      }
}

int main (void)
{
  int i;
  for (i = 0; i < 2; ++i)
    {
      a[i] = i + 2;
      b[i] = 2 + i + 2;
    }

  test ();
  return 0;
}
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 241180)
+++ config/sparc/sparc.c	(working copy)
@@ -12044,7 +12044,7 @@ sparc_expand_vec_perm_bmask (machine_mod
     }
 
   /* Always perform the final addition/merge within the bmask insn.  */
-  emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, t_1));
+  emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, t_1));
 }
 
 /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
@@ -12310,7 +12310,7 @@ vector_init_bshuffle (rtx target, rtx el
     }
 
   sel = force_reg (SImode, GEN_INT (bmask));
-  emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
+  emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
   emit_insn (final_insn);
 }
 
Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md	(revision 241147)
+++ config/sparc/sparc.md	(working copy)
@@ -8548,7 +8548,7 @@ (define_insn "bmaskdi_vis"
                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
         (plus:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_VIS2"
+  "TARGET_VIS2 && TARGET_ARCH64"
   "bmask\t%r1, %r2, %0"
   [(set_attr "type" "array")
    (set_attr "v3pipe" "true")])
@@ -8593,7 +8593,7 @@ (define_expand "vec_perm_constv8qi"
     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
   sel = force_reg (SImode, gen_int_mode (mask, SImode));
 
-  emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
+  emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
   DONE;
 })

Reply via email to