[PATCH] bitintlower: Fix memmove source operand in finish_arith_overflow [PR126939]

Manjunath S Matti <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Bootstrapped and regression tested on powerpc64-linux (-m32/-m64), s390 and
powerpc64le-linux.

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.

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.

The affected code is guarded by bitint_big_endian, and is only reached
for widths whose value needs more limbs than the destination object,
that is huge _BitInt operands of __builtin_{add,sub,mul}_overflow, so
it needs a big-endian target with _BitInt support to be exercised at
all.  It is being hit now that _BitInt is being enabled for powerpc
(PR117584).

Existing coverage is sufficient: on powerpc64 big-endian this fixes
gcc.dg/torture/bitint-93.c and bitint-94.c at -O0 and -O2, and
gcc.dg/torture/bitint-32.c through bitint-37.c at -O0.  No new test is
added.

2026-08-19  Manjunath Matti  <[email protected]>

PR middle-end/126939

gcc/
	* gimple-lower-bitint.cc (bitint_large_huge::finish_arith_overflow):
	Take the address of the memmove source operand.

diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index 52d0acad249..e36534ba13d 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -4594,8 +4594,9 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
 			     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));
+				 build_fold_addr_expr (src),
+				 build_int_cst (size_type_node,
+						obj_nelts * m_limb_size));
 	  insert_before (g);
 	}
       if (orig_obj == NULL_TREE && obj)
-- 
2.52.0
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.