I am looking at a bug/oddity in the HP-UX IA64 GCC compiler in ILP32 mode. Here is some code (cut out from libffi):
typedef void *PTR64 __attribute__((mode(DI))); extern void bar(PTR64); void foo(void * x) { bar(x); } Now the issue is whether or not this is legal and how x should get extended. I am assuming that it is legal and that, on IA64, we would like the pointer extended via the addp4 instruction. When I do not optimize this program I do not get any addp4 instructions, when I do optimize the program I do get the desired addp4 instructions. I believe the problem in the unoptomized case is in expand_expr_real_1, where we have: case NON_LVALUE_EXPR: case NOP_EXPR: case CONVERT_EXPR: . . . else if (modifier == EXPAND_INITIALIZER) op0 = gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, mode, op0); else if (target == 0) op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)))); else { convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)))); op0 = target; } The EXPAND_INITIALIZER if looks wrong (for IA64) because it assumes that ZERO_EXTEND and SIGN_EXTEND are the only possibilities and and if op0 is a pointer then we have a third possibility for ia64. Is the use of gen_rtx_fmt_e an optimization that could be replaced by convert_to_mode or convert_move or is there some underlying reason why that has to be a gen_rtx_fmt_e call for an initializer? The existing convert_to_mode and convert_move calls look suspicious to me too because they use the TYPE_UNSIGNED macro to determine wether to do signed or unsigned extensions and I am not sure if that would be set correctly for pointer types based on a platforms setting of POINTERS_EXTEND_UNSIGNED. Anyone have any insights? Steve Ellcey [EMAIL PROTECTED]