This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: POINTERS_EXTEND_UNSIGNED fix (found on IA64 HP-UX)
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: rth at redhat dot com, gcc-patches at gcc dot gnu dot org
- Date: Mon, 22 Jul 2002 12:32:12 -0700 (PDT)
- Subject: 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;
}