Sorry for the extra-long delay on this one.
"Steve Ellcey " <[email protected]> writes:
> The gcc.target/octeon-bbit-2.c is failing with -Os because that optimization
> level does not do whichever optimization it is that results in a bbit instead
> of a bbit[01]l. I would like to skip this test for -Os the way it already
> gets
> skipped for -O0.
The point of the test is that BBIT[01]L doesn't exist; there aren't any
branch-likely variants of BBIT[01]. So we wanted to check that we could
still use branch-likely instructions for g(), but wouldn't ever generate
the invalid BBIT[01]L for the similarly-structured f().
The problem is that:
int s = 0;
for (; i & 1; i++)
s += i;
return s;
isn't a very direct way of encouraging branch-likely instructions,
because it requires the i & 1 test to be duplicated. As you say,
we legimately don't do that for -Os. A sufficiently fancy gimple
optimiser could also figure out that the loop iterates at most once
and replace the loop with a non-iterating structure.
The patch below uses a form that doesn't require any code duplication
and which should be a bit more future-proof. Tested on mips64-linux-gnu
and applied.
Richard
gcc/testsuite/
* gcc.target/mips/octeon-bbit-2.c: Restructure loops so that no
code duplication is required. Allow BNE to appear.
Index: gcc/testsuite/gcc.target/mips/octeon-bbit-2.c
===================================================================
--- gcc/testsuite/gcc.target/mips/octeon-bbit-2.c 2012-08-27
17:27:13.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/octeon-bbit-2.c 2012-10-08
21:23:53.416540290 +0100
@@ -4,22 +4,21 @@
/* { dg-final { scan-assembler "\tbbit\[01\]\t" } } */
/* { dg-final { scan-assembler-not "\tbbit\[01\]l\t" } } */
/* { dg-final { scan-assembler "\tbnel\t" } } */
-/* { dg-final { scan-assembler-not "\tbne\t" } } */
NOMIPS16 int
-f (int n, int i)
+f (int *a, int *b)
{
- int s = 0;
- for (; i & 1; i++)
- s += i;
- return s;
+ do
+ if (__builtin_expect (*a & 1, 1))
+ *a = 0;
+ while (++a < b);
}
NOMIPS16 int
-g (int n, int i)
+g (int *a, int *b)
{
- int s = 0;
- for (i = 0; i < n; i++)
- s += i;
- return s;
+ do
+ if (__builtin_expect (*a == 3, 1))
+ *a = 0;
+ while (++a < b);
}