Bug 103353 - Indefinite recursion when compiling -mmma requiring testcase w/ -maltivec
Summary: Indefinite recursion when compiling -mmma requiring testcase w/ -maltivec
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Kewen Lin
URL: https://gcc.gnu.org/pipermail/gcc-pat...
Keywords: error-recovery, ice-on-invalid-code
: 101323 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-11-22 02:09 UTC by Arseny Solokha
Modified: 2022-08-25 05:55 UTC (History)
4 users (show)

See Also:
Host:
Target: powerpc-*-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-02-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2021-11-22 02:09:26 UTC
g++-12.0.0-alpha20211114 snapshot (g:3057f1ab737582a9fb37a3fb967ed8bf3659f2f4) ICEs because of stack exhaustion when compiling gcc/testsuite/gcc.target/powerpc/pr101849.c w/ -maltivec:

% powerpc-e300c3-linux-gnu-gcc-12.0.0 -maltivec -c gcc/testsuite/gcc.target/powerpc/pr101849.c
gcc/testsuite/gcc.target/powerpc/pr101849.c: In function 'foo':
gcc/testsuite/gcc.target/powerpc/pr101849.c:11:12: error: '__builtin_vsx_lxvp' requires the '-mmma' option
   11 |   dst[0] = __builtin_vsx_lxvp (0, (__vector_pair *)(void *)x);
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
powerpc-e300c3-linux-gnu-gcc-12.0.0: internal compiler error: Segmentation fault signal terminated program cc1

(gdb) where 10
#0  0x000000000093fc34 in ggc_internal_alloc (size=size@entry=24, f=f@entry=0x0, s=s@entry=0, n=n@entry=1)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/ggc-page.c:1278
#1  0x0000000000a8b94b in ggc_alloc<sequence_stack> ()
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/ggc.h:178
#2  start_sequence ()
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/emit-rtl.c:5476
#3  0x0000000000ac850b in emit_move_multi_word (mode=E_OOmode, x=<optimized out>, y=0x7ffff75fe978)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/expr.c:3889
#4  0x0000000000ac3d3f in emit_move_insn (x=x@entry=0x7ffff6511060, y=y@entry=0x7ffff75fe978)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/expr.c:4128
#5  0x0000000000a9ce04 in copy_to_reg (x=x@entry=0x7ffff75fe978)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/explow.c:625
#6  0x0000000000a88908 in operand_subword_force (op=op@entry=0x7ffff75fe978, offset=offset@entry=..., mode=mode@entry=E_OOmode)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/emit-rtl.c:1802
#7  0x0000000000ac861e in emit_move_multi_word (mode=E_OOmode, x=<optimized out>, y=0x7ffff75fe978)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/expr.c:3918
#8  0x0000000000ac3d3f in emit_move_insn (x=x@entry=0x7ffff6511018, y=y@entry=0x7ffff75fe978)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/expr.c:4128
#9  0x0000000000a9ce04 in copy_to_reg (x=x@entry=0x7ffff75fe978)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/explow.c:625
(More stack frames follow...)

(gdb) where -10
#882893 0x00000000009d29e5 in cgraph_node::expand (this=0x7ffff77c8440)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/context.h:48
#882894 cgraph_node::expand (this=0x7ffff77c8440)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/cgraphunit.c:1781
#882895 0x00000000009d3df6 in output_in_order ()
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/cgraphunit.c:2135
#882896 symbol_table::compile (this=0x7ffff77c0000)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/cgraphunit.c:2353
#882897 symbol_table::compile (this=0x7ffff77c0000)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/cgraphunit.c:2267
#882898 0x00000000009d6d07 in symbol_table::finalize_compilation_unit (this=0x7ffff77c0000)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/cgraphunit.c:2537
#882899 0x0000000000e8b4f7 in compile_file ()
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/toplev.c:479
#882900 0x000000000080d376 in do_compile (no_backend=false)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/toplev.c:2156
#882901 toplev::main (this=this@entry=0x7fffffffd9f6, argc=<optimized out>, argc@entry=12, argv=<optimized out>,
    argv@entry=0x7fffffffdb48)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/toplev.c:2308
