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

Reply via email to