On Thu, 31 May 2012, Eric Botcazou wrote: > > This fixes PR53501, fold_plusminus_mult_expr does not expect that > > operands have a sign-conversion stripped. So don't call it with > > such arguments. > > > > Bootstrap and regtest pending on x86_64-unknown-linux-gnu. > > > > Richard. > > > > 2012-05-30 Richard Guenther <rguent...@suse.de> > > > > PR middle-end/53501 > > * fold-const.c (fold_binary_loc): Make sure to call > > fold_plusminus_mult_expr with the original sign of operands. > > This pessimizes size computations in Ada for 64-bit targets on the 4.7 branch. > > For the attached testcase, we go from: > > Representation information for unit t (spec) > -------------------------------------------- > > for x'Object_Size use 17179869248; > for x'Value_Size use ((#1 + 8) * 8) ; > for x'Alignment use 4; > for x use record > m at 0 range 0 .. 30; > s at 4 range 0 .. ((#1 * 8)) - 1; > r at bit offset (((#1 + 4) * 8)) size in bits = 31 > b at bit offset ((((#1 + 7) * 8) + 7)) size in bits = 1 > end record; > > to > > Representation information for unit t (spec) > -------------------------------------------- > > for x'Object_Size use 17179869248; > for x'Value_Size use (((#1 + 7) * 8) + 8) ; > for x'Alignment use 4; > for x use record > m at 0 range 0 .. 30; > s at 4 range 0 .. ((#1 * 8)) - 1; > r at bit offset (((#1 + 4) * 8)) size in bits = 31 > b at bit offset ((((#1 + 7) * 8) + 7)) size in bits = 1 > end record; > > with -gnatR3 and I'm not sure to understand what the sign has to do here.
The issue is that fold_plusminus_mult re-writes the multiplication from unsigned to signed for the failing testcase, introducing undefined overflow. Yes, it's possible to make fold_plusminus_mult deal with the situation properly (you can always express the computations in unsigned arithmetic if association simplifies it). I just thought that's not appropriate for the branch, so the simple wrong-code fix was better (the rest is on my TODO for trunk - if you do not beat me to it). Richard.