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]

Re: POINTERS_EXTEND_UNSIGNED fix (found on IA64 HP-UX)


This is a patch to address a bug I found in convert_memory_address and
to fix some code that Richard Henderson said was invalid.  After
modifying convert_memory_address I had a couple of failures that
involved inlining memcpy and friends so I had to modify opcodes.c to fix
those failures by ensuring that the routines return ptr_mode addresses
and not Pmode ones.

Also, I was originally going to skip the permutation of the PLUS and the
conversion when POINTERS_EXTEND_UNSIGNED < 0, but I found that I could
not compile gcc.c-torture/compile/20010107-1.c in 32 bit mode without
doing this optimization.  The compiler would die with:

20010107-1.c:6: error: unrecognizable insn:
(insn 36 29 37 0 00000000 (set (reg:DI 15 r15)
        (plus:DI (reg:DI 1 r1)
            (const:DI (reg:DI 340)))) -1 (nil)
    (nil))

Since nothing failed when I did do this optimization in
convert_memory_address I enabled it for IA64 HP-UX.

Steve Ellcey
sje@cup.hp.com



2002-07-22  Steve Ellcey  <sje@cup.hp.com>

	* gcc/explow.c (convert_memory_address): Fix conversion of CONSTs.
	Fix permutation of conversion and plus/mult.
	* gcc/builtins.c (expand_builtin_memcpy) Ensure return pointer is
	ptr_mode and not Pmode when POINTERS_EXTEND_UNSIGNED is defined.
	(expand_builtin_strncpy) Ditto.
	(expand_builtin_memset) Ditto.



*** gcc.orig/gcc/explow.c	Mon Jul 22 08:24:46 2002
--- gcc/gcc/explow.c	Mon Jul 22 11:05:18 2002
*************** convert_memory_address (to_mode, x)
*** 353,358 ****
--- 353,359 ----
  {
    enum machine_mode from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
    rtx temp;
+   enum rtx_code code;
  
    /* Here we handle some special cases.  If none of them apply, fall through
       to the default case.  */
*************** convert_memory_address (to_mode, x)
*** 360,366 ****
      {
      case CONST_INT:
      case CONST_DOUBLE:
!       return x;
  
      case SUBREG:
        if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x)))
--- 361,378 ----
      {
      case CONST_INT:
      case CONST_DOUBLE:
!       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode))
! 	code = TRUNCATE;
!       else if (POINTERS_EXTEND_UNSIGNED < 0)
! 	break;
!       else if (POINTERS_EXTEND_UNSIGNED > 0)
! 	code = ZERO_EXTEND;
!       else
! 	code = SIGN_EXTEND;
!       temp = simplify_unary_operation (code, to_mode, x, from_mode);
!       if (temp)
! 	return temp;
!       break;
  
      case SUBREG:
        if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x)))
*************** convert_memory_address (to_mode, x)
*** 389,405 ****
  
      case PLUS:
      case MULT:
!       /* For addition the second operand is a small constant, we can safely
! 	 permute the conversion and addition operation.  We can always safely
! 	 permute them if we are making the address narrower.  In addition,
! 	 always permute the operations if this is a constant.  */
!       if ((GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
! 	      || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT
! 		  && (INTVAL (XEXP (x, 1)) + 20000 < 40000
! 		      || CONSTANT_P (XEXP (x, 0))))))
  	return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
  			       convert_memory_address (to_mode, XEXP (x, 0)),
! 			       convert_memory_address (to_mode, XEXP (x, 1)));
        break;
  
      default:
--- 401,417 ----
  
      case PLUS:
      case MULT:
!       /* For addition we can safely permute the conversion and addition
! 	 operation if one operand is a constant and converting the constant
! 	 does not change it.  We can always safely permute them if we are
! 	 making the address narrower.  */
!       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
! 	  || (GET_CODE (x) == PLUS
! 	      && GET_CODE (XEXP (x, 1)) == CONST_INT
! 	      && XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1))))
  	return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
  			       convert_memory_address (to_mode, XEXP (x, 0)),
! 			       XEXP (x, 1));
        break;
  
      default:
