On Fri, 14 Dec 2012, Michael Zolotukhin wrote:

I found quite an old bug PR34768 and was thinking of doing what was
suggested there.

Wrong bug number? 34678 probably.

Particularly, I was wondering about adding new subcodes to gimple and
rtl for describing operations with rounding.

Currently, I think the problem could be tackled in the following way:
In gimple we'll need to add a pass that would a) find regions with
constant, compile-time known rounding mode, b) replace operations with
subcodes like plus/minus/div/etc. with the corresponding operations
with rounding (plus_ru, plus_rd etc.), c) remove fesetround calls if
the region doesn't contain instructions that could depend on rounding
mode.
In RTL we'll need to support the instructions with rounding mode, and
also we'll need to be able to somehow emit such instructions.
Probably, we'll need a reverse transformation to insert fesetround
calls around the regions with instructions with rounding - that could
be done by mode_switching pass.

If this approach looks reasonable to you, then there are more questions:
1) What is the best way to represent operations with rounding in
Gimple and RTL? Should we add plus_round and add an attribute to
describe rounding mode, or we should add opcodes for different
rounding modes (plus_round_up, plus_round_down, etc.) - of course,
that should be done for all opcodes that are affected by rounding, not
only plus-opcode.
2) What's the best place to insert the new passes?

Any other input is more than welcome on this.

Dealing with rounding modes sounds like a great (and hard) thing, much needed by some users: here we wrap all operations with asm("":"+m"(x)) currently ("+mx" for sse, for some reason "+g" didn't seem to impact optimization last time I checked), because -frounding-math doesn't really work (simplify_const_unary_operation does constant propagation on sqrt, some rtl pass notices common sub-expressions and merges them despite a change of rounding mode in between, etc).

One thing that seems to make sense but would be way too large a change is to actually represent operations roughly the way they work in C and on x86: + is a function that takes 3 arguments (the 3rd is a global (TLS) variable describing the rounding mode) and has 2 outputs (already an issue in itself): the sum, and a tmp that is just used for exception_flags |= tmp. In some cases, you would know the rounding mode, but in the usual case where you don't, you could still know that (with some flags) a*b+c could be optimized to fma(a,b,c) if and only if * and + have compatible rounding modes (i.e. the same, or one has "don't care"). Things like common sub-expression optimization would work just fine: external function calls or asm might change the global variable, and without them the global variable remains the same and since the operator+ is const...

I don't know how modeling the rounding mode flag as a global variable would work with the mode_switching pass.

Not a realistic suggestion though :-(

Take this message as encouragement to improve this in any way you can :-)

--
Marc Glisse

Reply via email to