[gcc r17-2286] m68k: Properly model bset/bclr on memory

Andreas Schwab via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:b407be9e4bdc117a59d232a4db9672544c14a40a

commit r17-2286-gb407be9e4bdc117a59d232a4db9672544c14a40a
Author: Andreas Schwab <[email protected]>
Date:   Thu Jul 9 20:24:35 2026 +0200

    m68k: Properly model bset/bclr on memory
    
    When operating on memory the bset and bclr insns use only the low 3 bits
    of the bit number.
    
            PR target/126121
    gcc/
            * config/m68k/m68k.md (bsetmemqi, *bsetmemqi_ext, bclrmemqi)
            (*bclrmemqi_ext): Add AND with 7 around bit number.
    gcc/testsuite/
            * gcc.dg/torture/pr126121.c: New test.

Diff:
---
 gcc/config/m68k/m68k.md                 | 20 ++++++++++++--------
 gcc/testsuite/gcc.dg/torture/pr126121.c | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index e77ac13cf1b7..227399feeee4 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -5387,7 +5387,8 @@
 (define_insn "bsetmemqi"
   [(set (match_operand:QI 0 "memory_operand" "+m")
 	(ior:QI (subreg:QI (ashift:SI (const_int 1)
-		(match_operand:SI 1 "general_operand" "d")) 3)
+		(and:SI (match_operand:SI 1 "general_operand" "d")
+			(const_int 7))) 3)
 	(match_dup 0)))]
   ""
   "bset %1,%0"
@@ -5397,8 +5398,9 @@
 (define_insn "*bsetmemqi_ext"
   [(set (match_operand:QI 0 "memory_operand" "+m")
 	(ior:QI (subreg:QI (ashift:SI (const_int 1)
-	    (match_operator:SI 2 "extend_operator"
-		[(match_operand 1 "general_operand" "d")])) 3)
+	    (and:SI (match_operator:SI 2 "extend_operator"
+			[(match_operand 1 "general_operand" "d")])
+		    (const_int 7))) 3)
 	(match_dup 0)))]
   ""
   "bset %1,%0"
@@ -5438,8 +5440,9 @@
 (define_insn "bclrmemqi"
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
 	(const_int 1)
-	(minus:SI (const_int 7)
-	    (match_operand:SI 1 "general_operand" "d")))
+	(and:SI (minus:SI (const_int 7)
+		    (match_operand:SI 1 "general_operand" "d"))
+		(const_int 7)))
     (const_int 0))]
   ""
   "bclr %1,%0"
@@ -5449,9 +5452,10 @@
 (define_insn "*bclrmemqi_ext"
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
 	(const_int 1)
-	(minus:SI (const_int 7)
-	    (match_operator:SI 2 "extend_operator"
-		[(match_operand 1 "general_operand" "d")])))
+	(and:SI (minus:SI (const_int 7)
+		    (match_operator:SI 2 "extend_operator"
+			[(match_operand 1 "general_operand" "d")]))
+		(const_int 7)))
     (const_int 0))]
   ""
   "bclr %1,%0"
diff --git a/gcc/testsuite/gcc.dg/torture/pr126121.c b/gcc/testsuite/gcc.dg/torture/pr126121.c
new file mode 100644
index 000000000000..cea2c4eda658
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126121.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+__attribute__ ((noipa,noclone,noinline))
+void foo (char *a, int b)
+{
+  char c = 1 << b;
+  *a |= c;
+}
+
+int
+main (void)
+{
+  char a = 0;
+  foo (&a, 1);
+  if (a != 2) __builtin_abort ();
+  foo (&a, __CHAR_BIT__ + 2);
+  if (a != 2) __builtin_abort ();
+}
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.