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

            Bug ID: 128633
           Summary: [14/15/16/17 Regression] wrong code at -O1: constexpr
                    (true ? s.w : s.w) * 2 on a 33-bit bit-field is
                    evaluated in 33 bits since r9-6136
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---

#include <cstdio>
struct S { unsigned long long w : 33; };
constexpr unsigned long long f(S s) { return (true ? s.w : s.w) * 2; }
int main() { printf("%llu\n", f(S{1ULL << 32})); }

$ g++ -O0 t.cpp && ./a.out
8589934592
$ g++ -O1 t.cpp && ./a.out
0

Expected: 8589934592. The ?: result has type unsigned long long, so 2^32 * 2 =
8589934592. At -O1 cp_fold evaluates f(S{...}) with the constexpr evaluator in
33 bits and gets 0.

Suspected cause: C++ constexpr evaluation of a ?: with bit-field arms keeps the
bit-field precision (first bad 43574e4ff2a, 2019-02-21, c++/89285). Related:
PR122811.

Known to fail: 10.5.0, 11.4.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0, 17.0.

Known to work: 7.5.0, 8.5.0.

-O0 -fsanitize=undefined,address is clean.

gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release

Related: PR122811.

Reply via email to