From 4dc40eddbe69566869f7aafb78c31c4850b8aeb7 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Wed, 30 Apr 2025 08:43:51 +0200 Subject: [PATCH] AVR: target/119989 - Add missing clobbers to xload__libgcc. libgcc's __xload_1...4 is clobbering Z (and also R21 is some cases), but avr.md had clobbers of respective GPRs only up to reload. Outcome was that code reading from the same __memx address twice could be wrong. This patch adds respective clobbers. Forward-port from 2025-04-30 r14-11703 PR target/119989 gcc/ * config/avr/avr.md (xload__libgcc): Clobber R21, Z. gcc/testsuite/ * gcc.target/avr/torture/pr119989.h: New file. * gcc.target/avr/torture/pr119989-memx-1.c: New test. * gcc.target/avr/torture/pr119989-memx-2.c: New test. * gcc.target/avr/torture/pr119989-memx-3.c: New test. * gcc.target/avr/torture/pr119989-memx-4.c: New test. * gcc.target/avr/torture/pr119989-flashx-1.c: New test. * gcc.target/avr/torture/pr119989-flashx-2.c: New test. * gcc.target/avr/torture/pr119989-flashx-3.c: New test. * gcc.target/avr/torture/pr119989-flashx-4.c: New test. (cherry picked from commit 1ca1c1fc3b58ae5e1d3db4f5a2014132fe69f82a) --- gcc/config/avr/avr.md | 4 ++ .../avr/torture/pr119989-flashx-1.c | 7 ++++ .../avr/torture/pr119989-flashx-2.c | 7 ++++ .../avr/torture/pr119989-flashx-3.c | 7 ++++ .../avr/torture/pr119989-flashx-4.c | 7 ++++ .../gcc.target/avr/torture/pr119989-memx-1.c | 7 ++++ .../gcc.target/avr/torture/pr119989-memx-2.c | 7 ++++ .../gcc.target/avr/torture/pr119989-memx-3.c | 7 ++++ .../gcc.target/avr/torture/pr119989-memx-4.c | 7 ++++ .../gcc.target/avr/torture/pr119989.h | 37 +++++++++++++++++++ 10 files changed, 97 insertions(+) create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-1.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-2.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-3.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-4.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-memx-1.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-memx-2.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-memx-3.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989-memx-4.c create mode 100644 gcc/testsuite/gcc.target/avr/torture/pr119989.h diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 1c4e44dcfe4..01b8e4bce4c 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -718,6 +718,8 @@ "&& reload_completed" [(parallel [(set (reg:MOVMODE REG_22) (match_dup 0)) + (clobber (reg:QI REG_21)) + (clobber (reg:HI REG_Z)) (clobber (reg:CC REG_CC))])] { operands[0] = SET_SRC (single_set (curr_insn)); @@ -727,6 +729,8 @@ [(set (reg:MOVMODE REG_22) (mem:MOVMODE (lo_sum:PSI (reg:QI REG_21) (reg:HI REG_Z)))) + (clobber (reg:QI REG_21)) + (clobber (reg:HI REG_Z)) (clobber (reg:CC REG_CC))] "reload_completed && (avr_load_libgcc_insn_p (insn, ADDR_SPACE_MEMX, true) diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-1.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-1.c new file mode 100644 index 00000000000..086d1eab0e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-1.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +typedef __UINT8_TYPE__ TYP; +#define AS __flashx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-2.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-2.c new file mode 100644 index 00000000000..d053ab9c109 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-2.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +typedef __UINT16_TYPE__ TYP; +#define AS __flashx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-3.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-3.c new file mode 100644 index 00000000000..1a5e8f0488a --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-3.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +__extension__ typedef __uint24 TYP; +#define AS __flashx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-4.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-4.c new file mode 100644 index 00000000000..63fb52c146f --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-4.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +typedef __UINT32_TYPE__ TYP; +#define AS __flashx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-1.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-1.c new file mode 100644 index 00000000000..45535178bdb --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-1.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +typedef __UINT8_TYPE__ TYP; +#define AS __memx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-2.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-2.c new file mode 100644 index 00000000000..b28c4977518 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-2.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +typedef __UINT16_TYPE__ TYP; +#define AS __memx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-3.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-3.c new file mode 100644 index 00000000000..bb20053c157 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-3.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +__extension__ typedef __uint24 TYP; +#define AS __memx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-4.c b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-4.c new file mode 100644 index 00000000000..05a3ee7438e --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989-memx-4.c @@ -0,0 +1,7 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-additional-options "-std=gnu99" } */ + +typedef __UINT32_TYPE__ TYP; +#define AS __memx + +#include "pr119989.h" diff --git a/gcc/testsuite/gcc.target/avr/torture/pr119989.h b/gcc/testsuite/gcc.target/avr/torture/pr119989.h new file mode 100644 index 00000000000..12b5449b7c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr119989.h @@ -0,0 +1,37 @@ +const AS TYP some_data[] = { 1, 2, 3, 4, 5 }; +const AS TYP *IP; + +TYP DT, a, b; + +__attribute__((noipa)) +void do_test1 (void) +{ + DT = *IP; + DT = *IP--; +} + +__attribute__((noipa)) +void do_test2 (void) +{ + DT = *IP; + __asm volatile ("" ::: "memory"); // Prevents unwanted optimization + DT = *IP--; +} + +TYP difference(void) +{ + IP = &some_data[3]; + do_test1(); + a = DT; + IP = &some_data[3]; + do_test2(); + b = DT; + return a - b; // Expected: 0 +} + +int main (void) +{ + if (difference () != 0) + __builtin_exit (__LINE__); + return 0; +} -- 2.47.2