]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/77822: S390: Validate argument range of {zero,sign}_extract.
authorDominik Vogt <vogt@linux.vnet.ibm.com>
Fri, 2 Dec 2016 08:30:16 +0000 (08:30 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Fri, 2 Dec 2016 08:30:16 +0000 (08:30 +0000)
With some undefined code, combine generates patterns where the arguments to
*_extract are out of range, e.b. a negative bit position.  If the s390 backend
accepts these, they lead to not just undefined behaviour but invalid assembly
instructions (argument out of the allowed range).  So this patch makes sure
that the rtl expressions with out of range arguments are rejected.

gcc/ChangeLog:

2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>

PR target/77822
* config/s390/s390.md ("extzv")
("*extzv<mode><clobbercc_or_nocc>")
("*extzvdi<clobbercc_or_nocc>_lshiftrt")
("*<risbg_n>_ior_and_sr_ze")
("*extract1bitdi<clobbercc_or_nocc>")
("*insv<mode><clobbercc_or_nocc>", "*insv_rnsbg_noshift")
("*insv_rnsbg_srl", "*insv<mode>_mem_reg")
("*insvdi_mem_reghigh", "*insvdi_reg_imm"): Use EXTRACT_ARGS_IN_RANGE
to validate the arguments of zero_extract and sign_extract.

gcc/testsuite/ChangeLog:

2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>

PR target/77822
* gcc.target/s390/s390.exp: Support .C tests.
* gcc.target/s390/pr77822-2.c: New test.
* gcc.target/s390/pr77822-1.C: New test.

From-SVN: r243160

gcc/ChangeLog
gcc/config/s390/s390.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/pr77822-1.C [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/pr77822-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/s390.exp

index 8c71c21d1eb8808bacea62105d07d321c6e73eab..e357932cc188aed2abe7168c00f53055e58200b6 100644 (file)
@@ -1,3 +1,16 @@
+2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
+       PR target/77822
+       * config/s390/s390.md ("extzv")
+       ("*extzv<mode><clobbercc_or_nocc>")
+       ("*extzvdi<clobbercc_or_nocc>_lshiftrt")
+       ("*<risbg_n>_ior_and_sr_ze")
+       ("*extract1bitdi<clobbercc_or_nocc>")
+       ("*insv<mode><clobbercc_or_nocc>", "*insv_rnsbg_noshift")
+       ("*insv_rnsbg_srl", "*insv<mode>_mem_reg")
+       ("*insvdi_mem_reghigh", "*insvdi_reg_imm"): Use EXTRACT_ARGS_IN_RANGE
+       to validate the arguments of zero_extract and sign_extract.
+
 2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
        PR target/77822
index 5844e2847a5e3736197438611e24eab2614d98b6..4f2effd93ff04511b7e37a370a982c0014f8a110 100644 (file)
      (clobber (reg:CC CC_REGNUM))])]
   "TARGET_Z10"
 {
+  if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
+    FAIL;
   /* Starting with zEC12 there is risbgn not clobbering CC.  */
   if (TARGET_ZEC12)
     {
         (match_operand 2 "const_int_operand" "")   ; size
         (match_operand 3 "const_int_operand" ""))) ; start
   ]
-  "<z10_or_zEC12_cond>"
+  "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
+                            GET_MODE_BITSIZE (<MODE>mode))"
   "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
   [(set_attr "op_type" "RIE")
    (set_attr "z10prop" "z10_super_E1")])
        (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
                     (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
   "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
    && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
   "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
   [(set_attr "op_type" "RIE")
                  (match_operand 5 "const_int_operand" "")) ; start
                 4)))]
   "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
    && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
   "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
   [(set_attr "op_type" "RIE")
                (const_int 1)  ; size
                (match_operand 2 "const_int_operand" "")) ; start
               (const_int 0)))]
-  "<z10_or_zEC12_cond>"
+  "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
   "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
   [(set_attr "op_type" "RIE")
    (set_attr "z10prop" "z10_super_E1")])
                          (match_operand 2 "const_int_operand"    "I")) ; pos
        (match_operand:GPR 3 "nonimmediate_operand" "d"))]
   "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
+                            GET_MODE_BITSIZE (<MODE>mode))
    && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
   "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
   [(set_attr "op_type" "RIE")
          (match_operand:DI 3 "nonimmediate_operand" "d")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_Z10
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
    && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
   "rnsbg\t%0,%3,%2,63,0"
   [(set_attr "op_type" "RIE")])
          (match_operand:DI 4 "nonimmediate_operand" "d")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_Z10
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
    && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
   "rnsbg\t%0,%4,%2,%2+%1-1,%3"
   [(set_attr "op_type" "RIE")])
                        (match_operand 1 "const_int_operand" "n,n")
                        (const_int 0))
        (match_operand:W 2 "register_operand" "d,d"))]