*** gcc.orig/gcc/builtins.c	Mon Jul 22 08:24:50 2002
--- gcc/gcc/builtins.c	Mon Jul 22 09:34:57 2002
*************** expand_builtin_memcpy (arglist, target, 
*** 1981,1987 ****
  	  store_by_pieces (dest_mem, INTVAL (len_rtx),
  			   builtin_memcpy_read_str,
  			   (PTR) src_str, dest_align);
! 	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
  	}
  
        src_mem = get_memory_rtx (src);
--- 1981,1992 ----
  	  store_by_pieces (dest_mem, INTVAL (len_rtx),
  			   builtin_memcpy_read_str,
  			   (PTR) src_str, dest_align);
! 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
! #ifdef POINTERS_EXTEND_UNSIGNED
! 	  if (GET_MODE (dest_mem) != ptr_mode)
! 	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
! #endif
! 	  return dest_mem;
  	}
  
        src_mem = get_memory_rtx (src);
*************** expand_builtin_memcpy (arglist, target, 
*** 1991,1997 ****
        dest_addr = emit_block_move (dest_mem, src_mem, len_rtx);
  
        if (dest_addr == 0)
! 	dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
  
        return dest_addr;
      }
--- 1996,2008 ----
        dest_addr = emit_block_move (dest_mem, src_mem, len_rtx);
  
        if (dest_addr == 0)
! 	{
! 	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
! #ifdef POINTERS_EXTEND_UNSIGNED
! 	  if (GET_MODE (dest_addr) != ptr_mode)
! 	    dest_addr = convert_memory_address (ptr_mode, dest_addr);
! #endif
! 	}
  
        return dest_addr;
      }
*************** expand_builtin_strncpy (arglist, target,
*** 2107,2113 ****
  	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
  			   builtin_strncpy_read_str,
  			   (PTR) p, dest_align);
! 	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
  	}
  
        /* OK transform into builtin memcpy.  */
--- 2118,2129 ----
  	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
  			   builtin_strncpy_read_str,
  			   (PTR) p, dest_align);
! 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
! #ifdef POINTERS_EXTEND_UNSIGNED
! 	  if (GET_MODE (dest_mem) != ptr_mode)
! 	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
! #endif
! 	  return dest_mem;
  	}
  
        /* OK transform into builtin memcpy.  */
*************** expand_builtin_memset (exp, target, mode
*** 2232,2238 ****
  	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
  			   builtin_memset_gen_str,
  			   (PTR)val_rtx, dest_align);
! 	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
  	}
  
        if (target_char_cast (val, &c))
--- 2248,2259 ----
  	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
  			   builtin_memset_gen_str,
  			   (PTR)val_rtx, dest_align);
! 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
! #ifdef POINTERS_EXTEND_UNSIGNED
! 	  if (GET_MODE (dest_mem) != ptr_mode)
! 	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
! #endif
! 	  return dest_mem;
  	}
  
        if (target_char_cast (val, &c))
*************** expand_builtin_memset (exp, target, mode
*** 2251,2257 ****
  	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
  			   builtin_memset_read_str,
  			   (PTR) &c, dest_align);
! 	  return force_operand (XEXP (dest_mem, 0), NULL_RTX);
  	}
  
        len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
--- 2272,2283 ----
  	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
  			   builtin_memset_read_str,
  			   (PTR) &c, dest_align);
! 	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
! #ifdef POINTERS_EXTEND_UNSIGNED
! 	  if (GET_MODE (dest_mem) != ptr_mode)
! 	    dest_mem = convert_memory_address (ptr_mode, dest_mem);
! #endif
! 	  return dest_mem;
  	}
  
        len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
*************** expand_builtin_memset (exp, target, mode
*** 2261,2267 ****
        dest_addr = clear_storage (dest_mem, len_rtx);
  
        if (dest_addr == 0)
! 	dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
  
        return dest_addr;
      }
--- 2287,2299 ----
        dest_addr = clear_storage (dest_mem, len_rtx);
  
        if (dest_addr == 0)
! 	{
! 	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
! #ifdef POINTERS_EXTEND_UNSIGNED
! 	  if (GET_MODE (dest_addr) != ptr_mode)
! 	    dest_addr = convert_memory_address (ptr_mode, dest_addr);
! #endif
! 	}
  
        return dest_addr;
      }


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