https://gcc.gnu.org/g:e4f5a5b494ef66edf5b59bf822d08583f41d7e52

commit r15-10397-ge4f5a5b494ef66edf5b59bf822d08583f41d7e52
Author: Georg-Johann Lay <[email protected]>
Date:   Tue Oct 7 17:50:34 2025 +0200

    AVR: target/122187 - Don't clobber recog_data.operand[] in insn out.
    
    avr.cc::avr_out_extr() and avr.cc::avr_out_extr_not()
    changed xop for output, which spoiled the operand for
    the next invokation, running into an assertion.
    
    This patch makes a local copy of the operands.
    
            PR target/122187
    gcc/
            * config/avr/avr.cc (avr_out_extr, avr_out_extr_not):
            Make a local copy of the passed rtx[] operands.
    
    gcc/testsuite/
            * gcc.target/avr/torture/pr122187.c: New test.
    
    (cherry picked from commit 3cbd43d640d6384df85c171a0245488f0adc3145)

Diff:
---
 gcc/config/avr/avr.cc                           | 18 ++++++++++--------
 gcc/testsuite/gcc.target/avr/torture/pr122187.c | 17 +++++++++++++++++
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 9bfacae14adc..cf80d5a15551 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -10212,16 +10212,17 @@ avr_out_insv (rtx_insn *insn, rtx xop[], int *plen)
 }
 
 
-/* Output instructions to extract a bit to 8-bit register XOP[0].
-   The input XOP[1] is a register or an 8-bit MEM in the lower I/O range.
-   XOP[2] is the const_int bit position.  Return "".
+/* Output instructions to extract a bit to 8-bit register OP[0].
+   The input OP[1] is a register or an 8-bit MEM in the lower I/O range.
+   OP[2] is the const_int bit position.  Return "".
 
    PLEN != 0: Set *PLEN to the code length in words.  Don't output anything.
    PLEN == 0: Output instructions.  */
 
 const char *
-avr_out_extr (rtx_insn *insn, rtx xop[], int *plen)
+avr_out_extr (rtx_insn *insn, rtx op[], int *plen)
 {
+  rtx xop[] = { op[0], op[1], op[2] };
   rtx dest = xop[0];
   rtx src = xop[1];
   int bit = INTVAL (xop[2]);
@@ -10279,16 +10280,17 @@ avr_out_extr (rtx_insn *insn, rtx xop[], int *plen)
 }
 
 
-/* Output instructions to extract a negated bit to 8-bit register XOP[0].
-   The input XOP[1] is an 8-bit register or MEM in the lower I/O range.
-   XOP[2] is the const_int bit position.  Return "".
+/* Output instructions to extract a negated bit to 8-bit register OP[0].
+   The input OP[1] is an 8-bit register or MEM in the lower I/O range.
+   OP[2] is the const_int bit position.  Return "".
 
    PLEN != 0: Set *PLEN to the code length in words.  Don't output anything.
    PLEN == 0: Output instructions.  */
 
 const char *
-avr_out_extr_not (rtx_insn * /* insn */, rtx xop[], int *plen)
+avr_out_extr_not (rtx_insn * /* insn */, rtx op[], int *plen)
 {
+  rtx xop[] = { op[0], op[1], op[2] };
   rtx dest = xop[0];
   rtx src = xop[1];
   int bit = INTVAL (xop[2]);
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr122187.c 
b/gcc/testsuite/gcc.target/avr/torture/pr122187.c
new file mode 100644
index 000000000000..0f781eb1a64d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr122187.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options { -std=c99 } } */
+
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT8_TYPE__ uint8_t;
+
+#define PINB (*(volatile uint8_t*) (13 + __AVR_SFR_OFFSET__))
+#define PB1 1
+
+uint16_t fun (void)
+{
+    uint16_t h = 0;
+    for (uint32_t s = 0; s < 0x10000; ++s)
+        h += (PINB >> PB1) & 1;
+    return h;
+}

Reply via email to