]> gcc.gnu.org Git - gcc.git/commit
expmed: TRUNCATE value1 if needed in store_bit_field_using_insv
authorYunQiang Su <syq@gcc.gnu.org>
Sun, 28 Apr 2024 16:33:44 +0000 (00:33 +0800)
committerYunQiang Su <syq@debian.org>
Mon, 6 May 2024 04:10:08 +0000 (12:10 +0800)
commit7d5d2b879ae7636ca118fb4f3a08b22705cdeacb
tree8cd054b225ca262d07690118fb86996a8c34ee15
parent70d30dd656957f518b8169a125f6b17f53da8237
expmed: TRUNCATE value1 if needed in store_bit_field_using_insv

PR target/113179.

In `store_bit_field_using_insv`, we just use SUBREG if value_mode
>= op_mode, while in some ports, a sign_extend will be needed,
such as MIPS64:
  If either GPR rs or GPR rt does not contain sign-extended 32-bit
  values (bits 63..31 equal), then the result of the operation is
  UNPREDICTABLE.

The problem happens for the code like:
  struct xx {
        int a:4;
        int b:24;
        int c:3;
        int d:1;
  };

  void xx (struct xx *a, long long b) {
        a->d = b;
  }

In the above code, the hard register contains `b`, may be note well
sign-extended.

gcc/
PR target/113179
* expmed.cc(store_bit_field_using_insv): TRUNCATE value1 if
needed.

gcc/testsuite
PR target/113179
* gcc.target/mips/pr113179.c: New tests.
gcc/expmed.cc
gcc/testsuite/gcc.target/mips/pr113179.c [new file with mode: 0644]
This page took 0.062704 seconds and 6 git commands to generate.