* Issue during combine.
@ 2020-10-19 12:53 Henri Cloetens
2020-10-19 15:55 ` Henri Cloetens
2020-10-20 13:19 ` Richard Earnshaw
0 siblings, 2 replies; 8+ messages in thread
From: Henri Cloetens @ 2020-10-19 12:53 UTC (permalink / raw)
To: gcc-help
Hello all,
I am building a gcc 9.2.0 custom compiler, and I am running in an issue
during step 263, combine.
Before combine:
/(insn 2354 2352 1743 175 (set (reg/v:SI 197 [ dig ])//
// (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
// (const_int 1 [0x1]))//
// (reg:SI 708)//
// (reg/v:SI 197 [ dig ])))
"/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":771:6 35
{select_internal3}//
// (expr_list:REG_DEAD (reg:SI 708)//
// (expr_list:REG_DEAD (reg:SI 632)//
// (nil))))//
//(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
*s_304+0 S1 A8])//
// (subreg:QI (reg/v:SI 197 [ dig ]) 0))
"/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
{movqi_internal}//
// (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
// (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
// (nil))))/
This is during the combine-step transformed into:
/(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
*s_304+0 S1 A8])//
// (subreg:QI (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
// (const_int 1 [0x1]))//
// (reg:SI 708)//
// (reg/v:SI 197 [ dig ])) 0))
"/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
{movqi_internal}//
// (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
// (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
// (nil))))/
This, of course, is not correct any more. Now, how should I prevent this
?, the pattern is defined in the .md-file as:
/(define_insn "movqi_internal" //
//[(set (match_operand:QI 0 "movqi_operand_0"
"=r,r,r,r,r,r,u,u,W,t,r,c,*c*l,*h,*h,y")//
//(match_operand:QI 1 "movqi_operand_1" "O,k,i,r,W,t,W,t,r,r,*h,u, r,
r, 0,y"))]/
/.../
and /movqi_operand_1/ is defined as:
/(define_predicate "movqi_operand_1"//
// (ior (match_operand 0 "gpc_reg_operand")//
// (ior (match_operand 0
"quarterword_offset21_memref_operand_or_indirect")//
// (match_operand 0 "immediate_operand"))))/
and /gpc_reg_operand/ as:
/(define_predicate "gpc_reg_operand"//
// (and (match_operand 0 "register_operand")//
// (match_test "(GET_CODE (op) != REG && GET_CODE(op) != SUBREG//
// || (REGNO (op) >= ARG_POINTER_REGNUM//
// && !CA_REGNO_P (REGNO (op)))//
// || REGNO (op) == SFP_REGNO//
// || REGNO (op) == ARG_POINTER_REGNUM//
// || REGNO (op) <= MAX_REGFILE_REGNO)")))/
Any of you any idea why the combine succeeds ?. I mean, it should fail
!. After combine, it does not match /movqi_internal/ pattern
any more, but the compiler seems to think otherwise !.
Best Regards,
Henri.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-19 12:53 Issue during combine Henri Cloetens
@ 2020-10-19 15:55 ` Henri Cloetens
2020-10-19 19:28 ` Segher Boessenkool
2020-10-20 13:19 ` Richard Earnshaw
1 sibling, 1 reply; 8+ messages in thread
From: Henri Cloetens @ 2020-10-19 15:55 UTC (permalink / raw)
To: gcc-help
Hello all,
This seems to be a bug in the non-port code of the compiler.
It crashes in
/rtx simplify_subreg(machine_mode outer_mode, rtx op, machine_mode
inner_mode, poly_uint64 byte)/
The crash is, because this function is called with inner_mode =
Voidmode. (And seems illegal.)
It seems to me this "illegal" mode is the result of the /combine/ step,
trying to "improve" by doing combinations of
instructions "at random". Here, it tries a "combination" that does not
make sense, but it causes a crash in
the abovementioned routine. When I change the code, so that this routine
returns 0 (=fail the operation), it passes
the '263 step without errors. The meaningless combination is refused
elsewhere. It is not done.
Best Regards,
Henri.
On 10/19/2020 02:53 PM, Henri Cloetens wrote:
> Hello all,
>
> I am building a gcc 9.2.0 custom compiler, and I am running in an
> issue during step 263, combine.
>
> Before combine:
>
> /(insn 2354 2352 1743 175 (set (reg/v:SI 197 [ dig ])//
> // (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
> // (const_int 1 [0x1]))//
> // (reg:SI 708)//
> // (reg/v:SI 197 [ dig ])))
> "/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":771:6 35
> {select_internal3}//
> // (expr_list:REG_DEAD (reg:SI 708)//
> // (expr_list:REG_DEAD (reg:SI 632)//
> // (nil))))//
> //(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
> *s_304+0 S1 A8])//
> // (subreg:QI (reg/v:SI 197 [ dig ]) 0))
> "/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
> {movqi_internal}//
> // (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
> // (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
> // (nil))))/
>
> This is during the combine-step transformed into:
>
> /(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
> *s_304+0 S1 A8])//
> // (subreg:QI (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
> // (const_int 1 [0x1]))//
> // (reg:SI 708)//
> // (reg/v:SI 197 [ dig ])) 0))
> "/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
> {movqi_internal}//
> // (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
> // (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
> // (nil))))/
>
> This, of course, is not correct any more. Now, how should I prevent
> this ?, the pattern is defined in the .md-file as:
>
> /(define_insn "movqi_internal" //
> //[(set (match_operand:QI 0 "movqi_operand_0"
> "=r,r,r,r,r,r,u,u,W,t,r,c,*c*l,*h,*h,y")//
> //(match_operand:QI 1 "movqi_operand_1" "O,k,i,r,W,t,W,t,r,r,*h,u,
> r, r, 0,y"))]/
>
> /.../
> and /movqi_operand_1/ is defined as:
>
> /(define_predicate "movqi_operand_1"//
> // (ior (match_operand 0 "gpc_reg_operand")//
> // (ior (match_operand 0
> "quarterword_offset21_memref_operand_or_indirect")//
> // (match_operand 0 "immediate_operand"))))/
>
>
> and /gpc_reg_operand/ as:
>
> /(define_predicate "gpc_reg_operand"//
> // (and (match_operand 0 "register_operand")//
> // (match_test "(GET_CODE (op) != REG && GET_CODE(op) != SUBREG//
> // || (REGNO (op) >= ARG_POINTER_REGNUM//
> // && !CA_REGNO_P (REGNO (op)))//
> // || REGNO (op) == SFP_REGNO//
> // || REGNO (op) == ARG_POINTER_REGNUM//
> // || REGNO (op) <= MAX_REGFILE_REGNO)")))/
>
> Any of you any idea why the combine succeeds ?. I mean, it should fail
> !. After combine, it does not match /movqi_internal/ pattern
> any more, but the compiler seems to think otherwise !.
>
> Best Regards,
>
> Henri.
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-19 15:55 ` Henri Cloetens
@ 2020-10-19 19:28 ` Segher Boessenkool
2020-10-19 19:56 ` Henri Cloetens
0 siblings, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2020-10-19 19:28 UTC (permalink / raw)
To: Henri Cloetens; +Cc: gcc-help
[ Please don't top-post ]
Hi Henri,
On Mon, Oct 19, 2020 at 05:55:55PM +0200, Henri Cloetens wrote:
> On 10/19/2020 02:53 PM, Henri Cloetens wrote:
[ snip ]
> >This, of course, is not correct any more. Now, how should I prevent
> >this ?, the pattern is defined in the .md-file as:
The combiner only ever does transformations that result in recognised
instructions, see this code (and many lines before):
/* If it still isn't recognized, fail and change things back the way they
were. */
if ((insn_code_number < 0
/* Is the result a reasonable ASM_OPERANDS? */
&& (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
{
undo_all ();
return 0;
}
> >/(define_insn "movqi_internal" //
> >//[(set (match_operand:QI 0 "movqi_operand_0"
> >"=r,r,r,r,r,r,u,u,W,t,r,c,*c*l,*h,*h,y")//
> >//(match_operand:QI 1 "movqi_operand_1" "O,k,i,r,W,t,W,t,r,r,*h,u,
> >r, r, 0,y"))]/
> >
> >/.../
> >and /movqi_operand_1/ is defined as:
> >
> >/(define_predicate "movqi_operand_1"//
> >// (ior (match_operand 0 "gpc_reg_operand")//
> >// (ior (match_operand 0
> >"quarterword_offset21_memref_operand_or_indirect")//
> >// (match_operand 0 "immediate_operand"))))/
What is quarterword_offset21_memref_operand_or_indirect defined as?
> >Any of you any idea why the combine succeeds ?. I mean, it should fail
> >!. After combine, it does not match /movqi_internal/ pattern
> >any more, but the compiler seems to think otherwise !.
Maybe it matches some other pattern? Use -fdump-rtl-combine-all and
then look at the RTL dump file: at the end of each function it shows the
resulting RTL stream, and each insn like
(insn 7 18 8 2 (set (reg:DI 3 3)
(plus:DI (reg/f:DI 111 sfp)
(const_int 112 [0x70]))) "vlf.c":18:10 69 {*adddi3}
(nil))
shows the name of the pattern that matched this (*adddi3 here).
> This seems to be a bug in the non-port code of the compiler.
> It crashes in
> /rtx simplify_subreg(machine_mode outer_mode, rtx op, machine_mode
> inner_mode, poly_uint64 byte)/
>
> The crash is, because this function is called with inner_mode =
> Voidmode. (And seems illegal.)
Before you said that bad code was generated, and now you say the
compiler crashes. Which is it?
> It seems to me this "illegal" mode is the result of the /combine/ step,
> trying to "improve" by doing combinations of
> instructions "at random".
Combine combines instructions that have a (register) dependency. What
it comes up with as the combined insn is often not something that the
target in fact supports, but that is fine: then that combination is not
made.
> Here, it tries a "combination" that does not
> make sense, but it causes a crash in
> the abovementioned routine.
Please open a bug report (see <https://gcc.gnu.org/bugs.html> for
instructions). Thanks in advance!
> When I change the code, so that this routine
> returns 0 (=fail the operation), it passes
> the '263 step without errors. The meaningless combination is refused
> elsewhere. It is not done.
Btw, those numbers vary over time, and they are different for different
targets (combine currently is 265 for x86_64, and 270 for rs6000). Just
use the name please :-)
Segher
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-19 19:28 ` Segher Boessenkool
@ 2020-10-19 19:56 ` Henri Cloetens
2020-10-19 21:20 ` Segher Boessenkool
0 siblings, 1 reply; 8+ messages in thread
From: Henri Cloetens @ 2020-10-19 19:56 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: gcc-help
Hello Segher, Dan, all,
The issue is following:
(as far as I understand it.)
- There are 2 instructions, they are combined by the combiner.
- As correctly stated by you, the combiner tries these, to see if it
makes sense.
- Of course, it should not make sense, and should be rejected.
- However, during the "checking", the combiner calls "simplify_subreg"
in simplify-rtx.c.
- There, it crashes on "/gcc_assert(innermode != VOIDmode)/.
- Please look at the rtx, and how this is combined. This 'mistake' is
created by the combiner. Combining the RTX (see below),
it changed the expression
/(set (...) (subreg:qi(reg: si 197,0)))
/into
/(set (...) )subreg:qi(if_then_else ...
/Apparently, the /if_then_else/ - operator not being subreggable, this
is recognized as VOIDmode, causing simplify_subreg to crash.
- I fixed it by causing the subroutine to fail (= tell "this expression
cannot be simplified"), instead of crash by adding a statement.
- If you want me to submit it, well, simplify the test case that is
still possible, but ... how should I submit the custom back-end ?.
(I am willing to do it, but does it make sense ?.)
Best Regards,
Henri.
*BELOW/:/*/routine simplify_subreg/ and the relevant rtx statements
before and after combine.
//
/rtx//
//simplify_subreg (machine_mode outermode, rtx op,//
// machine_mode innermode, poly_uint64 byte)//
//{/*
/if(innermode == VOIDmode) return(0) ; // MY BUG//FIX/
*/gcc_assert(innermode != VOIDmode)/
Before combine:
/(insn 2354 2352 1743 175 (set (reg/v:SI 197 [ dig ])//
// (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
// (const_int 1 [0x1]))//
// (reg:SI 708)//
// (reg/v:SI 197 [ dig ])))
"/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":771:6 35
{select_internal3}//
// (expr_list:REG_DEAD (reg:SI 708)//
// (expr_list:REG_DEAD (reg:SI 632)//
// (nil))))//
//(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
*s_304+0 S1 A8])//
// (subreg:QI (reg/v:SI 197 [ dig ]) 0))
"/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
{movqi_internal}//
// (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
// (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
// (nil))))/
This is during the combine-step transformed into:
/(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
*s_304+0 S1 A8])//
// (subreg:QI (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
// (const_int 1 [0x1]))//
// (reg:SI 708)//
// (reg/v:SI 197 [ dig ])) 0))
"/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
{movqi_internal}//
// (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
// (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
// (nil))))/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-19 19:56 ` Henri Cloetens
@ 2020-10-19 21:20 ` Segher Boessenkool
0 siblings, 0 replies; 8+ messages in thread
From: Segher Boessenkool @ 2020-10-19 21:20 UTC (permalink / raw)
To: Henri Cloetens; +Cc: gcc-help
On Mon, Oct 19, 2020 at 09:56:04PM +0200, Henri Cloetens wrote:
> - However, during the "checking", the combiner calls "simplify_subreg"
> in simplify-rtx.c.
> - There, it crashes on "/gcc_assert(innermode != VOIDmode)/.
Because that is invalid RTL.
> /(insn 2354 2352 1743 175 (set (reg/v:SI 197 [ dig ])//
> // (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
> // (const_int 1 [0x1]))//
> // (reg:SI 708)//
> // (reg/v:SI 197 [ dig ])))
This is incorrect already (should be if_then_else:SI). It could have
crashed earlier... You can configure with "--enable-checking=yes,rtl"
to find many such problems (default is just "yes", see the manual for
other things you can ask to be checked ("tree" is useful; some others
are very very slow)).
HtH,
Segher
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-19 12:53 Issue during combine Henri Cloetens
2020-10-19 15:55 ` Henri Cloetens
@ 2020-10-20 13:19 ` Richard Earnshaw
2020-10-20 15:01 ` Henri Cloetens
1 sibling, 1 reply; 8+ messages in thread
From: Richard Earnshaw @ 2020-10-20 13:19 UTC (permalink / raw)
To: Henri Cloetens, gcc-help
On 19/10/2020 13:53, Henri Cloetens wrote:
> Hello all,
>
> I am building a gcc 9.2.0 custom compiler, and I am running in an issue
> during step 263, combine.
>
> Before combine:
>
> /(insn 2354 2352 1743 175 (set (reg/v:SI 197 [ dig ])//
> // (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
Your problem is likely here, on the input. The SET_SRC (the
if_then_else) of the pattern should have the same mode as the SET_DEST,
unless the SET_SRC is a CONST_INT.
R.
> // (const_int 1 [0x1]))//
> // (reg:SI 708)//
> // (reg/v:SI 197 [ dig ])))
> "/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":771:6 35
> {select_internal3}//
> // (expr_list:REG_DEAD (reg:SI 708)//
> // (expr_list:REG_DEAD (reg:SI 632)//
> // (nil))))//
> //(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
> *s_304+0 S1 A8])//
> // (subreg:QI (reg/v:SI 197 [ dig ]) 0))
> "/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
> {movqi_internal}//
> // (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
> // (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
> // (nil))))/
>
> This is during the combine-step transformed into:
>
> /(insn 1743 2354 124 175 (set (mem:QI (reg:SI 316 [ ivtmp.118 ]) [0
> *s_304+0 S1 A8])//
> // (subreg:QI (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
> // (const_int 1 [0x1]))//
> // (reg:SI 708)//
> // (reg/v:SI 197 [ dig ])) 0))
> "/home/henri/blueICe/gcc/newlib/newlib/libc/stdlib/dtoa.c":772:13 6
> {movqi_internal}//
> // (expr_list:REG_DEAD (reg:SI 316 [ ivtmp.118 ])//
> // (expr_list:REG_DEAD (reg/v:SI 197 [ dig ])//
> // (nil))))/
>
> This, of course, is not correct any more. Now, how should I prevent this
> ?, the pattern is defined in the .md-file as:
>
> /(define_insn "movqi_internal" //
> //[(set (match_operand:QI 0 "movqi_operand_0"
> "=r,r,r,r,r,r,u,u,W,t,r,c,*c*l,*h,*h,y")//
> //(match_operand:QI 1 "movqi_operand_1" "O,k,i,r,W,t,W,t,r,r,*h,u, r,
> r, 0,y"))]/
>
> /.../
> and /movqi_operand_1/ is defined as:
>
> /(define_predicate "movqi_operand_1"//
> // (ior (match_operand 0 "gpc_reg_operand")//
> // (ior (match_operand 0
> "quarterword_offset21_memref_operand_or_indirect")//
> // (match_operand 0 "immediate_operand"))))/
>
>
> and /gpc_reg_operand/ as:
>
> /(define_predicate "gpc_reg_operand"//
> // (and (match_operand 0 "register_operand")//
> // (match_test "(GET_CODE (op) != REG && GET_CODE(op) != SUBREG//
> // || (REGNO (op) >= ARG_POINTER_REGNUM//
> // && !CA_REGNO_P (REGNO (op)))//
> // || REGNO (op) == SFP_REGNO//
> // || REGNO (op) == ARG_POINTER_REGNUM//
> // || REGNO (op) <= MAX_REGFILE_REGNO)")))/
>
> Any of you any idea why the combine succeeds ?. I mean, it should fail
> !. After combine, it does not match /movqi_internal/ pattern
> any more, but the compiler seems to think otherwise !.
>
> Best Regards,
>
> Henri.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-20 13:19 ` Richard Earnshaw
@ 2020-10-20 15:01 ` Henri Cloetens
2020-10-20 15:48 ` Segher Boessenkool
0 siblings, 1 reply; 8+ messages in thread
From: Henri Cloetens @ 2020-10-20 15:01 UTC (permalink / raw)
To: Richard Earnshaw, gcc-help
Hello Richard, all,
Well, I guess there is the confusion.
- For me, this is a constant int.
- For gcc, apparently not.
Anyway, I changed the mode, and now it works.
Many thanks, Best Regards,
Henri.
On 10/20/2020 03:19 PM, Richard Earnshaw wrote:
> On 19/10/2020 13:53, Henri Cloetens wrote:
>> Hello all,
>>
>> I am building a gcc 9.2.0 custom compiler, and I am running in an issue
>> during step 263, combine.
>>
>> Before combine:
>>
>> /(insn 2354 2352 1743 175 (set (reg/v:SI 197 [ dig ])//
>> // (if_then_else (eq (subreg:QI (reg:SI 632) 1)//
> Your problem is likely here, on the input. The SET_SRC (the
> if_then_else) of the pattern should have the same mode as the SET_DEST,
> unless the SET_SRC is a CONST_INT.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Issue during combine.
2020-10-20 15:01 ` Henri Cloetens
@ 2020-10-20 15:48 ` Segher Boessenkool
0 siblings, 0 replies; 8+ messages in thread
From: Segher Boessenkool @ 2020-10-20 15:48 UTC (permalink / raw)
To: Henri Cloetens; +Cc: Richard Earnshaw, gcc-help
On Tue, Oct 20, 2020 at 05:01:24PM +0200, Henri Cloetens wrote:
> Well, I guess there is the confusion.
> - For me, this is a constant int.
A "constant int" (which this is not, fwiw) is not the same as a
CONST_INT. A CONST_INT is something specific in RTL (which always has
mode VOIDmode, and that is correct there, but not in most other
contexts).
Segher
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-10-20 15:49 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-19 12:53 Issue during combine Henri Cloetens
2020-10-19 15:55 ` Henri Cloetens
2020-10-19 19:28 ` Segher Boessenkool
2020-10-19 19:56 ` Henri Cloetens
2020-10-19 21:20 ` Segher Boessenkool
2020-10-20 13:19 ` Richard Earnshaw
2020-10-20 15:01 ` Henri Cloetens
2020-10-20 15:48 ` Segher Boessenkool
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).