aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2025-04-30 08:43:51 +0200
committerGeorg-Johann Lay <avr@gjlay.de>2025-04-30 11:01:48 +0200
commite268cb27332a1c39a5fc8426ae368c9878f3f241 (patch)
tree092d04b4851f0125e8bbb317d88c3fc9ca35a97b
parent17695fe9ca15046f32833c345ab2406b7c080416 (diff)
downloadgcc-e268cb27332a1c39a5fc8426ae368c9878f3f241.zip
gcc-e268cb27332a1c39a5fc8426ae368c9878f3f241.tar.gz
gcc-e268cb27332a1c39a5fc8426ae368c9878f3f241.tar.bz2
AVR: target/119989 - Add missing clobbers to xload_<mode>_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_<mode>_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)
-rw-r--r--gcc/config/avr/avr.md6
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-1.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-2.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-3.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-flashx-4.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-memx-1.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-memx-2.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-memx-3.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989-memx-4.c7
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr119989.h37
10 files changed, 98 insertions, 1 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 1c4e44d..14b3e77 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -716,8 +716,10 @@
|| avr_load_libgcc_insn_p (insn, ADDR_SPACE_FLASHX, true)"
"#"
"&& reload_completed"
- [(parallel [(set (reg:MOVMODE REG_22)
+ [(parallel [(set (reg:MOVMODE 22)
(match_dup 0))
+ (clobber (reg:QI 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 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 0000000..086d1ea
--- /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 0000000..d053ab9
--- /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 0000000..1a5e8f0
--- /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 0000000..63fb52c
--- /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 0000000..4553517
--- /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 0000000..b28c497
--- /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 0000000..bb20053
--- /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 0000000..05a3ee7
--- /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 0000000..12b5449
--- /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;
+}