-  "INTVAL (operands[1]) > 0
+  "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
+   && INTVAL (operands[1]) > 0
    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
 {
        (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
                     (const_int 32)))]
   "TARGET_ZARCH
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
    && INTVAL (operands[1]) > 0
    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
                         (match_operand 1 "const_int_operand" "n"))
        (match_operand:DI 2 "const_int_operand" "n"))]
   "TARGET_ZARCH
+   && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
    && INTVAL (operands[1]) >= 0
    && INTVAL (operands[1]) < BITS_PER_WORD
    && INTVAL (operands[1]) % 16 == 0"
index e39ab1c59a98a9f54c606769bc44758b7980e016..447aaf6e3a4b2597d2e40b07723db06b08bd3aea 100644 (file)
@@ -1,3 +1,10 @@
+2016-12-02  Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
+       PR target/77822
+       * gcc.target/s390/s390.exp: Support .C tests.
+       * gcc.target/s390/pr77822-2.c: New test.
+       * gcc.target/s390/pr77822-1.C: New test.
+
 2016-12-02  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        * gcc.target/s390/vector/vec-nopeel-1.c: New test.
diff --git a/gcc/testsuite/gcc.target/s390/pr77822-1.C b/gcc/testsuite/gcc.target/s390/pr77822-1.C
new file mode 100644 (file)
index 0000000..bd5a9b4
--- /dev/null
@@ -0,0 +1,21 @@
+/* Regression test for PR/77822.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=zEC12" } */
+
+class A {
+  void m_fn1();
+  char m_datawidth;
+  char m_subunits;
+  int m_subunit_infos[];
+};
+int a;
+long b;
+void A::m_fn1() {
+  int c = 32, d = m_datawidth / c;
+  for (int e = 0; e < d; e++) {
+    int f = e * 32;
+    if (b >> f & 1)
+      m_subunit_infos[m_subunits] = a;
+  }
+}
diff --git a/gcc/testsuite/gcc.target/s390/pr77822-2.c b/gcc/testsuite/gcc.target/s390/pr77822-2.c
new file mode 100644 (file)
index 0000000..6789152
--- /dev/null
@@ -0,0 +1,307 @@
+/* This testcase checks that the shift operand of r*sbg instructions is in
+   range.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=zEC12 -Wno-shift-count-overflow" } */
+
+int g;
+
+void pos_ll_129 (long long b)
+{
+  if (b >> 129 & 1)
+    g = b;
+}
+
+void sizepos_ll_134 (long long b)
+{
+  if (b >> 134 & 1)
+    g = b;
+}
+
+void pos_ll_65 (long long b)
+{
+  if (b >> 65 & 1)
+    g = b;
+}
+
+void sizepos_ll_70 (long long b)
+{
+  if (b >> 70 & 1)
+    g = b;
+}
+
+void pos_ll_33 (long long b)
+{
+  if (b >> 33 & 1)
+    g = b;
+}
+
+void sizepos_ll_38 (long long b)
+{
+  if (b >> 38 & 1)
+    g = b;
+}
+
+void pos_ll_17 (long long b)
+{
+  if (b >> 17 & 1)
+    g = b;
+}
+
+void sizepos_ll_22 (long long b)
+{
+  if (b >> 22 & 1)
+    g = b;
+}
+
+void pos_ll_8 (long long b)
+{
+  if (b >> 8 & 1)
+    g = b;
+}
+
+void sizepos_ll_13 (long long b)
+{
+  if (b >> 13 & 1)
+    g = b;
+}
+
+void pos_l_129 (long b)
+{
+  if (b >> 129 & 1)
+    g = b;
+}
+
+void sizepos_l_134 (long b)
+{
+  if (b >> 134 & 1)
+    g = b;
+}
+
+void pos_l_65 (long b)
+{
+  if (b >> 65 & 1)
+    g = b;
+}
+
+void sizepos_l_70 (long b)
+{
+  if (b >> 70 & 1)
+    g = b;
+}
+
+void pos_l_33 (long b)
+{
+  if (b >> 33 & 1)
+    g = b;
+}
+
+void sizepos_l_38 (long b)
+{
+  if (b >> 38 & 1)
+    g = b;
+}
+
+void pos_l_17 (long b)
+{
+  if (b >> 17 & 1)
+    g = b;
+}
+
+void sizepos_l_22 (long b)
+{
+  if (b >> 22 & 1)
+    g = b;
+}
+
+void pos_l_8 (long b)
+{
+  if (b >> 8 & 1)
+    g = b;
+}
+
+void sizepos_l_13 (long b)
+{
+  if (b >> 13 & 1)
+    g = b;
+}
+
+void pos_i_129 (int b)
+{
+  if (b >> 129 & 1)
+    g = b;
+}
+
+void sizepos_i_134 (int b)
+{
+  if (b >> 134 & 1)
+    g = b;
+}
+
+void pos_i_65 (int b)
+{
+  if (b >> 65 & 1)
+    g = b;
+}
+
+void sizepos_i_70 (int b)
+{
+  if (b >> 70 & 1)
+    g = b;
+}
+
+void pos_i_33 (int b)
+{
+  if (b >> 33 & 1)
+    g = b;
+}
+
+void sizepos_i_38 (int b)
+{
+  if (b >> 38 & 1)
+    g = b;
+}
+
+void pos_i_17 (int b)
+{
+  if (b >> 17 & 1)
+    g = b;
+}
+
+void sizepos_i_22 (int b)
+{
+  if (b >> 22 & 1)
+    g = b;
+}
+
+void pos_i_8 (int b)
+{
+  if (b >> 8 & 1)
+    g = b;
+}
+
+void sizepos_i_13 (int b)
+{
+  if (b >> 13 & 1)
+    g = b;
+}
+
+void pos_s_129 (short b)
+{
+  if (b >> 129 & 1)
+    g = b;
+}
+
+void sizepos_s_134 (short b)
+{
+  if (b >> 134 & 1)
+    g = b;
+}
+
+void pos_s_65 (short b)
+{
+  if (b >> 65 & 1)
+    g = b;
+}
+
+void sizepos_s_70 (short b)
+{
+  if (b >> 70 & 1)
+    g = b;
+}
+
+void pos_s_33 (short b)
+{
+  if (b >> 33 & 1)
+    g = b;
+}
+
+void sizepos_s_38 (short b)
+{
+  if (b >> 38 & 1)
+    g = b;
+}
+
+void pos_s_17 (short b)
+{
+  if (b >> 17 & 1)
+    g = b;
+}
+
+void sizepos_s_22 (short b)
+{
+  if (b >> 22 & 1)
+    g = b;
+}
+
+void pos_s_8 (short b)
+{
+  if (b >> 8 & 1)
+    g = b;
+}
+
+void sizepos_s_13 (short b)
+{
+  if (b >> 13 & 1)
+    g = b;
+}
+
+void pos_c_129 (signed char b)
+{
+  if (b >> 129 & 1)
+    g = b;
+}
+
+void sizepos_c_134 (signed char b)
+{
+  if (b >> 134 & 1)
+    g = b;
+}
+
+void pos_c_65 (signed char b)
+{
+  if (b >> 65 & 1)
+    g = b;
+}
+
+void sizepos_c_70 (signed char b)
+{
+  if (b >> 70 & 1)
+    g = b;
+}
+
+void pos_c_33 (signed char b)
+{
+  if (b >> 33 & 1)
+    g = b;
+}
+
+void sizepos_c_38 (signed char b)
+{
+  if (b >> 38 & 1)
+    g = b;
+}
+
+void pos_c_17 (signed char b)
+{
+  if (b >> 17 & 1)
+    g = b;
+}
+
+void sizepos_c_22 (signed char b)
+{
+  if (b >> 22 & 1)
+    g = b;
+}
+
+void pos_c_8 (signed char b)
+{
+  if (b >> 8 & 1)
+    g = b;
+}
+
+void sizepos_c_13 (signed char b)
+{
+  if (b >> 13 & 1)
+    g = b;
+}
index f4ad7a1f25bb6af237198b701023b338babadbec..450dcaf427275cb113b0e184943cdd658a464bab 100644 (file)
@@ -90,16 +90,16 @@ dg-init
 set md_tests $srcdir/$subdir/md/*.c
 
 # Main loop.
-dg-runtest [lsort [prune [glob -nocomplain $srcdir/$subdir/*.\[cS\]] \
+dg-runtest [lsort [prune [glob -nocomplain $srcdir/$subdir/*.{c,S,C}] \
                         $md_tests]] "" $DEFAULT_CFLAGS
 
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*vector*/*.\[cS\]]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*vector*/*.]] \
        "" $DEFAULT_CFLAGS
 
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/target-attribute/*.\[cS\]]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/target-attribute/*.{c,S,C}]] \
        "" $DEFAULT_CFLAGS
 
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/md/*.\[cS\]]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/md/*.{c,S,C}]] \
        "" $DEFAULT_CFLAGS
 
 # Additional hotpatch torture tests.