On Sat, Mar 2, 2024 at 5:51 PM Iain Buclaw <ibuc...@gdcproject.org> wrote: > > Hi, > > This patch fixes a wrong code issue in the D front-end where lowered > struct comparisons would reinterpret fields with a different (usually > bigger) alignment than the original. Use `build_aligned_type' to > preserve the alignment when casting away for such comparisons. > > Bootstrapped and regression tested on x86_64-linux-gnu/-m32, committed > to mainline, and backported to releases/gcc-13, releases/gcc-12, and > releases/gcc-11. > > Regards, > Iain. > --- > PR d/114171 > > gcc/d/ChangeLog: > > * d-codegen.cc (lower_struct_comparison): Keep alignment of original > type in reinterpret cast for comparison. > > gcc/testsuite/ChangeLog: > > * gdc.dg/torture/pr114171.d: New test. > --- > gcc/d/d-codegen.cc | 1 + > gcc/testsuite/gdc.dg/torture/pr114171.d | 29 +++++++++++++++++++++++++ > 2 files changed, 30 insertions(+) > create mode 100644 gcc/testsuite/gdc.dg/torture/pr114171.d > > diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc > index 5bc233928aa..43d7739f8fc 100644 > --- a/gcc/d/d-codegen.cc > +++ b/gcc/d/d-codegen.cc > @@ -1006,6 +1006,7 @@ lower_struct_comparison (tree_code code, > StructDeclaration *sd, > if (tmode == NULL_TREE) > tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require > ())); > > + tmode = build_aligned_type (tmode, TYPE_ALIGN (stype));
You might also need to build a may_alias variant too. Or make sure the access is using the correct aliasing set. I have not checked if the D front-end does anything special for aliasing sets so I am not sure if that is needed or not but I suspect it is. Thanks, Andrew Pinski > t1ref = build_vconvert (tmode, t1ref); > t2ref = build_vconvert (tmode, t2ref); > > diff --git a/gcc/testsuite/gdc.dg/torture/pr114171.d > b/gcc/testsuite/gdc.dg/torture/pr114171.d > new file mode 100644 > index 00000000000..0f9ffcab916 > --- /dev/null > +++ b/gcc/testsuite/gdc.dg/torture/pr114171.d > @@ -0,0 +1,29 @@ > +// { dg-do run } > +// { dg-additional-options "-mavx" { target avx_runtime } } > +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } > +import gcc.builtins; > + > +struct S1 > +{ > + string label; > +} > + > +struct S2 > +{ > + ulong pad; > + S1 label; > +} > + > +pragma(inline, false) > +auto newitem() > +{ > + void *p = __builtin_malloc(S2.sizeof); > + __builtin_memset(p, 0, S2.sizeof); > + return cast(S2*) p; > +} > + > +int main() > +{ > + auto bn = newitem(); > + return bn.label is S1.init ? 0 : 1; > +} > -- > 2.40.1 >