[Bug c/126939] New: Fix memmove source operand in finish_arith_overflow at gimple-lower-bitint.cc

"mmatti at linux dot vnet.ibm.com via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126939

            Bug ID: 126939
           Summary: Fix memmove source operand in finish_arith_overflow at
                    gimple-lower-bitint.cc
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mmatti at linux dot vnet.ibm.com
  Target Milestone: ---

finish_arith_overflow builds a memmove call to shift the result of a
double-width multiplication down inside the destination object, on
big-endian targets where the computed value occupies more limbs than
the destination:

   else if (obj && bitint_big_endian && nelts != obj_nelts)
        {
          ...
          tree src = build2 (MEM_REF, atype,
                             build_fold_addr_expr (unshare_expr (obj)), off);
          g = gimple_build_call (fn, 3,
                                 build_fold_addr_expr (unshare_expr (obj)),
                                 src, ...);

The destination argument correctly takes the address of OBJ, but SRC is a
MEM_REF, that is a value of array type, and it is passed directly as memmove's
second argument, which is a pointer.  Wrap it in build_fold_addr_expr so that
the address is passed instead.  Since build_fold_addr_expr of a MEM_REF folds
back to the pointer, no dereference is materialised.

On powerpc64 big-endian gcc.dg/torture/bitint-93.c fails with

  Program received signal SIGSEGV, Segmentation fault.
  __memmove_power7 () at memmove.S:707
  #1  f1 (q=<error reading variable: Cannot access memory at address 0x1>, ...)
      at bitint-93.c:20

Similar failures are observed  

gcc.dg/torture/bitint-32.c      -m64    -O0 only (passes -O2)
gcc.dg/torture/bitint-33.c      -m64    -O0 only (passes -O2)
gcc.dg/torture/bitint-34.c      -m64    -O0 only (passes -O2)
gcc.dg/torture/bitint-35.c      -m64    -O0 only (passes -O2)
gcc.dg/torture/bitint-36.c      -m64    -O0 only (passes -O2)
gcc.dg/torture/bitint-37.c      -m64    -O0 only (passes -O2)
gcc.dg/torture/bitint-93.c      -m64    both -O0 and -O2        
gcc.dg/torture/bitint-94.c      -m64    both -O0 and -O2

Debugging this issues, which points me to a code block in
gcc/gcc/gimple-lower-bitint.cc 

=> tree src = build2 (MEM_REF, atype,
                    build_fold_addr_expr (unshare_expr (obj)), off);
g = gimple_build_call (fn, 3,
                       build_fold_addr_expr (unshare_expr (obj)),
                       src, build_int_cst (size_type_node,
                                           obj_nelts * m_limb_size));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.