* PATCH [8/n] X32: Convert to Pmode if needed
@ 2011-07-19 7:58 H.J. Lu
2011-07-19 18:41 ` Uros Bizjak
2011-07-21 11:28 ` Uros Bizjak
0 siblings, 2 replies; 5+ messages in thread
From: H.J. Lu @ 2011-07-19 7:58 UTC (permalink / raw)
To: gcc-patches, Uros Bizjak
Hi,
This patch adds the missing Pmode check and conversion. OK for trunk?
Thanks.
H.J.
---
2011-07-18 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_legitimize_address): Convert to
Pmode if needed.
(ix86_expand_move): Likewise.
(ix86_expand_call): Likewise.
(ix86_expand_special_args_builtin): Likewise.
(ix86_expand_builtin): Likewise.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c268899..1ed451b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12618,7 +12667,11 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
rtx temp = gen_reg_rtx (Pmode);
rtx val = force_operand (XEXP (x, 1), temp);
if (val != temp)
- emit_move_insn (temp, val);
+ {
+ if (GET_MODE (val) != Pmode)
+ val = convert_to_mode (Pmode, val, 1);
+ emit_move_insn (temp, val);
+ }
XEXP (x, 1) = temp;
return x;
@@ -12629,7 +12682,11 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
rtx temp = gen_reg_rtx (Pmode);
rtx val = force_operand (XEXP (x, 0), temp);
if (val != temp)
- emit_move_insn (temp, val);
+ {
+ if (GET_MODE (val) != Pmode)
+ val = convert_to_mode (Pmode, val, 1);
+ emit_move_insn (temp, val);
+ }
@@ -14956,6 +15023,8 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
if (model)
{
op1 = legitimize_tls_address (op1, model, true);
+ if (GET_MODE (op1) != mode)
+ op1 = convert_to_mode (mode, op1, 1);
op1 = force_operand (op1, op0);
if (op1 == op0)
return;
@@ -21475,7 +21554,10 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
: !call_insn_operand (XEXP (fnaddr, 0), Pmode))
{
- fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
+ fnaddr = XEXP (fnaddr, 0);
+ if (GET_MODE (fnaddr) != Pmode)
+ fnaddr = convert_to_mode (Pmode, fnaddr, 1);
+ fnaddr = copy_to_mode_reg (Pmode, fnaddr);
fnaddr = gen_rtx_MEM (QImode, fnaddr);
}
@@ -26700,7 +26782,11 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
op = expand_normal (arg);
gcc_assert (target == 0);
if (memory)
- target = gen_rtx_MEM (tmode, copy_to_mode_reg (Pmode, op));
+ {
+ if (GET_MODE (op) != Pmode)
+ op = convert_to_mode (Pmode, op, 1);
+ target = gen_rtx_MEM (tmode, copy_to_mode_reg (Pmode, op));
+ }
else
target = force_reg (tmode, op);
arg_adjust = 1;
@@ -26743,6 +26829,8 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
if (i == memory)
{
/* This must be the memory operand. */
+ if (GET_MODE (op) != Pmode)
+ op = convert_to_mode (Pmode, op, 1);
op = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, op));
gcc_assert (GET_MODE (op) == mode
|| GET_MODE (op) == VOIDmode);
@@ -26969,6 +27057,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
mode1 = insn_data[icode].operand[1].mode;
mode2 = insn_data[icode].operand[2].mode;
+ if (GET_MODE (op0) != Pmode)
+ op0 = convert_to_mode (Pmode, op0, 1);
op0 = force_reg (Pmode, op0);
op0 = gen_rtx_MEM (mode1, op0);
@@ -27001,7 +27091,11 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
op0 = expand_normal (arg0);
icode = CODE_FOR_sse2_clflush;
if (!insn_data[icode].operand[0].predicate (op0, Pmode))
+ {
+ if (GET_MODE (op0) != Pmode)
+ op0 = convert_to_mode (Pmode, op0, 1);
op0 = copy_to_mode_reg (Pmode, op0);
+ }
emit_insn (gen_sse2_clflush (op0));
return 0;
@@ -27014,7 +27108,11 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
op1 = expand_normal (arg1);
op2 = expand_normal (arg2);
if (!REG_P (op0))
- op0 = copy_to_mode_reg (Pmode, op0);
+ {
+ if (GET_MODE (op0) != Pmode)
+ op0 = convert_to_mode (Pmode, op0, 1);
+ op0 = copy_to_mode_reg (Pmode, op0);
+ }
if (!REG_P (op1))
op1 = copy_to_mode_reg (SImode, op1);
if (!REG_P (op2))
@@ -27094,7 +27192,11 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
op0 = expand_normal (arg0);
icode = CODE_FOR_lwp_llwpcb;
if (!insn_data[icode].operand[0].predicate (op0, Pmode))
- op0 = copy_to_mode_reg (Pmode, op0);
+ {
+ if (GET_MODE (op0) != Pmode)
+ op0 = convert_to_mode (Pmode, op0, 1);
+ op0 = copy_to_mode_reg (Pmode, op0);
+ }
emit_insn (gen_lwp_llwpcb (op0));
return 0;
@@ -27153,7 +27255,10 @@ rdrand_step:
arg0 = CALL_EXPR_ARG (exp, 0);
op1 = expand_normal (arg0);
if (!address_operand (op1, VOIDmode))
- op1 = copy_addr_to_reg (op1);
+ {
+ op1 = convert_memory_address (Pmode, op1);
+ op1 = copy_addr_to_reg (op1);
+ }
emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
op1 = gen_reg_rtx (SImode);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH [8/n] X32: Convert to Pmode if needed
2011-07-19 7:58 PATCH [8/n] X32: Convert to Pmode if needed H.J. Lu
@ 2011-07-19 18:41 ` Uros Bizjak
2011-07-19 19:09 ` H.J. Lu
2011-07-21 11:28 ` Uros Bizjak
1 sibling, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2011-07-19 18:41 UTC (permalink / raw)
To: H.J. Lu; +Cc: gcc-patches
On Tue, Jul 19, 2011 at 6:47 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> This patch adds the missing Pmode check and conversion. OK for trunk?
> 2011-07-18 H.J. Lu <hongjiu.lu@intel.com>
>
> * config/i386/i386.c (ix86_legitimize_address): Convert to
> Pmode if needed.
> (ix86_expand_move): Likewise.
> (ix86_expand_call): Likewise.
> (ix86_expand_special_args_builtin): Likewise.
> (ix86_expand_builtin): Likewise.
copy_addr_to_reg ?
Uros.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH [8/n] X32: Convert to Pmode if needed
2011-07-19 18:41 ` Uros Bizjak
@ 2011-07-19 19:09 ` H.J. Lu
0 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 2011-07-19 19:09 UTC (permalink / raw)
To: Uros Bizjak; +Cc: gcc-patches
On Tue, Jul 19, 2011 at 10:49 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Jul 19, 2011 at 6:47 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>
>> This patch adds the missing Pmode check and conversion. OK for trunk?
>
>> 2011-07-18 H.J. Lu <hongjiu.lu@intel.com>
>>
>> * config/i386/i386.c (ix86_legitimize_address): Convert to
>> Pmode if needed.
>> (ix86_expand_move): Likewise.
>> (ix86_expand_call): Likewise.
>> (ix86_expand_special_args_builtin): Likewise.
>> (ix86_expand_builtin): Likewise.
>
> copy_addr_to_reg ?
>
The change is
arg0 = CALL_EXPR_ARG (exp, 0);
op1 = expand_normal (arg0);
if (!address_operand (op1, VOIDmode))
- op1 = copy_addr_to_reg (op1);
+ {
+ op1 = convert_memory_address (Pmode, op1);
+ op1 = copy_addr_to_reg (op1);
+ }
emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
op1 = gen_reg_rtx (SImode);
OP1 may not be in Pmode. My change calls convert_memory_address
before calling copy_addr_to_reg (op1).
--
H.J.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH [8/n] X32: Convert to Pmode if needed
2011-07-19 7:58 PATCH [8/n] X32: Convert to Pmode if needed H.J. Lu
2011-07-19 18:41 ` Uros Bizjak
@ 2011-07-21 11:28 ` Uros Bizjak
2011-07-22 8:08 ` H.J. Lu
1 sibling, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2011-07-21 11:28 UTC (permalink / raw)
To: H.J. Lu; +Cc: gcc-patches
On Tue, Jul 19, 2011 at 6:47 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
So, since copy_to_reg & co. expects x in Pmode or VOIDmode constant
(due to force_reg that won't do mode conversion), we have to implement
them with a mode conversion...
> This patch adds the missing Pmode check and conversion. OK for trunk?
> 2011-07-18 H.J. Lu <hongjiu.lu@intel.com>
>
> * config/i386/i386.c (ix86_legitimize_address): Convert to
> Pmode if needed.
> (ix86_expand_move): Likewise.
> (ix86_expand_call): Likewise.
> (ix86_expand_special_args_builtin): Likewise.
> (ix86_expand_builtin): Likewise.
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index c268899..1ed451b 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -12618,7 +12667,11 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
> rtx temp = gen_reg_rtx (Pmode);
> rtx val = force_operand (XEXP (x, 1), temp);
> if (val != temp)
> - emit_move_insn (temp, val);
> + {
> + if (GET_MODE (val) != Pmode)
> + val = convert_to_mode (Pmode, val, 1);
> + emit_move_insn (temp, val);
> + }
>
> XEXP (x, 1) = temp;
> return x;
OK.
> @@ -12629,7 +12682,11 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
> rtx temp = gen_reg_rtx (Pmode);
> rtx val = force_operand (XEXP (x, 0), temp);
> if (val != temp)
> - emit_move_insn (temp, val);
> + {
> + if (GET_MODE (val) != Pmode)
> + val = convert_to_mode (Pmode, val, 1);
> + emit_move_insn (temp, val);
> + }
OK.
> @@ -14956,6 +15023,8 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
> if (model)
> {
> op1 = legitimize_tls_address (op1, model, true);
> + if (GET_MODE (op1) != mode)
> + op1 = convert_to_mode (mode, op1, 1);
> op1 = force_operand (op1, op0);
> if (op1 == op0)
> return;
Please write this part in the same form as above two changes. This
way, force_operand will emit instructions in narrower mode (i.e.
SImode, not in DImode).
> @@ -21475,7 +21554,10 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
> ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
> : !call_insn_operand (XEXP (fnaddr, 0), Pmode))
> {
> - fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
> + fnaddr = XEXP (fnaddr, 0);
> + if (GET_MODE (fnaddr) != Pmode)
> + fnaddr = convert_to_mode (Pmode, fnaddr, 1);
> + fnaddr = copy_to_mode_reg (Pmode, fnaddr);
> fnaddr = gen_rtx_MEM (QImode, fnaddr);
> }
>
Use force_reg (Pmode, ...) instead of copy_to_mode_reg (Pmode, ...).
We know we have Pmode here. No need to copy a register if
convert_to_mode returned a register.
Better yet:
fnaddr = gen_rtx_MEM (QImode, force_reg (Pmode, fnaddr));
> @@ -26700,7 +26782,11 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
> op = expand_normal (arg);
> gcc_assert (target == 0);
> if (memory)
> - target = gen_rtx_MEM (tmode, copy_to_mode_reg (Pmode, op));
> + {
> + if (GET_MODE (op) != Pmode)
> + op = convert_to_mode (Pmode, op, 1);
> + target = gen_rtx_MEM (tmode, copy_to_mode_reg (Pmode, op));
> + }
> else
> target = force_reg (tmode, op);
> arg_adjust = 1;
Use force_reg.
> @@ -26743,6 +26829,8 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
> if (i == memory)
> {
> /* This must be the memory operand. */
> + if (GET_MODE (op) != Pmode)
> + op = convert_to_mode (Pmode, op, 1);
> op = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, op));
> gcc_assert (GET_MODE (op) == mode
> || GET_MODE (op) == VOIDmode);
Same here.
> @@ -26969,6 +27057,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
> mode1 = insn_data[icode].operand[1].mode;
> mode2 = insn_data[icode].operand[2].mode;
>
> + if (GET_MODE (op0) != Pmode)
> + op0 = convert_to_mode (Pmode, op0, 1);
> op0 = force_reg (Pmode, op0);
> op0 = gen_rtx_MEM (mode1, op0);
>
op0 = gen_rtx_MEM (mode1, force_reg (Pmode, op0));
> @@ -27001,7 +27091,11 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
> op0 = expand_normal (arg0);
> icode = CODE_FOR_sse2_clflush;
> if (!insn_data[icode].operand[0].predicate (op0, Pmode))
> + {
> + if (GET_MODE (op0) != Pmode)
> + op0 = convert_to_mode (Pmode, op0, 1);
> op0 = copy_to_mode_reg (Pmode, op0);
> + }
>
> emit_insn (gen_sse2_clflush (op0));
> return 0;
Use force_reg.
> @@ -27014,7 +27108,11 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
> op1 = expand_normal (arg1);
> op2 = expand_normal (arg2);
> if (!REG_P (op0))
> - op0 = copy_to_mode_reg (Pmode, op0);
> + {
> + if (GET_MODE (op0) != Pmode)
> + op0 = convert_to_mode (Pmode, op0, 1);
> + op0 = copy_to_mode_reg (Pmode, op0);
> + }
> if (!REG_P (op1))
> op1 = copy_to_mode_reg (SImode, op1);
> if (!REG_P (op2))
And here.
> @@ -27094,7 +27192,11 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
> op0 = expand_normal (arg0);
> icode = CODE_FOR_lwp_llwpcb;
> if (!insn_data[icode].operand[0].predicate (op0, Pmode))
> - op0 = copy_to_mode_reg (Pmode, op0);
> + {
> + if (GET_MODE (op0) != Pmode)
> + op0 = convert_to_mode (Pmode, op0, 1);
> + op0 = copy_to_mode_reg (Pmode, op0);
> + }
> emit_insn (gen_lwp_llwpcb (op0));
> return 0;
>
And here.
> @@ -27153,7 +27255,10 @@ rdrand_step:
> arg0 = CALL_EXPR_ARG (exp, 0);
> op1 = expand_normal (arg0);
> if (!address_operand (op1, VOIDmode))
> - op1 = copy_addr_to_reg (op1);
> + {
> + op1 = convert_memory_address (Pmode, op1);
> + op1 = copy_addr_to_reg (op1);
> + }
> emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
>
> op1 = gen_reg_rtx (SImode);
>
OK.
Please re-test the patch on mainline. OK, if also passes x32 regression tests.
Thanks,
Uros.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH [8/n] X32: Convert to Pmode if needed
2011-07-21 11:28 ` Uros Bizjak
@ 2011-07-22 8:08 ` H.J. Lu
0 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 2011-07-22 8:08 UTC (permalink / raw)
To: Uros Bizjak; +Cc: gcc-patches
On Thu, Jul 21, 2011 at 3:00 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Jul 19, 2011 at 6:47 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>
> So, since copy_to_reg & co. expects x in Pmode or VOIDmode constant
> (due to force_reg that won't do mode conversion), we have to implement
> them with a mode conversion...
>
>> This patch adds the missing Pmode check and conversion. OK for trunk?
>
>> 2011-07-18 H.J. Lu <hongjiu.lu@intel.com>
>>
>> * config/i386/i386.c (ix86_legitimize_address): Convert to
>> Pmode if needed.
>> (ix86_expand_move): Likewise.
>> (ix86_expand_call): Likewise.
>> (ix86_expand_special_args_builtin): Likewise.
>> (ix86_expand_builtin): Likewise.
>>
>
>> @@ -21475,7 +21554,10 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
>> ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
>> : !call_insn_operand (XEXP (fnaddr, 0), Pmode))
>> {
>> - fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
>> + fnaddr = XEXP (fnaddr, 0);
>> + if (GET_MODE (fnaddr) != Pmode)
>> + fnaddr = convert_to_mode (Pmode, fnaddr, 1);
>> + fnaddr = copy_to_mode_reg (Pmode, fnaddr);
>> fnaddr = gen_rtx_MEM (QImode, fnaddr);
>> }
>>
>
> Use force_reg (Pmode, ...) instead of copy_to_mode_reg (Pmode, ...).
> We know we have Pmode here. No need to copy a register if
> convert_to_mode returned a register.
>
> Better yet:
>
> fnaddr = gen_rtx_MEM (QImode, force_reg (Pmode, fnaddr));
>
This caused the regression in 32bit:
[hjl@gnu-6 gcc]$ cat /tmp/x.i
f(x)
{
(*(void (*)())&x)();
}
[hjl@gnu-6 gcc]$ ./xgcc -B./ -S /tmp/x.i -m32 -O
/tmp/x.i: In function \u2018f\u2019:
/tmp/x.i:4:1: error: unrecognizable insn:
(call_insn 5 4 11 3 (call (mem:QI (reg/f:SI 53 virtual-incoming-args)
[0 *x.0_1 S1 A8])
(const_int 0 [0])) /tmp/x.i:3 -1
(nil)
(nil))
/tmp/x.i:4:1: internal compiler error: in extract_insn, at recog.c:2115
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
[hjl@gnu-6 gcc]$
I checked in the enclosed patch as an obvious fix.
--
H.J.
---
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6456000..5ac6697 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2011-07-21 H.J. Lu <hongjiu.lu@intel.com>
+ * config/i386/i386.c (ix86_expand_call): Call copy_to_mode_reg
+ instead of force_reg.
+
+2011-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
* config/i386/i386.c (ix86_expand_move): Convert to Pmode if
needed and use force_reg after convert.
(ix86_expand_call): Likewise.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 6e030d9..ddf674a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -21545,7 +21545,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
fnaddr = XEXP (fnaddr, 0);
if (GET_MODE (fnaddr) != Pmode)
fnaddr = convert_to_mode (Pmode, fnaddr, 1);
- fnaddr = gen_rtx_MEM (QImode, force_reg (Pmode, fnaddr));
+ fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr));
}
call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-07-22 5:26 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-19 7:58 PATCH [8/n] X32: Convert to Pmode if needed H.J. Lu
2011-07-19 18:41 ` Uros Bizjak
2011-07-19 19:09 ` H.J. Lu
2011-07-21 11:28 ` Uros Bizjak
2011-07-22 8:08 ` H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).