https://gcc.gnu.org/g:2415f291466dc93182b64e6f069dd0015862e70f
commit r17-1453-g2415f291466dc93182b64e6f069dd0015862e70f Author: Ciprian Arbone <[email protected]> Date: Tue Jun 9 16:31:11 2026 +0100 ARM: Fix broken Thumb1 CBZ cc tracking [PR124077] thumb1_cbz uses operands[2], both when checking if it can reuse the previously set condition code, and when recording the operands that set the current condition code. operands[2] for this pattern is the target label of the jump though, and not the intended second operand of the comparison operator. As the label is unlikely to end up as operands[2], the condition code reuse logic doesn't kick in and causes the redundant CMP instruction described in PR124077. In addition, thumb1_final_prescan_insn also doesn't treat thumb1_cbz as a cbranch and ends up resetting condition code tracking state. Fix by replacing operands[2] with the actual second operand of the pattern i.e const0_rtx. Also treat thumb1_cbz the same as cbranchsi4_insn in thumb1_final_prescan_insn and let it track condition code state itself. gcc/ChangeLog: PR target/124077 * config/arm/arm.cc (thumb1_final_prescan_insn): Also skip condition code update for thumb1_cbz instructions. * config/arm/thumb1.md (thumb1_cbz): Use const0_rtx as the recorded cc_op1 instead of operands[2]. gcc/testsuite/ChangeLog: PR target/124077 * gcc.target/arm/pr124077.c: New test. Co-authored-by: Senthil Kumar Selvaraj <[email protected]> Diff: --- gcc/config/arm/arm.cc | 3 ++- gcc/config/arm/thumb1.md | 4 ++-- gcc/testsuite/gcc.target/arm/pr124077.c | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 971347ab37eb..d24b06a64458 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -26834,7 +26834,8 @@ thumb1_final_prescan_insn (rtx_insn *insn) asm_fprintf (asm_out_file, "%@ 0x%04x\n", INSN_ADDRESSES (INSN_UID (insn))); /* Don't overwrite the previous setter when we get to a cbranch. */ - if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn) + if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn + && INSN_CODE (insn) != CODE_FOR_thumb1_cbz) { enum attr_conds conds; diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md index 611d8b885028..0c704c5d87fc 100644 --- a/gcc/config/arm/thumb1.md +++ b/gcc/config/arm/thumb1.md @@ -1120,7 +1120,7 @@ if (t != NULL_RTX) { if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1]) - || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2])) + || !rtx_equal_p (cfun->machine->thumb1_cc_op1, const0_rtx)) t = NULL_RTX; if (cfun->machine->thumb1_cc_mode == CC_NZmode) { @@ -1135,7 +1135,7 @@ output_asm_insn ("cmp\t%1, #0", operands); cfun->machine->thumb1_cc_insn = insn; cfun->machine->thumb1_cc_op0 = operands[1]; - cfun->machine->thumb1_cc_op1 = operands[2]; + cfun->machine->thumb1_cc_op1 = const0_rtx; cfun->machine->thumb1_cc_mode = CCmode; } else diff --git a/gcc/testsuite/gcc.target/arm/pr124077.c b/gcc/testsuite/gcc.target/arm/pr124077.c new file mode 100644 index 000000000000..ac6005f5c1c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr124077.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-require-effective-target arm_arch_v8m_base_ok } */ +/* { dg-add-options arm_arch_v8m_base } */ + +extern int y; +extern void bar(void); +extern volatile int *p; + +#define FILL p[0] = 1; p[1] = 2; p[2] = 3; p[3] = 4; p[4] = 5; p[5] = 6; p[6] = 7; + +void foo(int x, int z) +{ + y = x & z; + if (y) + { + FILL FILL FILL FILL FILL; + } + else + { + bar(); + } +} + +/* { dg-final { scan-assembler-not "cmp\tr\[0-9\], #0" } } */
