/* Check that GCC generates Armv8.1-M low over head loop instructions with some less trivial loops and the result is correct. */ /* { dg-do run } */ /* { dg-require-effective-target arm_v8_1_lob_ok } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ /* { dg-options "-march=armv8.1-m.main -mthumb -O3 --save-temps" } */ #include <stdlib.h> #include "lob.h" #define TEST_CODE1 \ { \ for (int i = 0; i < N; i++) \ { \ a[i] = i; \ b[i] = i * 2; \ \ for (int k = 0; k < N; k++) \ { \ MAYBE_LOB; \ c[k] = k / 2; \ } \ c[i] = a[i] - b[i]; \ } \ } #define TEST_CODE2 \ { \ for (int i = 0; i < N / 2; i++) \ { \ MAYBE_LOB; \ if (c[i] % 2 == 0) \ break; \ a[i]++; \ b[i]++; \ } \ } int a1[N]; int b1[N]; int c1[N]; int a2[N]; int b2[N]; int c2[N]; #define MAYBE_LOB void __attribute__((noinline)) loop1 (int *a, int *b, int *c) TEST_CODE1; void __attribute__((noinline)) loop2 (int *a, int *b, int *c) TEST_CODE2; #undef MAYBE_LOB #define MAYBE_LOB NO_LOB void ref1 (int *a, int *b, int *c) TEST_CODE1; void ref2 (int *a, int *b, int *c) TEST_CODE2; void check (void) { for (int i = 0; i < N; i++) { NO_LOB; if (a1[i] != a2[i] && b1[i] != b2[i] && c1[i] != c2[i]) abort (); } } int main (void) { reset_data (a1, b1, c1, N); reset_data (a2, b2, c2, N); loop1 (a1, b1, c1); ref1 (a2, b2, c2); check (); reset_data (a1, b1, c1, N); reset_data (a2, b2, c2, N); loop2 (a1, b1, c1); ref2 (a2, b2, c2); check (); return 0; } /* { dg-final { scan-assembler-times {dls\s\S*,\s\S*} 1 } } */ /* { dg-final { scan-assembler-times {le\slr,\s\S*} 1 } } */