#882902 0x000000000080f261 in main (argc=12, argv=0x7fffffffdb48)
    at /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-12.0.0_alpha20211114/work/gcc-12-20211114/gcc/main.c:39
Comment 1 Kewen Lin 2022-02-17 01:55:15 UTC
Confirmed.
Comment 2 Kewen Lin 2022-02-22 07:37:09 UTC
In function rs6000_expand_builtin, we have one hunk to check if one bif has been enabled under the expected target flags, otherwise it will emit error but still tries to expand the call.

  if (!(e == ENB_ALWAYS
	|| (e == ENB_P5 && TARGET_POPCNTB)
	|| (e == ENB_P6 && TARGET_CMPB)
        ...

	|| (e == ENB_P10_64 && TARGET_POWER10 && TARGET_POWERPC64)
	|| (e == ENB_MMA && TARGET_MMA)))
    {
      rs6000_invalid_builtin (fcode);
      return expand_call (exp, target, ignore);
    }

I simply hacked it into:

diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 5d34c1bcfc9..f888ce80c62 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -3284,7 +3284,7 @@ htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode,
    Use the new builtin infrastructure.  */
 rtx
 rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
-                       machine_mode /* mode */, int ignore)
+                       machine_mode /* mode */, int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   enum rs6000_gen_builtins fcode
@@ -3394,7 +3394,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
         || (e == ENB_MMA && TARGET_MMA)))
     {
       rs6000_invalid_builtin (fcode);
-      return expand_call (exp, target, ignore);
+      return const0_rtx;
     }

   if (bif_is_nosoft (*bifaddr)

and it's bootstrapped and no regression failures found on ppc64le p9/p10 and ppc64 p8. It's a bit surprising to me. By checking its history, it's added by r0-113861-g15ce64af29141f.  Either we miss some coverage here or it's unused any more.

I'm not sure why we still want to expand the call further, I guess we still want the bif to act like a normal function call and can link with some library definition?
Comment 3 Kewen Lin 2022-02-22 08:49:45 UTC
And I am also curious about what will we miss if just changing it back to return const0_rtx?

Back to the failure itself, without TARGET_MMA set we don't have the optab movoo support. When it is expanding the bif, it tries to emit_move_insn (target, valreg)

(gdb) pr target
(reg:OO 117 [ _1 ])

(gdb) pr valreg
(reg:OO 66 2)

For the target, it's pseudo and able to get subreg:SI; while for the valreg, it's hard reg, fails to gen subreg, but it will call operand_subword_force (y, i, mode) to get subword further, it goes with:

   copy_to_reg (op);

     further call: emit_move_insn (temp, x) 

// back to the original, OOmode move from the hard register to another pseudo, and again and again... until memory run out for allocation.

If the answer to the question above is it's still meaningful to expand this call without an expected context, I think we have to extend OOmode and XOmode handling.

Any thoughts?
Comment 4 Segher Boessenkool 2022-02-22 11:33:44 UTC
You miss all extra errors the expand_call can generate.  This is the general
reason why we try to continue instead of stopping after the first error.  The
reason is that later errors may be more obvious to the user.  This of course
does no longer work so well because our errors now take 30 lines instead of 1.

It probably is best if the generic opaque-mode emit_move code does not try
to move it via some other mode_class.  Peter?

Failing that, we can work around it by having move patterns for those modes
always, but hard erroring on them (FAIL is no good).
Comment 5 Kewen Lin 2022-02-23 02:38:33 UTC
(In reply to Segher Boessenkool from comment #4)
> You miss all extra errors the expand_call can generate.  This is the general
> reason why we try to continue instead of stopping after the first error.  The
> reason is that later errors may be more obvious to the user.  This of course
> does no longer work so well because our errors now take 30 lines instead of
> 1.
> 

Thanks for the explanation! One consequent question is that this point can be applied for the other places where some expected conditions don't hold for bif expansion, but I saw the other places are using "return const0_rtx". Is there something special causing this difference?

> It probably is best if the generic opaque-mode emit_move code does not try
> to move it via some other mode_class.  Peter?
> 
> Failing that, we can work around it by having move patterns for those modes
> always, but hard erroring on them (FAIL is no good).

Yeah, one workround can help the ICE gone: (similar thing needed for XOmode as well):

diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index 907c9d6d516..04e887ad147 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -268,10 +268,12 @@ (define_int_attr avvi4i4i4 [(UNSPEC_MMA_PMXVI8GER4PP       "pmxvi8ger4pp")
 (define_expand "movoo"
   [(set (match_operand:OO 0 "nonimmediate_operand")
         (match_operand:OO 1 "input_operand"))]
-  "TARGET_MMA"
+  ""
 {
-  rs6000_emit_move (operands[0], operands[1], OOmode);
-  DONE;
+  if (TARGET_MMA) {
+    rs6000_emit_move (operands[0], operands[1], OOmode);
+    DONE;
+  }
 })

 (define_insn_and_split "*movoo"
Comment 6 Arseny Solokha 2022-02-24 04:32:36 UTC
*** Bug 101323 has been marked as a duplicate of this bug. ***
Comment 7 Segher Boessenkool 2022-02-24 12:12:08 UTC
(In reply to Kewen Lin from comment #5)
> (In reply to Segher Boessenkool from comment #4)
> > You miss all extra errors the expand_call can generate.  This is the general
> > reason why we try to continue instead of stopping after the first error.  The
> > reason is that later errors may be more obvious to the user.  This of course
> > does no longer work so well because our errors now take 30 lines instead of
> > 1.
> 
> Thanks for the explanation! One consequent question is that this point can
> be applied for the other places where some expected conditions don't hold
> for bif expansion, but I saw the other places are using "return const0_rtx".
> Is there something special causing this difference?

Not really, no.  In general we try to continue a bit longer (like, evaluate
the arguments, as here).  This gives much better diagnostics to the user.  In
a few cases you just have to give up early though, for practical reasons.

> > It probably is best if the generic opaque-mode emit_move code does not try
> > to move it via some other mode_class.  Peter?
> > 
> > Failing that, we can work around it by having move patterns for those modes
> > always, but hard erroring on them (FAIL is no good).
> 
> Yeah, one workround can help the ICE gone: (similar thing needed for XOmode
> as well):
> 
> diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
> index 907c9d6d516..04e887ad147 100644
> --- a/gcc/config/rs6000/mma.md
> +++ b/gcc/config/rs6000/mma.md
> @@ -268,10 +268,12 @@ (define_int_attr avvi4i4i4 [(UNSPEC_MMA_PMXVI8GER4PP  
> "pmxvi8ger4pp")
>  (define_expand "movoo"
>    [(set (match_operand:OO 0 "nonimmediate_operand")
>          (match_operand:OO 1 "input_operand"))]
> -  "TARGET_MMA"
> +  ""
>  {
> -  rs6000_emit_move (operands[0], operands[1], OOmode);
> -  DONE;
> +  if (TARGET_MMA) {
> +    rs6000_emit_move (operands[0], operands[1], OOmode);
> +    DONE;
> +  }
>  })

Like that.  But with a big fat comment, what is done when !TARGET_MMA, and
why we do that.  It is arguably the completely wrong thing to do for opaque
modes.
Comment 8 GCC Commits 2022-08-16 05:50:43 UTC
The master branch has been updated by Kewen Lin <linkw@gcc.gnu.org>:

https://gcc.gnu.org/g:9367e3a65f874dffc8f8a3b6760e77fd9ed67117

commit r13-2062-g9367e3a65f874dffc8f8a3b6760e77fd9ed67117
Author: Kewen.Lin <linkw@gcc.gnu.org>
Date:   Tue Aug 16 00:24:07 2022 -0500

    rs6000: Adjust mov optabs for opaque modes [PR103353]
    
    As PR103353 shows, we may want to continue to expand built-in
    function __builtin_vsx_lxvp, even if we have already emitted
    error messages about some missing required conditions.  As
    shown in that PR, without one explicit mov optab on OOmode
    provided, it would call emit_move_insn recursively.
    
    So this patch is to allow the mov pattern to be generated during
    expanding phase if compiler has already seen errors.
    
            PR target/103353
    
    gcc/ChangeLog:
    
            * config/rs6000/mma.md (define_expand movoo): Move TARGET_MMA condition
            check to preparation statements and add handlings for !TARGET_MMA.
            (define_expand movxo): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/powerpc/pr103353.c: New test.
Comment 9 GCC Commits 2022-08-24 02:31:42 UTC
The releases/gcc-12 branch has been updated by Kewen Lin <linkw@gcc.gnu.org>:

https://gcc.gnu.org/g:d0d72e0b1ebbac487d70281a56799bf547034ec1

commit r12-8709-gd0d72e0b1ebbac487d70281a56799bf547034ec1
Author: Kewen.Lin <linkw@gcc.gnu.org>
Date:   Tue Aug 16 00:24:07 2022 -0500

    rs6000: Adjust mov optabs for opaque modes [PR103353]
    
    As PR103353 shows, we may want to continue to expand built-in
    function __builtin_vsx_lxvp, even if we have already emitted
    error messages about some missing required conditions.  As
    shown in that PR, without one explicit mov optab on OOmode
    provided, it would call emit_move_insn recursively.
    
    So this patch is to allow the mov pattern to be generated during
    expanding phase if compiler has already seen errors.
    
            PR target/103353
    
    gcc/ChangeLog:
    
            * config/rs6000/mma.md (define_expand movoo): Move TARGET_MMA condition
            check to preparation statements and add handlings for !TARGET_MMA.
            (define_expand movxo): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/powerpc/pr103353.c: New test.
    
    (cherry picked from commit 9367e3a65f874dffc8f8a3b6760e77fd9ed67117)
Comment 10 GCC Commits 2022-08-24 02:32:58 UTC
The releases/gcc-11 branch has been updated by Kewen Lin <linkw@gcc.gnu.org>:

https://gcc.gnu.org/g:3fc2a9dba4c06115daaa8a39acffadbc33b51152

commit r11-10220-g3fc2a9dba4c06115daaa8a39acffadbc33b51152
Author: Kewen.Lin <linkw@gcc.gnu.org>
Date:   Tue Aug 16 00:24:07 2022 -0500

    rs6000: Adjust mov optabs for opaque modes [PR103353]
    
    As PR103353 shows, we may want to continue to expand built-in
    function __builtin_vsx_lxvp, even if we have already emitted
    error messages about some missing required conditions.  As
    shown in that PR, without one explicit mov optab on OOmode
    provided, it would call emit_move_insn recursively.
    
    So this patch is to allow the mov pattern to be generated during
    expanding phase if compiler has already seen errors.
    
            PR target/103353
    
    gcc/ChangeLog:
    
            * config/rs6000/mma.md (define_expand movoo): Move TARGET_MMA condition
            check to preparation statements and add handlings for !TARGET_MMA.
            (define_expand movxo): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/powerpc/pr103353.c: New test.
    
    (cherry picked from commit 9367e3a65f874dffc8f8a3b6760e77fd9ed67117)
Comment 11 GCC Commits 2022-08-24 02:35:41 UTC
The releases/gcc-10 branch has been updated by Kewen Lin <linkw@gcc.gnu.org>:

https://gcc.gnu.org/g:501fba663052b0b4a1eb6a42c32b74c254cbedbc

commit r10-10959-g501fba663052b0b4a1eb6a42c32b74c254cbedbc
Author: Kewen Lin <linkw@linux.ibm.com>
Date:   Tue Aug 23 03:31:17 2022 -0500

    rs6000: Adjust mov optabs for opaque modes [PR103353]
    
    As PR103353 shows, we may want to continue to expand built-in
    function __builtin_vsx_lxvp, even if we have already emitted
    error messages about some missing required conditions.  As
    shown in that PR, without one explicit mov optab on OOmode
    provided, it would call emit_move_insn recursively.
    
    So this patch is to allow the mov pattern to be generated during
    expanding phase if compiler has already seen errors.
    
            PR target/103353
    
    gcc/ChangeLog:
    
            * config/rs6000/mma.md (define_expand movpoi): Move TARGET_MMA condition
            check to preparation statements and add handlings for !TARGET_MMA.
            (define_expand movpxi): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/powerpc/pr103353.c: New test.
    
    (cherry picked from commit 9367e3a65f874dffc8f8a3b6760e77fd9ed67117)
Comment 12 Kewen Lin 2022-08-24 02:49:12 UTC
Fixed everywhere.