]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: target/116953 - ICE due to operands clobber in avr_out_sbxx_branch.
authorGeorg-Johann Lay <avr@gjlay.de>
Thu, 3 Oct 2024 07:34:08 +0000 (09:34 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Fri, 4 Oct 2024 18:28:12 +0000 (20:28 +0200)
PR target/116953
gcc/
* config/avr/avr.cc (avr_out_sbxx_branch): Work on a copy of
the operands rather than on operands itself, which is just
recog_data.operand and may be clobbered by jump_over_one_insn_p.
gcc/testsuite/
* gcc.target/avr/torture/pr116953.c: New test.

gcc/config/avr/avr.cc
gcc/testsuite/gcc.target/avr/torture/pr116953.c [new file with mode: 0644]

index 92013c3845db3a22d38e9cb269bfd3a9080b8fae..735d05b1e7477f5d4f19466e786301ce31dbc887 100644 (file)
@@ -13603,8 +13603,12 @@ avr_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
    Operand 3: label to jump to if the test is true.  */
 
 const char *
-avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
+avr_out_sbxx_branch (rtx_insn *insn, rtx xop[])
 {
+  // jump_over_one_insn_p may call extract on the next insn, clobbering
+  // recog_data.operand.  Hence make a copy of the operands (PR116953).
+  rtx operands[] = { xop[0], xop[1], xop[2], xop[3] };
+
   rtx_code comp = GET_CODE (operands[0]);
   bool long_jump = get_attr_length (insn) >= 4;
   bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr116953.c b/gcc/testsuite/gcc.target/avr/torture/pr116953.c
new file mode 100644 (file)
index 0000000..f8e5a38
--- /dev/null
@@ -0,0 +1,7 @@
+unsigned foo (unsigned x, unsigned y)
+{
+  int i;
+  for (i = 8; i--; x <<= 1)
+    y ^= (x ^ y) & 0x80 ? 79U : 0U;
+  return y;
+}