[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-02 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #11 from Jakub Jelinek  ---
(In reply to Uroš Bizjak from comment #10)
> (In reply to Jakub Jelinek from comment #9)
> Years ago, I defined HAVE_PRE_DEC, and I was told that it is intended for
> targets that can increment pointer on *any* memory access, not just on stack
> pointer. So, x86 uses PRE_DEC and POST_INC only to abstract push and pop
> insn. Various parts of the compiler (modulo auto-inc-dec.c) mostly check for
> PRE_DEC and POST_INC to skip further optimizations, which is non-issue for
> push and pop.
> 
> But this generic part of the code assumes that any target can handle
> PRE_MODIFY, and emits insn even for !HAVE_PRE_MODIFY_DISP. This is
> conservatively incorrect, so conditionally disabling the part that blindly
> emits PRE_MODIFY is IMO the way to go.

But isn't that the same?  Targets can only define HAVE_PRE_MODIFY_DISP, if they
support PRE_MODIFY with arbitrary registers, but when they only support it with
the stack pointer, they can't.

> Maybe this issue should be discussed on the ML.

Maybe.
This matters only for targets that define PUSH_ROUNDING and define it to
something other than unconditionally the first argument.
I think that is
cr16, h8300, i386, m32c, m68k, pdp11, sh, stormy16
None of these targets define HAVE_PRE_MODIFY_DISP, though h8300 clearly has
patterns with pre_modify on stack_pointer_rtx (thus relies on the patch I've
attached not to be applied), and i386.c, m32c.c, pdp11.c stormy16.c all have
PRE_MODIFY tests at least in one place, e.g. pdp11.c has:
/* accept -(SP) -- which uses PRE_MODIFY for byte mode */
comment (and code inspection agrees with that), so at least pdp11 and h8300
would be broken by that change, maybe m32c and stormy16 too.

> BTW:
> 
> -  dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
> - gen_int_mode (offset, Pmode));
> +  if (offset)
> + dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
> +   gen_int_mode (offset, Pmode));
> +  else
> + dest_addr = stack_pointer_rtx;
> 
> plus_constant?

Sure, iff we want to do that change.

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-02 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #10 from Uroš Bizjak  ---
(In reply to Jakub Jelinek from comment #9)
> Created attachment 40868 [details]
> gcc7-pr79514.patch
> 
> You mean like this?  That certainly works for x86, but I'm afraid it is
> going to break or penalize various other arches.
> The thing is, HAVE_PRE_MODIFY_DISP is set to 1 only on 5 targets, but quick
> grep reveals that there are many more targets that somehow handle pre_modify
> or have insn patterns using that.  This is not unlike HAVE_PRE_DEC and
> similar, x86 also doesn't claim it has HAVE_PRE_DEC, yet it uses it for
> pushes.
> So I think pushxf1 expander in i386.md is the way to go.

Years ago, I defined HAVE_PRE_DEC, and I was told that it is intended for
targets that can increment pointer on *any* memory access, not just on stack
pointer. So, x86 uses PRE_DEC and POST_INC only to abstract push and pop insn.
Various parts of the compiler (modulo auto-inc-dec.c) mostly check for PRE_DEC
and POST_INC to skip further optimizations, which is non-issue for push and
pop.

But this generic part of the code assumes that any target can handle
PRE_MODIFY, and emits insn even for !HAVE_PRE_MODIFY_DISP. This is
conservatively incorrect, so conditionally disabling the part that blindly
emits PRE_MODIFY is IMO the way to go.

Maybe this issue should be discussed on the ML.

BTW:

-  dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-   gen_int_mode (offset, Pmode));
+  if (offset)
+   dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ gen_int_mode (offset, Pmode));
+  else
+   dest_addr = stack_pointer_rtx;

plus_constant?

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-02 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #9 from Jakub Jelinek  ---
Created attachment 40868
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40868=edit
gcc7-pr79514.patch

