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 (); +} +
