Ping.
> Hello,
>
> 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.
>
> This patch fixes this by replacing operands[2] with the actual second
> operand of the pattern i.e const0_rtx. It also treats thumb1_cbz the
> same as cbranchsi4_insn in thumb1_final_prescan_insn and lets it track
> the condition code state itself.
>
> Ok for master?
>
> Regards
> Senthil
>
> 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.
>
>
> diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
> index 41808e42ab1..ec46cac0e61 100644
> --- a/gcc/config/arm/arm.cc
> +++ b/gcc/config/arm/arm.cc
> @@ -26612,7 +26612,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 db0fab2e1f6..4fa64e42340 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 00000000000..8841629a928
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pr124077.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Os" } */
> +/* { dg-require-effective-target arm_thumb1_ok } */
> +
> +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" } } */