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.
---
 gcc/config/m68k/m68k.md                 | 20 ++++++++++++--------
 gcc/testsuite/gcc.dg/torture/pr126121.c | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr126121.c

diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index e77ac13cf1b..227399feeee 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -5387,7 +5387,8 @@ (define_expand "bswapsi2"
 (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"
 (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 "*bclrdreg"
 (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"
 (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 00000000000..cea2c4eda65
--- /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 ();
+}
+  
-- 
2.55.0


-- 
Andreas Schwab, [email protected]
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

Reply via email to