re PR target/82015 (PowerPC should check if 2nd argument to __builtin_unpackv1ti...
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Tue, 29 Aug 2017 20:25:57 +0000 (20:25 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Tue, 29 Aug 2017 20:25:57 +0000 (20:25 +0000)
[gcc]
2017-08-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/82015
* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Insure
that the second argument of the built-in functions to unpack
128-bit scalar types to 64-bit values is 0 or 1.  Change to use a
switch statement instead a lot of if statements.
* config/rs6000/rs6000.md (unpack<mode>, FMOVE128_VSX iterator):
Allow 64-bit values to be in Altivec registers as well as
traditional floating point registers.
(pack<mode>, FMOVE128_VSX iterator): Likewise.

[gcc/testsuite]
2017-08-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/82015
* gcc.target/powerpc/pr82015.c: New test.

From-SVN: r251432

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr82015.c [new file with mode: 0644]

index 35bd379..b7cb4fe 100644 (file)
@@ -1,3 +1,15 @@
+2017-08-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/82015
+       * config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Insure
+       that the second argument of the built-in functions to unpack
+       128-bit scalar types to 64-bit values is 0 or 1.  Change to use a
+       switch statement instead a lot of if statements.
+       * config/rs6000/rs6000.md (unpack<mode>, FMOVE128_VSX iterator):
+       Allow 64-bit values to be in Altivec registers as well as
+       traditional floating point registers.
+       (pack<mode>, FMOVE128_VSX iterator): Likewise.
+
 2017-08-29  Alexander Monakov  <amonakov@ispras.ru>
 
        * ira-costs.c (record_address_regs): Handle both operands of PLUS for
index 9ff73ec..a55c657 100644 (file)
@@ -14001,14 +14001,17 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
   if (arg0 == error_mark_node || arg1 == error_mark_node)
     return const0_rtx;
 
-  if (icode == CODE_FOR_altivec_vcfux
-      || icode == CODE_FOR_altivec_vcfsx
-      || icode == CODE_FOR_altivec_vctsxs
-      || icode == CODE_FOR_altivec_vctuxs
-      || icode == CODE_FOR_altivec_vspltb
-      || icode == CODE_FOR_altivec_vsplth
-      || icode == CODE_FOR_altivec_vspltw)
+  switch (icode)
     {
+    default:
+      break;
+    case CODE_FOR_altivec_vcfux:
+    case CODE_FOR_altivec_vcfsx:
+    case CODE_FOR_altivec_vctsxs:
+    case CODE_FOR_altivec_vctuxs:
+    case CODE_FOR_altivec_vspltb:
+    case CODE_FOR_altivec_vsplth:
+    case CODE_FOR_altivec_vspltw:
       /* Only allow 5-bit unsigned literals.  */
       STRIP_NOPS (arg1);
       if (TREE_CODE (arg1) != INTEGER_CST
@@ -14017,16 +14020,15 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
          error ("argument 2 must be a 5-bit unsigned literal");
          return CONST0_RTX (tmode);
        }
-    }
-  else if (icode == CODE_FOR_dfptstsfi_eq_dd
-      || icode == CODE_FOR_dfptstsfi_lt_dd
-      || icode == CODE_FOR_dfptstsfi_gt_dd
-      || icode == CODE_FOR_dfptstsfi_unordered_dd
-      || icode == CODE_FOR_dfptstsfi_eq_td
-      || icode == CODE_FOR_dfptstsfi_lt_td
-      || icode == CODE_FOR_dfptstsfi_gt_td
-      || icode == CODE_FOR_dfptstsfi_unordered_td)
-    {
+      break;
+    case CODE_FOR_dfptstsfi_eq_dd:
+    case CODE_FOR_dfptstsfi_lt_dd:
+    case CODE_FOR_dfptstsfi_gt_dd:
+    case CODE_FOR_dfptstsfi_unordered_dd:
+    case CODE_FOR_dfptstsfi_eq_td:
+    case CODE_FOR_dfptstsfi_lt_td:
+    case CODE_FOR_dfptstsfi_gt_td:
+    case CODE_FOR_dfptstsfi_unordered_td:
       /* Only allow 6-bit unsigned literals.  */
       STRIP_NOPS (arg0);
       if (TREE_CODE (arg0) != INTEGER_CST
@@ -14035,13 +14037,12 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
          error ("argument 1 must be a 6-bit unsigned literal");
          return CONST0_RTX (tmode);
        }
-    }
-  else if (icode == CODE_FOR_xststdcqp
-          || icode == CODE_FOR_xststdcdp
-          || icode == CODE_FOR_xststdcsp
-          || icode == CODE_FOR_xvtstdcdp
-          || icode == CODE_FOR_xvtstdcsp)
-    {
+      break;
+    case CODE_FOR_xststdcqp:
+    case CODE_FOR_xststdcdp:
+    case CODE_FOR_xststdcsp:
+    case CODE_FOR_xvtstdcdp:
+    case CODE_FOR_xvtstdcsp:
       /* Only allow 7-bit unsigned literals. */
       STRIP_NOPS (arg1);
       if (TREE_CODE (arg1) != INTEGER_CST
@@ -14050,6 +14051,21 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
          error ("argument 2 must be a 7-bit unsigned literal");
          return CONST0_RTX (tmode);
        }
+      break;
+    case CODE_FOR_unpackv1ti:
+    case CODE_FOR_unpackkf:
+    case CODE_FOR_unpacktf:
+    case CODE_FOR_unpackif:
+    case CODE_FOR_unpacktd:
+      /* Only allow 1-bit unsigned literals. */
+      STRIP_NOPS (arg1);
+      if (TREE_CODE (arg1) != INTEGER_CST
+         || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
+       {
+         error ("argument 2 must be a 1-bit unsigned literal");
+         return CONST0_RTX (tmode);
+       }
+      break;
     }
 
   if (target == 0
index 5ad13d7..c0c392c 100644 (file)
    (set_attr "length" "4,8")])
 
 (define_insn "unpack<mode>"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
+  [(set (match_operand:DI 0 "register_operand" "=wa,wa")
        (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
                    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
         UNSPEC_UNPACK_128BIT))]
 (define_insn "pack<mode>"
   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
        (unspec:FMOVE128_VSX
-        [(match_operand:DI 1 "register_operand" "d")
-         (match_operand:DI 2 "register_operand" "d")]
+        [(match_operand:DI 1 "register_operand" "wa")
+         (match_operand:DI 2 "register_operand" "wa")]
         UNSPEC_PACK_128BIT))]
   "TARGET_VSX"
   "xxpermdi %x0,%x1,%x2,0"
index ab80105..ba864c5 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/82015
+       * gcc.target/powerpc/pr82015.c: New test.
+
 2017-08-29  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.target/i386/*.c: Remove excess braces from target selectors.
diff --git a/gcc/testsuite/gcc.target/powerpc/pr82015.c b/gcc/testsuite/gcc.target/powerpc/pr82015.c
new file mode 100644 (file)
index 0000000..b177de4
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mvsx" } */
+
+unsigned long foo_11(vector __int128_t *p)
+{
+  return __builtin_unpack_vector_int128(*p, 11); /* { dg-error "argument 2 must be 0 or 1" } */
+}
+
+unsigned long foo_n(vector __int128_t *p, unsigned long n)
+{
+  return __builtin_unpack_vector_int128(*p, n);        /* { dg-error "argument 2 must be 0 or 1" } */
+}