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."