[gcc r17-1453] ARM: Fix broken Thumb1 CBZ cc tracking [PR124077]
Richard Earnshaw
rearnsha@gcc.gnu.org
Tue Jun 9 16:35:58 GMT 2026
https://gcc.gnu.org/g:2415f291466dc93182b64e6f069dd0015862e70f
commit r17-1453-g2415f291466dc93182b64e6f069dd0015862e70f
Author: Ciprian Arbone <Ciprian.Arbone@microchip.com>
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 <saaadhu@gcc.gnu.org>
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" } } */
More information about the Gcc-cvs
mailing list