This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR31641: Fix S/390 setmem expander


Hi,

this fixes the memset problem in PR31641. Although the testcase is broken
GCC should not response with an ICE.

The problem was a broken assertion in the back end. Instead of checking
whether the length argument to memset is below 0 using the INTVAL of the
argument we should take care to handle *large* values properly.

Bootstrapped on s390x.
No testsuite regressions.

Ok for mainline and 4.1 ? Since it is broken in 4.1 as well its not a new regression in 4.2.

Bye,

-Andreas-


2007-04-24  Andreas Krebbel  <krebbel1@de.ibm.com>

	PR target/31641
	* config/s390/s390.c (s390_expand_setmem): Don't ICE for constant length
	argument of 0 for memset.
	(s390_expand_movmem, s390_expand_setmem, s390_expand_cmpmem): Use
	unsigned shift instead of the signed variant.


2007-04-24  Andreas Krebbel  <krebbel1@de.ibm.com>

	PR target/31641
	* gcc.c-torture/compile/pr31641.c: New testcase.


Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2007-04-23 16:02:36.000000000 +0200
--- gcc/config/s390/s390.c	2007-04-23 16:50:06.000000000 +0200
*************** s390_expand_movmem (rtx dst, rtx src, rt
*** 3568,3574 ****
        if (temp != count)
          emit_move_insn (count, temp);
  
!       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
        if (temp != blocks)
          emit_move_insn (blocks, temp);
  
--- 3568,3574 ----
        if (temp != count)
          emit_move_insn (count, temp);
  
!       temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
        if (temp != blocks)
          emit_move_insn (blocks, temp);
  
*************** s390_expand_movmem (rtx dst, rtx src, rt
*** 3605,3614 ****
  void
  s390_expand_setmem (rtx dst, rtx len, rtx val)
  {
!   gcc_assert (GET_CODE (len) != CONST_INT || INTVAL (len) > 0);
    gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
    
!   if (GET_CODE (len) == CONST_INT && INTVAL (len) <= 257)
      {
        if (val == const0_rtx && INTVAL (len) <= 256)
          emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
--- 3605,3616 ----
  void
  s390_expand_setmem (rtx dst, rtx len, rtx val)
  {
!   if (GET_CODE (len) == CONST_INT && INTVAL (len) == 0)
!     return;
! 
    gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
    
!   if (GET_CODE (len) == CONST_INT && INTVAL (len) > 0 && INTVAL (len) <= 257)
      {
        if (val == const0_rtx && INTVAL (len) <= 256)
          emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
*************** s390_expand_setmem (rtx dst, rtx len, rt
*** 3682,3688 ****
        if (temp != count)
          emit_move_insn (count, temp);
  
!       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
        if (temp != blocks)
          emit_move_insn (blocks, temp);
  
--- 3684,3690 ----
        if (temp != count)
          emit_move_insn (count, temp);
  
!       temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
        if (temp != blocks)
          emit_move_insn (blocks, temp);
  
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3774,3780 ****
        if (temp != count)
          emit_move_insn (count, temp);
  
!       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
        if (temp != blocks)
          emit_move_insn (blocks, temp);
  
--- 3776,3782 ----
        if (temp != count)
          emit_move_insn (count, temp);
  
!       temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
        if (temp != blocks)
          emit_move_insn (blocks, temp);
  
Index: gcc/testsuite/gcc.c-torture/compile/pr31641.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.c-torture/compile/pr31641.c	2007-04-23 17:04:26.000000000 +0200
***************
*** 0 ****
--- 1,19 ----
+ /* This used to ICE on S/390 with -O1 when expanding
+    memset in the back end.  */
+ 
+ typedef __SIZE_TYPE__ size_t;
+ extern void *memset(void *, int, size_t);
+ 
+ char *target;
+ 
+ void
+ foo ()
+ {
+   memset (target, 1, 0);
+ }
+ 
+ void
+ bar ()
+ {
+   memset (target, 1, -1);
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]