[Bug rtl-optimization/121649] [16 Regression] wrong code with _BitInt() conversions (?) at -O2 since r16-2382 (cse)

cvs-commit at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Mar 17 08:30:19 GMT 2026


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121649

--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-15 branch has been updated by Robin Dapp <rdapp@gcc.gnu.org>:

https://gcc.gnu.org/g:422ad1d9300d69477450f05c54eed40639589d82

commit r15-10979-g422ad1d9300d69477450f05c54eed40639589d82
Author: Robin Dapp <rdapp@oss.qualcomm.com>
Date:   Thu Feb 26 18:08:27 2026 +0100

    cse: Only use non-reg vec_select simplifications. [PR121649]

    When merging classes, cse computes new equivalences for constants.
    In the PR we have

      (insn 1173 1172 1174 2 (set (reg:V8QI 33 v1)
             (const_vector:V8QI [
                     (const_int 3 [0x3])
                     (const_int -4 [0xfffffffffffffffc])
                     (const_int 0 [0]) repeated x6
                 ])) "pr121649.c":63:3 1325 {*aarch64_simd_movv8qi}
          (nil))

    of which the second element is selected:

      (insn 1178 1177 1179 2 (set (reg:QI 4 x4)
              (vec_select:QI (reg:V8QI 33 v1)
                  (parallel [
                          (const_int 1 [0x1])
                      ]))) "pr121649.c":63:3 2968 {aarch64_get_lanev8qi}
           (expr_list:REG_EQUAL (const_int -4 [0xfffffffffffffffc])
              (nil)))

    We find (const_int 3 [0x3]) and a few others to be equivalent, among
    them (reg:QI v1).  This is a "fake set" that we create to help CSE extract
    const_vector elements and reuse them.  Element 0 is special, though.
    We lowpart-subreg simplify it to (reg:QI v1) directly and, as the register
    stays the same, consider it equivalent to (reg:V8QI v1).

    Because both equivs refer to the same hard reg, in merge_equiv_classes, the
    old (reg:V8QI) equiv is deleted and replaced by the new (reg:QI) one,
    forgetting that the old equiv had 7 more elements.
    Subsequently, extracting element 1 of a zero-extended QImode register
results
    in "0" instead of the correct "-4".

    Therefore, this patch only uses those vec_select simplification that do
    not directly result in a register.

            PR rtl-optimization/121649

    gcc/ChangeLog:

            * cse.cc (find_sets_in_insn):  Only use non-reg vec_select
            simplifications.

    gcc/testsuite/ChangeLog:

            * gcc.dg/torture/pr121649.c: New test.

    (cherry picked from commit 2a155ceffe663949cdb70805c25b5483fa315863)


More information about the Gcc-bugs mailing list