Bug 93658

Summary: [9 Regression] infinite loop building ghostscript and icu with -O3 on powerpc64le-linux-gnu
Product: gcc Reporter: Matthias Klose <doko>
Component: targetAssignee: Peter Bergner <bergner>
Status: RESOLVED FIXED    
Severity: normal CC: bergner, dimitar.yordanov, jakub
Priority: P2 Keywords: ra
Version: 9.2.1   
Target Milestone: 10.0   
URL: https://gcc.gnu.org/ml/gcc-patches/2020-02/msg01142.html
Host: Target: powerpc64le-linux-gnu
Build: Known to work: 10.0
Known to fail: 9.2.1, 9.5.0 Last reconfirmed: 2020-02-11 00:00:00
Attachments: preprocessed source

Description Matthias Klose 2020-02-10 20:21:05 UTC
Created attachment 47813 [details]
preprocessed source

seen with gcc-9 and trunk 20200204, building ghostscript and icu with -O3 on powerpc64le-linux-gnu.  Falling back to -O2 lets the build succeed, a -O3 build on x86_64-linux-gnu succeeds.

Program received signal SIGTSTP, Stopped (user).
push_to_sequence (first=0x7ffff320d580) at ../../src/gcc/emit-rtl.c:5574
5574    ../../src/gcc/emit-rtl.c: No such file or directory.
(gdb) bt
#0  push_to_sequence (first=0x7ffff320d580) at ../../src/gcc/emit-rtl.c:5574
#1  0x0000000010843000 in process_address_1 (nop=nop@entry=0, 
    check_only_p=check_only_p@entry=false, before=before@entry=0x7fffffffdbf0, 
    after=after@entry=0x7fffffffdbe8) at ../../src/gcc/lra-constraints.c:3434
#2  0x000000001084527c in process_address (after=<optimized out>, before=<optimized out>, 
    check_only_p=<optimized out>, nop=<optimized out>) at ../../src/gcc/lra-constraints.c:3637
#3  curr_insn_transform (check_only_p=check_only_p@entry=false)
    at ../../src/gcc/lra-constraints.c:3952
#4  0x000000001084ad10 in lra_constraints (first_p=<optimized out>)
    at ../../src/gcc/lra-constraints.c:5025
#5  0x0000000010833940 in lra (f=<optimized out>) at ../../src/gcc/lra.c:2437
#6  0x00000000107d893c in do_reload () at ../../src/gcc/ira.c:5518
#7  (anonymous namespace)::pass_reload::execute (this=<optimized out>) at ../../src/gcc/ira.c:5704
#8  0x0000000010928280 in execute_one_pass (pass=pass@entry=0x11d106f0)
    at ../../src/gcc/passes.c:2500
#9  0x0000000010929314 in execute_pass_list_1 (pass=0x11d106f0) at ../../src/gcc/passes.c:2588
#10 0x000000001092932c in execute_pass_list_1 (pass=0x11d0f4f0) at ../../src/gcc/passes.c:2589
#11 0x00000000109293b8 in execute_pass_list (fn=<optimized out>, pass=<optimized out>)
    at ../../src/gcc/passes.c:2599
#12 0x00000000104f4a2c in cgraph_node::expand (this=0x7ffff6ee7d28) at ../../src/gcc/context.h:48
#13 0x00000000104f600c in expand_all_functions () at ../../src/gcc/cgraphunit.c:2454
#14 symbol_table::compile (this=this@entry=0x7ffff52f0000) at ../../src/gcc/cgraphunit.c:2804
#15 0x00000000104f8c54 in symbol_table::compile (this=0x7ffff52f0000)
    at ../../src/gcc/cgraphunit.c:2984
#16 symbol_table::finalize_compilation_unit (this=0x7ffff52f0000)
    at ../../src/gcc/cgraphunit.c:2984
#17 0x0000000010a321bc in compile_file () at ../../src/gcc/toplev.c:483
#18 0x0000000010187c8c in do_compile () at ../../src/gcc/toplev.c:2273
#19 toplev::main (this=0x7fffffffe6a0, argc=<optimized out>, argv=<optimized out>)
    at ../../src/gcc/toplev.c:2412
