On Thu, Mar 9, 2017 at 4:07 PM, Olivier Hainque <hain...@adacore.com> wrote: > Hello, > > The mainline compiler, configured for powerpc-wrs-vxworks, fails > to handle the simple test below at -O2. > > The failure mode looks like: > > ./gnat1 -Iada/rts opt64_pkg.adb -O2 > ... > opt64_pkg.adb: In function 'Opt64_Pkg.Encode': > opt64_pkg.adb:14:1: error: alignment of array elements is greater than > element size > > The error is spurious, caused by a misinteraction between tree-sra > and tree-switch-conversion. > > SRA first transforms the case statement into: > > Created a replacement for result offset: 0, size: 8: result$1 > ... > > Opt64_Pkg.Encode (const integer x) > { > character result$1; > character result[1:1]; > > <bb 2> [0.00%]: > switch (x_2(D)) <default: <L3> [0.00%], case 1: <L0> [0.00%], case 2: <L1> > [0.00%], case 3: <L2> [0.00%]> > > <L0> [0.00%]: > result$1_13 = MEM[(character[1:1] *)"1"]; > goto <bb 7>; [0.00%] > ... > <L3> [0.00%]: > result$1_14 = MEM[(character[1:1] *)"?"]; > > <bb 7> [0.00%]: > # result$1_10 = PHI <result$1_13(3), result$1_12(4), result$1_11(5), > result$1_14(6)> > MEM[(character[1:1] *)&opt64_pkg__last_hash] = result$1_10; > return; > > with a particularity on the MEM references for loads: their > type are of QI mode with 32bit alignment, from > > build_ref_for_offset (...) > { ... > get_object_alignment_1 (base, &align, &misalign); > ... > if (align != TYPE_ALIGN (exp_type)) > exp_type = build_aligned_type (exp_type, align); > ... > > Indeed, align is assigned through > > get_object_alignment_2 (...) > ... > else if (TREE_CODE (exp) == STRING_CST) > { > /* STRING_CST are the only constant objects we allow to be not > wrapped inside a CONST_DECL. */ > align = TYPE_ALIGN (TREE_TYPE (exp)); > if (CONSTANT_CLASS_P (exp)) > align = (unsigned) CONSTANT_ALIGNMENT (exp, align); > > and rs6000.h has: > > /* Make strings word-aligned so strcpy from constants will be faster. */ > #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ > ... > > Later on, the switch-conversion pass quicks in and decides to make an array > of the possible values assigned to "result". The chosen array element type is > one altered by SRA (QI mode, align 32) and stor-layout complains. > > The over-alignment is allowed by SRA on purpose, not to interfere with > vectorisation - see PR65310 & PR50819. > > The attached patch is a suggestion to fix this by teaching switch-conversion > about this possibility and adjust the alignment back to the first value lower > than size for the type used for array elements. > > Bootstrapped and regtested on x86_64-linux. Verified that it cures the > spurious error on powerpc and that the resolution to PR50819 isn't affected. > > The change triggering the misinteraction is the one allowing SRA to produce > types with larger alignments, introduced on Mar 2015 for PR 65310, to fix a > regression a previous change on the PR exposed against PR 50819. > > We see the the spurious error on our gcc-6 based compilers, not on those based > on gcc-4.9 so this qualifies as a regression I think. > > OK to commit ?
I think a simpler fix, doing type = TYPE_MAIN_VARIANT (type); should work equally well. Richard. > Thanks in advance! > > With Kind Regards, > > Olivier > > 2017-03-09 Olivier Hainque <hain...@adacore.com> > > * tree-switch-conversion (array_value_type): Start by adjusting the > alignment of the candidate type back to a value lower than its size. > > gnat.dg/ > * opt64.ad[bs], opt64_pkg.ad[bs]: New test. > > -- > > package body Opt64_PKG is > > procedure Encode (X : Integer) is > result : Hash; > begin > case X is > when 1 => result := "1"; > when 2 => result := "2"; > when 3 => result := "3"; > when others => Result := "?"; > end case; > Last_Hash := Result; > end; > end; > > package Opt64_PKG is > type Hash is new string (1 .. 1); > Last_Hash : Hash; > > procedure Encode (X : Integer); > end; >