https://gcc.gnu.org/g:976bad6ea48346b0dc31e68b035daa9569724fb5

commit r16-3146-g976bad6ea48346b0dc31e68b035daa9569724fb5
Author: Richard Henderson <richard.hender...@linaro.org>
Date:   Thu Aug 7 04:51:02 2025 +0000

    aarch64: Remove cc clobber from *aarch64_tbz<LTGE><ALLI>1
    
    There is a conflict between aarch64_tbzltdi1 and aarch64_cbltdi
    with respect to pnum_clobbers, resulting in a recog failure:
    
    0xa1fffe fancy_abort(char const*, int, char const*)
            ../../gcc/diagnostics/context.cc:1640
    0x81340e patch_jump_insn
            ../../gcc/cfgrtl.cc:1303
    0xc0eafe redirect_branch_edge
            ../../gcc/cfgrtl.cc:1330
    0xc0f372 cfg_layout_redirect_edge_and_branch
            ../../gcc/cfgrtl.cc:4736
    0xbfb6b9 redirect_edge_and_branch(edge_def*, basic_block_def*)
            ../../gcc/cfghooks.cc:391
    0x1fa9310 try_forward_edges
            ../../gcc/cfgcleanup.cc:561
    0x1fa9310 try_optimize_cfg
            ../../gcc/cfgcleanup.cc:2931
    0x1fa9310 cleanup_cfg(int)
            ../../gcc/cfgcleanup.cc:3143
    0x1fe11e8 rest_of_handle_cse
            ../../gcc/cse.cc:7591
    0x1fe11e8 execute
            ../../gcc/cse.cc:7622
    
    The simplest solution is to remove the clobber from aarch64_tbz.
    This removes the possibility of expansion via TST+B.cond, which
    will merely fall back to TBNZ+B on shorter branches.
    
    gcc:
            PR target/121385
            * config/aarch64/aarch64.md (*aarch64_tbz<LTGE><ALLI>1): Remove
            cc clobber and expansion via TST+Bcond.
    
    gcc/testsuite:
            PR target/121385
            * gcc.target/aarch64/cmpbr-1.c: New.

Diff:
---
 gcc/config/aarch64/aarch64.md              | 26 ++++++--------------------
 gcc/testsuite/gcc.target/aarch64/cmpbr-1.c | 25 +++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6f6e3a93aedd..54389e96f7ce 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -838,27 +838,13 @@
   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
                                 (const_int 0))
                           (label_ref (match_operand 1))
-                          (pc)))
-   (clobber (reg:CC CC_REGNUM))]
+                          (pc)))]
   "!aarch64_track_speculation"
   {
-    if (get_attr_length (insn) == 8)
-      {
-       if (get_attr_far_branch (insn) == FAR_BRANCH_YES)
-         return aarch64_gen_far_branch (operands, 1, "Ltb",
-                                        "<inv_tb>\\t%<w>0, <sizem1>, ");
-       else
-         {
-           char buf[64];
-           uint64_t val = ((uint64_t) 1)
-               << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
-           sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
-           output_asm_insn (buf, operands);
-           return "<bcond>\t%l1";
-         }
-      }
-    else
+    if (get_attr_length (insn) == 4)
       return "<tbz>\t%<w>0, <sizem1>, %l1";
+    return aarch64_gen_far_branch (operands, 1, "Ltb",
+                                  "<inv_tb>\\t%<w>0, <sizem1>, ");
   }
   [(set_attr "type" "branch")
    (set (attr "length")
@@ -870,9 +856,9 @@
                      (const_int 8)))
    (set (attr "far_branch")
        (if_then_else (and (ge (minus (match_dup 1) (pc))
-                              (const_int BRANCH_LEN_N_1MiB))
+                              (const_int BRANCH_LEN_N_32KiB))
                           (lt (minus (match_dup 1) (pc))
-                              (const_int BRANCH_LEN_P_1MiB)))
+                              (const_int BRANCH_LEN_P_32KiB)))
                      (const_string "no")
                      (const_string "yes")))]
 )
diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr-1.c 
b/gcc/testsuite/gcc.target/aarch64/cmpbr-1.c
new file mode 100644
index 000000000000..39f1549edd5d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cmpbr-1.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* PR target/121385 */
+
+#pragma GCC target "+cmpbr"
+
+struct DWstruct {
+    long low, high;
+};
+typedef union {
+    struct DWstruct s;
+    __int128 ll;
+} DWunion;
+__int128 f(__int128 u) {
+    if (u >> 64 == 0)
+     {
+        __int128 t = (__int128)(unsigned long )u * 2;
+        DWunion ww;
+        ww.ll = t;
+        ww.s.high -= 1;
+        if (ww.s.high >= 0)
+            return ww.ll;
+    }
+  return 0;
+}

Reply via email to