diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2025-08-07 04:51:02 +0000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2025-08-11 23:25:09 +0000 |
commit | 976bad6ea48346b0dc31e68b035daa9569724fb5 (patch) | |
tree | 3cfacda7a3037faa099693e63431be73d2276077 /gcc | |
parent | 5a2d86939c735ca2e9aba68c534bffe763a8f7a6 (diff) | |
download | gcc-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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 26 | ||||
-rw-r--r-- | 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 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; +} |