[PATCH 2/2 v3] PR77822

Dominik Vogt vogt@linux.vnet.ibm.com
Fri Nov 25 08:26:00 GMT 2016


On Mon, Nov 21, 2016 at 12:05:42PM +0100, Dominik Vogt wrote:
> On Thu, Nov 17, 2016 at 04:54:17PM +0100, Dominik Vogt wrote:
> > On Thu, Nov 17, 2016 at 04:53:03PM +0100, Dominik Vogt wrote:
> > > The following two patches fix PR 77822 on s390x for gcc-7.  As the
> > > macro doing the argument range checks can be used on other targets
> > > as well, I've put it in system.h (couldn't think of a better
> > > place; maybe rtl.h?).
> > > 
> > > Bootstrapped on s390x biarch, regression tested on s390x biarch
> > > and s390, all on a zEC12 with -march=zEC12.
> > > 
> > > Please check the commit messages for details.
> > 
> > S390 backend patch.

Version 4 of the patchset.  Bootstrapped and regression tested on
s390 biarch and s390.

Changes since the first version of the patchset:

v2:
        Add s390 test cases.
        Support .cxx tests in s390.exp.
        Put all arguments of SIZE_POS_IN_RANGE in parentheses.
        Rewrite SIZE_POS_IN_RANGE macro to handle wrapping SIZE +
POS.

v3:
        Rename macro argument from UPPER back to RANGE.

v4:
        Rename SIZE_POS_IN_RANGE to EXTRACT_ARGS_IN_RANGE and move it to rtl.h.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany
-------------- next part --------------
gcc/ChangeLogb

	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/ChangeLogb

	PR target/77822
	* gcc.target/s390/s390.exp: Support .cxx tests.
	* gcc.target/s390/pr77822-2.c: New test.
	* gcc.target/s390/pr77822-1.cxx: New test.
-------------- next part --------------
>From bcf508a7e2f90c7e67702c437780cc12a3f74860 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Thu, 17 Nov 2016 14:49:48 +0100
Subject: [PATCH 2/2] PR target/77822: S390: Validate argument range of
 {zero,sign}_extract.

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/config/s390/s390.md                     |  20 +-
 gcc/testsuite/gcc.target/s390/pr77822-1.cxx |  21 ++
 gcc/testsuite/gcc.target/s390/pr77822-2.c   | 307 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/s390/s390.exp      |   8 +-
 4 files changed, 349 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/pr77822-1.cxx
 create mode 100644 gcc/testsuite/gcc.target/s390/pr77822-2.c

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index a449b03..aaf8427 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3741,6 +3741,8 @@
      (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)
     {
@@ -3760,7 +3762,9 @@
         (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")])
@@ -3773,6 +3777,7 @@
 	(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")
@@ -3791,6 +3796,7 @@
 		  (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")
@@ -3804,7 +3810,8 @@
 		(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")])
@@ -3919,6 +3926,8 @@
 			  (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")
@@ -4214,6 +4223,7 @@
 	  (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")])
@@ -4230,6 +4240,7 @@
 	  (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")])
@@ -4239,7 +4250,8 @@
 			(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"
 {
@@ -4260,6 +4272,7 @@
 	(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"
@@ -4278,6 +4291,7 @@
 			 (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"
diff --git a/gcc/testsuite/gcc.target/s390/pr77822-1.cxx b/gcc/testsuite/gcc.target/s390/pr77822-1.cxx
new file mode 100644
index 0000000..bd5a9b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr77822-1.cxx
@@ -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
index 0000000..6789152
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr77822-2.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp
index f4ad7a1..69c1f39 100644
--- a/gcc/testsuite/gcc.target/s390/s390.exp
+++ b/gcc/testsuite/gcc.target/s390/s390.exp
@@ -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,cxx}] \
 			 $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,cxx}]] \
 	"" $DEFAULT_CFLAGS
 
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/md/*.\[cS\]]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/md/*.{c,S,cxx}]] \
 	"" $DEFAULT_CFLAGS
 
 # Additional hotpatch torture tests.
-- 
2.3.0



More information about the Gcc-patches mailing list