On Thu, Jun 19, 2025 at 05:59:06PM +0800, Yang Yujie wrote: > For targets that have extended bitints, we need to ensure these > are extended before writing to the memory, including via atomic > exchange. > > gcc/c-family/ChangeLog: > > * c-common.cc (resolve_overloaded_atomic_exchange): Extend > _BitInts before atomic exchange if needed. > (resolve_overloaded_atomic_compare_exchange): Same. > --- > gcc/c-family/c-common.cc | 63 +++++++++++++++++++++++++++++++++++----- > 1 file changed, 55 insertions(+), 8 deletions(-) > > diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc > index f71cb2652d5..962e9d2a639 100644 > --- a/gcc/c-family/c-common.cc > +++ b/gcc/c-family/c-common.cc > @@ -8059,11 +8059,35 @@ resolve_overloaded_atomic_exchange (location_t loc, > tree function, > /* Convert new value to required type, and dereference it. > If *p1 type can have padding or may involve floating point which > could e.g. be promoted to wider precision and demoted afterwards, > - state of padding bits might not be preserved. */ > + state of padding bits might not be preserved. > + > + However, as a special case, we still want to preserve the padding > + bits of _BitInt values if the ABI requires them to be extended in > + memory. */ > + > build_indirect_ref (loc, p1, RO_UNARY_STAR); > - p1 = build2_loc (loc, MEM_REF, I_type, > - build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1), > - build_zero_cst (TREE_TYPE (p1))); > + > + tree p1type = TREE_TYPE (p1); > + bool bitint_extended_p = false; > + if (TREE_CODE (TREE_TYPE (p1type)) == BITINT_TYPE) > + { > + struct bitint_info info; > + unsigned prec = TYPE_PRECISION (TREE_TYPE (p1type)); > + targetm.c.bitint_type_info (prec, &info);
I'd like to replace this line with bool ok = targetm.c.bitint_type_info (prec, &info); gcc_assert (ok); > + bitint_extended_p = info.extended; > + } > + > + if (bitint_extended_p) > + p1 = fold_convert_loc (loc, I_type, > + build2_loc (loc, MEM_REF, TREE_TYPE (p1type), > + p1, build_zero_cst (p1type))); > + /* Otherwise, the padding bits might not be preserved, as stated above. */ > + else > + p1 = build2_loc (loc, MEM_REF, I_type, > + build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1), > + build_zero_cst (p1type)); > + > + > (*params)[1] = p1; > > /* Move memory model to the 3rd position, and end param list. */ > @@ -8143,11 +8167,34 @@ resolve_overloaded_atomic_compare_exchange > (location_t loc, tree function, > /* Convert desired value to required type, and dereference it. > If *p2 type can have padding or may involve floating point which > could e.g. be promoted to wider precision and demoted afterwards, > - state of padding bits might not be preserved. */ > + state of padding bits might not be preserved. > + > + However, as a special case, we still want to preserve the padding > + bits of _BitInt values if the ABI requires them to be extended in > + memory. */ > + > build_indirect_ref (loc, p2, RO_UNARY_STAR); > - p2 = build2_loc (loc, MEM_REF, I_type, > - build1 (VIEW_CONVERT_EXPR, I_type_ptr, p2), > - build_zero_cst (TREE_TYPE (p2))); > + > + tree p2type = TREE_TYPE (p2); > + bool bitint_extended_p = false; > + if (TREE_CODE (TREE_TYPE (p2type)) == BITINT_TYPE) > + { > + struct bitint_info info; > + unsigned prec = TYPE_PRECISION (TREE_TYPE (p2type)); > + targetm.c.bitint_type_info (prec, &info); And here as well. Plus there should be a testcase for both of those cases, using the bitintext.h infrastructure like in gcc.dg/torture/bitint-82.c that FAILs without this patch and succeeds with it. Jakub