Hi all, When using the short Thumb2 IT blocks we want to also restrict ifcvt so that it will not end up generating a number of back-to-back cond_execs that will later end up being back to back single-instruction IT blocks. Branching over them should be a better choice.
This patch implements that by setting max_insns_skipped to 1 when arm_restrict_it. With this patch, I've seen GCC replace a number of sequences in places like SPEC2006 from: it eq moveq r1, r5 it ne movne r1, r10 it eq moveq r8, r4 to a branch over them. Bootstrapped and tested on arm. Ok for trunk? Thanks, Kyrill 2015-05-18 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * config/arm/arm.c (arm_option_params_internal): When optimising for speed set max_insns_skipped when arm_restrict_it. 2015-05-18 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * gcc.target/arm/short-it-ifcvt-1.c: New test. * gcc.target/arm/short-it-ifcvt-2.c: Likewise.
commit f23178a102c3f35d42d36e14ed69d6b03f5cd300 Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com> Date: Thu May 14 12:08:14 2015 +0100 [ARM] Restrict MAX_CONDITIONAL_EXECUTE when -mrestrict-it is in place diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3f1e48a..6b570af 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2770,7 +2770,10 @@ arm_option_params_internal (struct gcc_options *opts) max_insns_skipped = opts->x_arm_restrict_it ? 1 : 4; } else - max_insns_skipped = current_tune->max_insns_skipped; + /* When -mrestrict-it is in use tone down the if-conversion. */ + max_insns_skipped + = (TREE_TARGET_THUMB2 (opts) && opts->x_arm_restrict_it) + ? 1 : current_tune->max_insns_skipped; } /* Reset options between modes that the user has specified. */ diff --git a/gcc/testsuite/gcc.target/arm/short-it-ifcvt-1.c b/gcc/testsuite/gcc.target/arm/short-it-ifcvt-1.c new file mode 100644 index 0000000..f3d29b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/short-it-ifcvt-1.c @@ -0,0 +1,23 @@ +/* Test that ifcvt is not being too aggressive when -mrestrict-it. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mrestrict-it" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ + +int +f1(int x, int y, int z) +{ + if (x > 100) + { + x++; + z = -z; + } + else + { + x = -x; + y = -y; + z = 1; + } + return x + y + z; +} + +/* { dg-final { scan-assembler "b(gt|le)" } } */ diff --git a/gcc/testsuite/gcc.target/arm/short-it-ifcvt-2.c b/gcc/testsuite/gcc.target/arm/short-it-ifcvt-2.c new file mode 100644 index 0000000..9ac8153 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/short-it-ifcvt-2.c @@ -0,0 +1,21 @@ +/* Test that ifcvt is not being too aggressive when -mrestrict-it. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mrestrict-it" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ + +int +f1(int x, int y, int z) +{ + if (x > 100) + { + x++; + z = -z; + } + else + { + x = -x; + y = -y; + } + return x + y + z; +} +/* { dg-final { scan-assembler "b(gt|le)" } } */