aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-08-07 04:51:02 +0000
committerRichard Henderson <richard.henderson@linaro.org>2025-08-11 23:25:09 +0000
commit976bad6ea48346b0dc31e68b035daa9569724fb5 (patch)
tree3cfacda7a3037faa099693e63431be73d2276077
parent5a2d86939c735ca2e9aba68c534bffe763a8f7a6 (diff)
downloadgcc-976bad6ea48346b0dc31e68b035daa9569724fb5.zip
gcc-976bad6ea48346b0dc31e68b035daa9569724fb5.tar.gz
gcc-976bad6ea48346b0dc31e68b035daa9569724fb5.tar.bz2
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.
-rw-r--r--gcc/config/aarch64/aarch64.md26
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cmpbr-1.c25
2 files changed, 31 insertions, 20 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6f6e3a9..54389e9 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 0000000..39f1549
--- /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;
+}