A USE or CLOBBER emits nothing, so it should not end a skipped region.
This is what lets the previous patch predicate a return of a value. It
shrinks 15 more gcc.c-torture/compile objects at -O2 on armv6zk, and no
file grows.
Bootstrapped on x86_64-pc-linux-gnu, regression tested on arm-none-eabi.
Assisted-by: Claude Opus 5 (Anthropic)
gcc/ChangeLog:
* config/arm/arm.cc (arm_final_prescan_insn): Skip a bare USE or
CLOBBER in the skipped region.
gcc/testsuite/ChangeLog:
* gcc.target/arm/cond-exec-return-2.c: New test.
Signed-off-by: Dominic P <[email protected]>
---
gcc/config/arm/arm.cc | 3 ++
.../gcc.target/arm/cond-exec-return-2.c | 43 +++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/arm/cond-exec-return-2.c
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 49fe75bcf7d..9a9847d988b 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -25989,6 +25989,9 @@ arm_final_prescan_insn (rtx_insn *insn)
/* Check the instruction is explicitly marked as predicable.
Instructions using or affecting the condition codes are not.
*/
scanbody = PATTERN (this_insn);
+ if (GET_CODE (scanbody) == USE
+ || GET_CODE (scanbody) == CLOBBER)
+ break;
if (!(GET_CODE (scanbody) == SET
|| GET_CODE (scanbody) == PARALLEL)
|| get_attr_predicable (this_insn) != PREDICABLE_YES
diff --git a/gcc/testsuite/gcc.target/arm/cond-exec-return-2.c
b/gcc/testsuite/gcc.target/arm/cond-exec-return-2.c
new file mode 100644
index 00000000000..fac768d79cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cond-exec-return-2.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2 -marm -march=armv6zk -mtune=arm1176jzf-s" } */
+/* { dg-add-options check_function_bodies } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+extern void spin (void) __attribute__ ((noreturn));
+
+/* The marker keeping the return value live sits between the last
+ instruction and the return, so the region is only reachable once a bare
+ USE is skipped. */
+
+/*
+**retval:
+** tst r0, r1
+** mvnne r0, #0
+** bxne lr
+**...
+*/
+int
+retval (int a, int b)
+{
+ if (!(a & b))
+ spin ();
+ return -1;
+}
+
+/*
+**retval2:
+** cmp r1, #4096
+** strcc r1, \[r0\]
+** addcc r0, r1, #1
+** bxcc lr
+**...
+*/
+unsigned
+retval2 (unsigned *p, unsigned n)
+{
+ if (n >= 4096)
+ spin ();
+ *p = n;
+ return n + 1;
+}
--
2.55.0