rs6000: Do not allow out of range immediate in vsplt[bhw] (PR86987)
authorSegher Boessenkool <segher@kernel.crashing.org>
Tue, 25 Sep 2018 22:09:38 +0000 (00:09 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Tue, 25 Sep 2018 22:09:38 +0000 (00:09 +0200)
The original AltiVec manuals had the immediate lane number in the
splat instructions as a 5-bit number, but anything too big has no
defined meaning, and gas will choke on it too.  This patch disallows
it in the instruction patterns as well as in the builtins.  This
solves PR86987.

PR target/86987
* config/rs6000/altivec.md (altivec_vspltb): Use
const_0_to_15_operand instead of u5bit_cint_operand.
(*altivec_vspltb_internal): Ditto.
(altivec_vspltb_direct): Ditto.
(altivec_vsplth): Use const_0_to_7_operand instead of
u5bit_cint_operand.
(*altivec_vsplth_internal): Ditto.
(altivec_vsplth_direct): Ditto.
(altivec_vspltw): Use const_0_to_3_operand instead of
u5bit_cint_operand.
(*altivec_vspltw_internal): Ditto.
(altivec_vspltw_direct): Ditto.
(altivec_vspltsf): Ditto.
(*altivec_vspltsf_internal): Ditto.
* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Handle the
various splats with the proper size immediate.  Reorder the various
cases by ascending size of immediate, and put all such together.

From-SVN: r264584

gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/config/rs6000/rs6000.c

index 6be143e9f18545f2036e7ca5825716d22cc56dd9..12e7789991ad1daa984b9e5af4c5d25f7d8beed3 100644 (file)
@@ -1,3 +1,24 @@
+2018-09-25  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/86987
+       * config/rs6000/altivec.md (altivec_vspltb): Use
+       const_0_to_15_operand instead of u5bit_cint_operand.
+       (*altivec_vspltb_internal): Ditto.
+       (altivec_vspltb_direct): Ditto.
+       (altivec_vsplth): Use const_0_to_7_operand instead of
+       u5bit_cint_operand.
+       (*altivec_vsplth_internal): Ditto.
+       (altivec_vsplth_direct): Ditto.
+       (altivec_vspltw): Use const_0_to_3_operand instead of
+       u5bit_cint_operand.
+       (*altivec_vspltw_internal): Ditto.
+       (altivec_vspltw_direct): Ditto.
+       (altivec_vspltsf): Ditto.
+       (*altivec_vspltsf_internal): Ditto.
+       * config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Handle the
+       various splats with the proper size immediate.  Reorder the various
+       cases by ascending size of immediate, and put all such together.
+
 2018-09-25  Richard Biener  <rguenther@suse.de>
 
        PR debug/83941
index 1ddf58026071baabdc58fcfaf719c04481f7563b..345be09ceff59aa177d12bd0624e9d7163e88881 100644 (file)
 (define_expand "altivec_vspltb"
   [(use (match_operand:V16QI 0 "register_operand"))
    (use (match_operand:V16QI 1 "register_operand"))
-   (use (match_operand:QI 2 "u5bit_cint_operand"))]
+   (use (match_operand:QI 2 "const_0_to_15_operand"))]
   "TARGET_ALTIVEC"
 {
   rtvec v = gen_rtvec (1, operands[2]);
         (vec_duplicate:V16QI
         (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
                        (parallel
-                        [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
+                        [(match_operand:QI 2 "const_0_to_15_operand" "")]))))]
   "TARGET_ALTIVEC"
 {
   if (!BYTES_BIG_ENDIAN)
 (define_insn "altivec_vspltb_direct"
   [(set (match_operand:V16QI 0 "register_operand" "=v")
         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
-                      (match_operand:QI 2 "u5bit_cint_operand" "i")]
+                      (match_operand:QI 2 "const_0_to_15_operand" "i")]
                       UNSPEC_VSPLT_DIRECT))]
   "TARGET_ALTIVEC"
   "vspltb %0,%1,%2"
 (define_expand "altivec_vsplth"
   [(use (match_operand:V8HI 0 "register_operand"))
    (use (match_operand:V8HI 1 "register_operand"))
-   (use (match_operand:QI 2 "u5bit_cint_operand"))]
+   (use (match_operand:QI 2 "const_0_to_7_operand"))]
   "TARGET_ALTIVEC"
 {
   rtvec v = gen_rtvec (1, operands[2]);
        (vec_duplicate:V8HI
         (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
                        (parallel
-                        [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
+                        [(match_operand:QI 2 "const_0_to_7_operand" "")]))))]
   "TARGET_ALTIVEC"
 {
   if (!BYTES_BIG_ENDIAN)
 (define_insn "altivec_vsplth_direct"
   [(set (match_operand:V8HI 0 "register_operand" "=v")
         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
-                      (match_operand:QI 2 "u5bit_cint_operand" "i")]
+                      (match_operand:QI 2 "const_0_to_7_operand" "i")]
                      UNSPEC_VSPLT_DIRECT))]
   "TARGET_ALTIVEC"
   "vsplth %0,%1,%2"
 (define_expand "altivec_vspltw"
   [(use (match_operand:V4SI 0 "register_operand"))
    (use (match_operand:V4SI 1 "register_operand"))
-   (use (match_operand:QI 2 "u5bit_cint_operand"))]
+   (use (match_operand:QI 2 "const_0_to_3_operand"))]
   "TARGET_ALTIVEC"
 {
   rtvec v = gen_rtvec (1, operands[2]);
        (vec_duplicate:V4SI
         (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
                        (parallel
-                        [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
+                        [(match_operand:QI 2 "const_0_to_3_operand" "i")]))))]
   "TARGET_ALTIVEC"
 {
   if (!BYTES_BIG_ENDIAN)
 (define_insn "altivec_vspltw_direct"
   [(set (match_operand:V4SI 0 "register_operand" "=v")
         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
-                      (match_operand:QI 2 "u5bit_cint_operand" "i")]
+                      (match_operand:QI 2 "const_0_to_3_operand" "i")]
                      UNSPEC_VSPLT_DIRECT))]
   "TARGET_ALTIVEC"
   "vspltw %0,%1,%2"
 (define_expand "altivec_vspltsf"
   [(use (match_operand:V4SF 0 "register_operand"))
    (use (match_operand:V4SF 1 "register_operand"))
-   (use (match_operand:QI 2 "u5bit_cint_operand"))]
+   (use (match_operand:QI 2 "const_0_to_3_operand"))]
   "TARGET_ALTIVEC"
 {
   rtvec v = gen_rtvec (1, operands[2]);
        (vec_duplicate:V4SF
         (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
                        (parallel
-                        [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
+                        [(match_operand:QI 2 "const_0_to_3_operand" "i")]))))]
   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
 {
   if (!BYTES_BIG_ENDIAN)
index 5c7ab2b24e26e7c15ef2e7c3d92a4437b245f108..baa585191b06da2ee0af24bba8edc8a7617cecd9 100644 (file)
@@ -13456,13 +13456,58 @@ 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
+  if (icode == CODE_FOR_unpackv1ti
+          || icode == CODE_FOR_unpackkf
+          || icode == CODE_FOR_unpacktf
+          || icode == CODE_FOR_unpackif
+          || icode == 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);
+       }
+    }
+  else if (icode == CODE_FOR_altivec_vspltw)
+    {
+      /* Only allow 2-bit unsigned literals.  */
+      STRIP_NOPS (arg1);
+      if (TREE_CODE (arg1) != INTEGER_CST
+         || TREE_INT_CST_LOW (arg1) & ~3)
+       {
+         error ("argument 2 must be a 2-bit unsigned literal");
+         return CONST0_RTX (tmode);
+       }
+    }
+  else if (icode == CODE_FOR_altivec_vsplth)
+    {
+      /* Only allow 3-bit unsigned literals.  */
+      STRIP_NOPS (arg1);
+      if (TREE_CODE (arg1) != INTEGER_CST
+         || TREE_INT_CST_LOW (arg1) & ~7)
+       {
+         error ("argument 2 must be a 3-bit unsigned literal");
+         return CONST0_RTX (tmode);
+       }
+    }
+  else if (icode == CODE_FOR_altivec_vspltb)
+    {
+      /* Only allow 4-bit unsigned literals.  */
+      STRIP_NOPS (arg1);
+      if (TREE_CODE (arg1) != INTEGER_CST
+         || TREE_INT_CST_LOW (arg1) & ~15)
+       {
+         error ("argument 2 must be a 4-bit unsigned literal");
+         return CONST0_RTX (tmode);
+       }
+    }
+  else 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)
+      || icode == CODE_FOR_altivec_vctuxs)
     {
       /* Only allow 5-bit unsigned literals.  */
       STRIP_NOPS (arg1);
@@ -13507,21 +13552,6 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
          return CONST0_RTX (tmode);
        }
     }
-  else if (icode == CODE_FOR_unpackv1ti
-          || icode == CODE_FOR_unpackkf
-          || icode == CODE_FOR_unpacktf
-          || icode == CODE_FOR_unpackif
-          || icode == 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);
-       }
-    }
 
   if (target == 0
       || GET_MODE (target) != tmode