The loop_align.c test has been broken for some time, since I put in patches to
eliminate some debug hooks (-mno-upper-regs-{df,di,sf}) that we deemed to no
longer be needed.
As Segher and I were discussing over private IRC, the root cause of this bug is
the compiler no long generates the BDNZ instruction for a count down loop,
instead it decrements the index in a GPR and does a branch/comparison on it.
In doing so, it now unrolls the loop twice, and and the resulting loop is too
big for the target hook TARGET_ASM_LOOP_ALIGN_MAX_SKIP. This means the loop
isn't aligned to a 32 byte boundary.
While it is important to ultimately fix the code generation bug to once again
generate the BDNZ instruction, it may be more involved in fixing the bug. So,
I decided to rewrite the test to be simpler, and the resulting code fits within
the 4-8 instruction window the target hook is looking for.
I have tested this on a little endian power8 system, and a big endian power8
system, doing both bootstrap builds and regression tests. The only change to
the regression test is that loop_align.c now passes on little endian 64-bit and
big endian 64-bit (big endian 32-bit did not fail with the new changes). Can I
install this on the trunk? Back ports to GCC 7/6 are not needed, since the
original code works on those systems.
[gcc/testsuite]
2018-01-24 Michael Meissner <[email protected]>
PR target/81550
* gcc.target/powerpc/loop_align.c: Rewrite test so that the loop
remains small enough that it tests the alignment of loops
specified by the target hook TARGET_ASM_LOOP_ALIGN_MAX_SKIP.
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: [email protected], phone: +1 (978) 899-4797
Index: gcc/testsuite/gcc.target/powerpc/loop_align.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/loop_align.c (revision 256992)
+++ gcc/testsuite/gcc.target/powerpc/loop_align.c (working copy)
@@ -1,11 +1,16 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* powerpc-ibm-aix* } } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } {
"-mcpu=power7" } } */
-/* { dg-options "-O2 -mcpu=power7 -falign-functions=16" } */
+/* { dg-options "-O2 -mcpu=power7 -falign-functions=16 -fno-reorder-blocks" }
*/
/* { dg-final { scan-assembler ".p2align 5,,31" } } */
-void f(double *a, double *b, double *c, int n) {
- int i;
+/* This test must be crafted so that the loop is less than 8 insns (and more
+ than 4) in order for the TARGET_ASM_LOOP_ALIGN_MAX_SKIP target hook to fire
+ and align the loop properly. Originally the loop used double, and various
+ optimizations caused the loop to double in size, and fail the test. */
+
+void f(long *a, long *b, long *c, long n) {
+ long i;
for (i=0; i < n; i++)
a[i] = b[i] + c[i];
}