You mean like this?  That certainly works for x86, but I'm afraid it is going
to break or penalize various other arches.
The thing is, HAVE_PRE_MODIFY_DISP is set to 1 only on 5 targets, but quick
grep reveals that there are many more targets that somehow handle pre_modify or
have insn patterns using that.  This is not unlike HAVE_PRE_DEC and similar,
x86 also doesn't claim it has HAVE_PRE_DEC, yet it uses it for pushes.
So I think pushxf1 expander in i386.md is the way to go.

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-02 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #8 from Uroš Bizjak  ---
(In reply to Jakub Jelinek from comment #7)
> (In reply to Uroš Bizjak from comment #6)
> > (In reply to Uroš Bizjak from comment #5)
> > > Maybe we should use our own pushxf expander?
> > 
> > No. Middle end should be fixed. x86 does not define any of HAVE_PRE_MODIFY
> > macros.
> 
> So what it can emit?  PRE_DEC is not really right, because GET_MODE_SIZE
> (XFmode) is in that case 12, but PUSH_ROUNDING increases that to 16.  But
> the push actually needs to adjust sp by 16, not 12.
> With -m128bit-long-double, rounded_size is equal to GET_MODE_SIZE and we get
> to:
> 4124if (GET_MODE_SIZE (mode) == rounded_size)
> 4125  dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode,
> stack_pointer_rtx);
> I think i386.md should have a pushxf1 expander enabled at least for the case
> when GET_MODE_SIZE (XFmode) != PUSH_ROUNDING (GET_MODE_SIZE (XFmode)) and
> just not use PRE_DEC in the pattern at all, just sp subtraction plus store.

Just below the code you quoted is some fixup code, depending on
FUNCTION_ARG_PADDING () == downward. I wonder, why similar fixup can't be also
applied for upward padding (the referred code)? The proposed XFmode expander
would do just that - adjust the stack pointer reg and move the value to
adjusted position, as is already the case with a similar x86 splitter (...
which, according to its %%% comment, is a workaround by itself and should be
killed).

So, while introducing expander would solve this particular problem for x86, it
would leave other targets unfixed. IMO, this problem should be fixed in the
middle-end, not worked around with long-lasting target workarounds.

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-02 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #7 from Jakub Jelinek  ---
(In reply to Uroš Bizjak from comment #6)
> (In reply to Uroš Bizjak from comment #5)
> > Maybe we should use our own pushxf expander?
> 
> No. Middle end should be fixed. x86 does not define any of HAVE_PRE_MODIFY
> macros.

So what it can emit?  PRE_DEC is not really right, because GET_MODE_SIZE
(XFmode) is in that case 12, but PUSH_ROUNDING increases that to 16.  But the
push actually needs to adjust sp by 16, not 12.
With -m128bit-long-double, rounded_size is equal to GET_MODE_SIZE and we get
to:
4124  if (GET_MODE_SIZE (mode) == rounded_size)
4125dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode,
stack_pointer_rtx);
I think i386.md should have a pushxf1 expander enabled at least for the case
when GET_MODE_SIZE (XFmode) != PUSH_ROUNDING (GET_MODE_SIZE (XFmode)) and just
not use PRE_DEC in the pattern at all, just sp subtraction plus store.

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-01 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #6 from Uroš Bizjak  ---
(In reply to Uroš Bizjak from comment #5)
> Maybe we should use our own pushxf expander?

No. Middle end should be fixed. x86 does not define any of HAVE_PRE_MODIFY
macros.

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-01 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

--- Comment #5 from Uroš Bizjak  ---
We go through:

  if (STACK_GROWS_DOWNWARD)
/* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC.  */
dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
  gen_int_mode (-(HOST_WIDE_INT) rounded_size,
Pmode));
  else
/* ??? This seems wrong if STACK_PUSH_CODE == POST_INC.  */
dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
  gen_int_mode (rounded_size, Pmode));

  dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);

Maybe we should use our own pushxf expander?

[Bug middle-end/79514] [5/6/7 Regression] ICE in curr_insn_transform, at lra-constraints.c:3773

2017-03-01 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79514

Uroš Bizjak  changed:

   What|Removed |Added

  Component|target  |middle-end

--- Comment #4 from Uroš Bizjak  ---
(In reply to Uroš Bizjak from comment #3)
> (In reply to Gerhard Steinmetz from comment #0)
> > (insn 10 9 11 2 (set (mem:XF (pre_modify:DI (reg/f:DI 7 sp)
> > (plus:DI (reg/f:DI 7 sp)
> > (const_int -16 [0xfff0]))) [2  S12 A32])
> > (reg:XF 87 [ _1 ])) "pr46251.c":3 118 {*pushxf}
> >  (expr_list:REG_DEAD (reg:XF 87 [ _1 ])
> > (expr_list:REG_ARGS_SIZE (const_int 16 [0x10])
> > (nil
> 
> This doesn't look like a valid RTL to me.

A bit of debugging shows:

Breakpoint 1, gen_movxf (operand0=0x2e8f3318, operand1=0x2e8daf90) at
../../git/gcc/gcc/config/i386/i386.md:3185
3185  return standard_sse_constant_opcode (insn, operands[1]);
(gdb) p debug_rtx (operand1)
(reg:XF 87 [ _1 ])
$3 = void
(gdb) p debug_rtx (operand0)
(mem:XF (pre_modify:DI (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int -16 [0xfff0]))) [2  S12 A32])
$4 = void
(gdb) bt
#0  gen_movxf (operand0=0x2e8f3318, operand1=0x2e8daf90) at
../../git/gcc/gcc/config/i386/i386.md:3185
#1  0x007e23ef in operator() (a1=0x2e8daf90, a0=0x2e8f3318,
this=) at ../../git/gcc/gcc/recog.h:301
#2  emit_move_insn_1 (x=0x2e8f3318, y=0x2e8daf90) at
../../git/gcc/gcc/expr.c:3643
#3  0x007e2745 in emit_move_insn (x=x@entry=0x2e8f3318,
y=y@entry=0x2e8daf90) at ../../git/gcc/gcc/expr.c:3738
#4  0x007e4433 in emit_single_push_insn_1 (type=0x2e7c8498,
x=0x2e8daf90, mode=) at ../../git/gcc/gcc/expr.c:4185
#5  emit_single_push_insn (mode=, x=0x2e8daf90,
type=0x2e7c8498) at ../../git/gcc/gcc/expr.c:4197
#6  0x007e817b in emit_push_insn (x=0x2e8daf90, mode=XFmode,
type=0x2e7c8498, size=0x0, align=64, partial=0, reg=0x0, extra=0, 
args_addr=0x0, args_so_far=0x2e7b0480, reg_parm_stack_space=0,
alignment_pad=0x2e7b0480, sibcall_p=true)
at ../../git/gcc/gcc/expr.c:4536
...
(gdb) f 4
#4  0x007e4433 in emit_single_push_insn_1 (type=0x2e7c8498,
x=0x2e8daf90, mode=) at ../../git/gcc/gcc/expr.c:4185
4185  emit_move_insn (dest, x);
(gdb) p debug_rtx (dest)
(mem:XF (pre_modify:DI (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int -16 [0xfff0]))) [2  S12 A32])
$12 = void
(gdb) list
4180   outgoing arguments and we cannot allow reordering of reads
4181   from function arguments with stores to outgoing arguments
4182   of sibling calls.  */
4183set_mem_alias_set (dest, 0);
4184}
4185  emit_move_insn (dest, x);
4186}
4187
4188/* Emit and annotate a single push insn.  */
4189

So, it is middle end that generates invalid RTX.