#20 0x0000000010189e78 in main (argc=<optimized out>, argv=0x7fffffffeac8)
    at ../../src/gcc/main.c:39

GCC defaults to hardening options and is configured using
--enable-languages=c,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=powerpc64le-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --enable-plugin --enable-default-pie --with-system-zlib --disable-libphobos --enable-objc-gc=auto --enable-secureplt --with-cpu=power8 --enable-targets=powerpcle-linux --disable-multilib --enable-multiarch --disable-werror --with-long-double-128 --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=powerpc64le-linux-gnu --host=powerpc64le-linux-gnu --target=powerpc64le-linux-gnu
Comment 1 Matthias Klose 2020-02-10 20:23:06 UTC
memory usage stays constant at about 2GB, the package build gets cancelled after 150 minutes.
Comment 2 seurer 2020-02-10 22:16:32 UTC
How are you configuring ghostscript when you build it?  I get a link error involving png:
./obj/pngrutil.o: In function `png_read_filter_row':
pngrutil.c:(.text+0x8948): undefined reference to `png_init_filter_functions_vsx'
Comment 3 Peter Bergner 2020-02-10 23:13:48 UTC
I cannot recreate this with trunk or GCC 9 from today.  DO you have extra patches applied or ???
Comment 4 Matthias Klose 2020-02-11 06:07:17 UTC
the file from icu 65.1 is built using

g++ -v -Wdate-time -g -O3 -fstack-protector-strong -Wformat -Werror=format-security -W -Wall -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long -std=c++11 -c -o genmbcs.o genmbcs.ii

no specific patches applied for the trunk. The compiler defaults to PIE, and the usual hardening defaults:

/usr/lib/gcc/powerpc64le-linux-gnu/10/cc1plus -fpreprocessed genmbcs.ii -msecure-plt -quiet -dumpbase genmbcs.ii -mcpu=power8 -auxbase-strip genmbcs.o -g -O3 -Wdate-time -Wformat=1 -Werror=format-security -Wextra -Wall -Wpedantic -Wpointer-arith -Wwrite-strings -Wno-long-long -std=c++11 -version -fstack-protector-strong -fasynchronous-unwind-tables -fstack-protector-strong -Wformat-security -fstack-clash-protection
Comment 5 Peter Bergner 2020-02-11 15:55:29 UTC
Confirmed.  With the options in Comment 4, I'm able to recreate the hang/infinite loop.  I'll have a look.
Comment 6 Peter Bergner 2020-02-11 17:41:46 UTC
So we are in an infinite loop in process_address() calling process_address_1().  I've hacked in some code to ICE if we loop for too long and I'm currently using creduce to minimize the test case.
Comment 7 Peter Bergner 2020-02-11 19:02:29 UTC
Here's the minimal test case using options -O3 -mcpu=power8 -fstack-protector-strong:

void bar();
char b;
void
foo (void)
{
  char a;
  int d = b;
  char *e = &a;
  while (d)
    *e++ = --d;
  bar ();
}
Comment 8 Jakub Jelinek 2020-02-12 18:38:23 UTC
On the #c7 testcase, this started with r8-6072-ga3a821c903c9fa2288712d31da2038d0297babcb (so I wonder why this isn't a 8/9/10 Regression).
Comment 9 Peter Bergner 2020-02-12 21:33:17 UTC
(In reply to Jakub Jelinek from comment #8)
> On the #c7 testcase, this started with
> r8-6072-ga3a821c903c9fa2288712d31da2038d0297babcb (so I wonder why this
> isn't a 8/9/10 Regression).

I'm not sure Kelvin's patch is to blame.  I think it's just exposing a latent issue.
Comment 10 Peter Bergner 2020-02-19 23:03:45 UTC
Ok, after debugging, this looks to be a bug in rs6000_legitimate_address_p().
At the beginning of LRA, we have the following insn:

(insn 520 67 71 5 (set (mem:V16QI (and:DI (reg/f:DI 110 sfp)
                (const_int -16 [0xfffffffffffffff0])) [0 MEM <vector(16) char> [(char *)&a + 16B]+0 S16 A128])
        (reg:V16QI 303 [ vect__2.13 ])) "bug.i":10:10 1103 {vsx_movv16qi_64bit}
     (expr_list:REG_DEAD (reg:V16QI 303 [ vect__2.13 ])
        (nil)))

lra_eliminate() then converts that to:

(insn 520 67 71 5 (set (mem:V16QI (and:DI (plus:DI (reg/f:DI 110 sfp)
                    (const_int 112 [0x70]))
                (const_int -16 [0xfffffffffffffff0])) [0 MEM <vector(16) char> [(char *)&a + 16B]+0 S16 A128])
        (reg:V16QI 303 [ vect__2.13 ])) "bug.i":10:10 1103 {vsx_movv16qi_64bit}
     (expr_list:REG_DEAD (reg:V16QI 303 [ vect__2.13 ])
        (nil)))

which isn't valid and needs fixing...which is fine.  process_address() then gives us:

(insn 520 67 71 5 (set (mem:V16QI (and:DI (reg:DI 633)
                (const_int -16 [0xfffffffffffffff0])) [0 MEM <vector(16) char> [(char *)&a + 16B]+0 S16 A128])
        (reg:V16QI 303 [ vect__2.13 ])) "bug.i":10:10 1103 {vsx_movv16qi_64bit}
     (expr_list:REG_DEAD (reg:V16QI 303 [ vect__2.13 ])
        (nil)))

...with pseudo 633 being set to plus:DI (reg/f:DI 110 sfp) (const_int 112 [0x70])
which is also good.  The bug comes when we now pass insn 520 to rs6000_legitimate_address_p() and we hit the following code:

  /* If this is an unaligned stvx/ldvx type address, discard the outer AND.  */
  if (VECTOR_MEM_ALTIVEC_P (mode)
      && GET_CODE (x) == AND
      && CONST_INT_P (XEXP (x, 1))
      && INTVAL (XEXP (x, 1)) == -16)
    x = XEXP (x, 0);

Our mode is V16QI, so we should execute this code, but we don't.  The problem is that VECTOR_MEM_ALTIVEC_P(mode) checks for "rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC" and V16QI mode returns VECTOR_VSX, so we fail to fall into the code above and end up telling LRA this isn't a valid address.  LRA then attempts to spill this again and again and...   

The following patch fixes the bug for me and I'm regtesting it now:

--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -8808,7 +8808,7 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
   bool quad_offset_p = mode_supports_dq_form (mode);
 
   /* If this is an unaligned stvx/ldvx type address, discard the outer AND.  */
-  if (VECTOR_MEM_ALTIVEC_P (mode)
+  if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
       && GET_CODE (x) == AND
       && CONST_INT_P (XEXP (x, 1))
       && INTVAL (XEXP (x, 1)) == -16)
Comment 11 GCC Commits 2020-02-20 17:09:15 UTC
The master branch has been updated by Peter Bergner <bergner@gcc.gnu.org>:

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

commit r10-6760-gb82d426662469ee8b78ec7e8f74abe950485c9d5
Author: Peter Bergner <bergner@linux.ibm.com>
Date:   Thu Feb 20 11:08:02 2020 -0600

    rs6000: Fix infinite loop building ghostscript and icu [PR93658]
    
    Fix rs6000_legitimate_address_p(), which erroneously marks a valid Altivec
    address as being invalid, which causes LRA's process_address()  to go into
    an infinite loop spilling the same address over and over again.
    
    gcc/
    	PR target/93658
    	* config/rs6000/rs6000.c (rs6000_legitimate_address_p): Handle VSX
    	vector modes.
    
    gcc/testsuite/
    	PR target/93658
    	* gcc.target/powerpc/pr93658.c: New test.
Comment 12 GCC Commits 2020-02-20 17:27:07 UTC
The master branch has been updated by Peter Bergner <bergner@gcc.gnu.org>:

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

commit r10-6762-ge6f24f824beb8ba6805702e287bbd6153b472488
Author: Peter Bergner <bergner@linux.ibm.com>
Date:   Thu Feb 20 11:25:12 2020 -0600

    rs6000: Fix infinite loop building ghostscript and icu [PR93658]
    
    Previous push didn't get the ChangeLog entries or the actual fix.
    Push those now.
    
    gcc/
    	PR target/93658
    	* config/rs6000/rs6000.c (rs6000_legitimate_address_p): Handle VSX
    	vector modes.
    
    gcc/testsuite/
    	PR target/93658
    	* gcc.target/powerpc/pr93658.c: New test.
Comment 13 Peter Bergner 2020-02-23 00:32:14 UTC
Simple backports to GCC 8 and 9 exposed some bugs that have already been fixed on trunk.  The following patch resubmission includes those extra fixes that need backports too:

    https://gcc.gnu.org/ml/gcc-patches/2020-02/msg01253.html
Comment 14 GCC Commits 2020-02-24 00:33:03 UTC
The releases/gcc-9 branch has been updated by Peter Bergner <bergner@gcc.gnu.org>:

https://gcc.gnu.org/g:066184a282b622ac6880150eb4e42fe57881b606

commit r9-8269-g066184a282b622ac6880150eb4e42fe57881b606
Author: Peter Bergner <bergner@linux.ibm.com>
Date:   Sun Feb 23 18:22:57 2020 -0600

    rs6000: Fix infinite loop building ghostscript and icu [PR93658]
    
    Fix rs6000_legitimate_address_p(), which erroneously marks a valid Altivec
    address as being invalid, which causes LRA's process_address()  to go into
    an infinite loop spilling the same address over and over again.
    Include Mike's earlier commits that fix bugs this patch exposes.
    
    	Backport from master
    	2020-02-20  Peter Bergner  <bergner@linux.ibm.com>
    
    	PR target/93658
    	* config/rs6000/rs6000.c (rs6000_legitimate_address_p): Handle VSX
    	vector modes.
    
    	* gcc.target/powerpc/pr93658.c: New test.
Comment 15 GCC Commits 2020-02-24 04:13:11 UTC
The releases/gcc-8 branch has been updated by Peter Bergner <bergner@gcc.gnu.org>:

https://gcc.gnu.org/g:53efbfe030a5fda41e5e7856d76ea827dd09f49c

commit r8-10050-g53efbfe030a5fda41e5e7856d76ea827dd09f49c
Author: Peter Bergner <bergner@linux.ibm.com>
Date:   Sun Feb 23 22:04:44 2020 -0600

    rs6000: Fix infinite loop building ghostscript and icu [PR93658]
    
    Fix rs6000_legitimate_address_p(), which erroneously marks a valid Altivec
    address as being invalid, which causes LRA's process_address()  to go into
    an infinite loop spilling the same address over and over again.
    Include Mike's earlier commits that fix bugs this patch exposes.
    
    	Backport from master
    	2020-02-20  Peter Bergner  <bergner@linux.ibm.com>
    
    	PR target/93658
    	* config/rs6000/rs6000.c (rs6000_legitimate_address_p): Handle VSX
    	vector modes.
    
    	* gcc.target/powerpc/pr93658.c: New test.
    	* gcc.target/powerpc/vsx-vector-6-le.c: Update fragile insn count.
Comment 16 Peter Bergner 2020-02-24 04:23:05 UTC
Fixed everywhere.
Comment 17 Jakub Jelinek 2020-02-28 20:19:22 UTC
Caused PR93974.
Comment 18 Jakub Jelinek 2020-03-02 10:15:48 UTC
The fixes have been reverted for 9.3/8.4.
Comment 19 Jakub Jelinek 2020-03-12 11:59:01 UTC
GCC 9.3.0 has been released, adjusting target milestone.
Comment 20 Richard Biener 2021-06-01 08:16:19 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 21 Richard Biener 2022-05-27 08:43:26 UTC
Fixed for GCC 10.