On Tue, Feb 23, 2016 at 11:39 AM, Dmytro Sheyko <dmytro.she...@gmail.com> wrote: > Hello, > > I am compiling code like this: > > int test(int x, int eq, int lt, int gt) { > return x < 2000 ? lt : x > 2000 ? gt : eq; > } > > and expect that compiler would generate one CMP instruction for both > comparisons: > > cmpl $2000, %edi > jl .L37 > jne .L38 > ... > > however result is quite different: > > cmpl $1999, %edi > jle .L37 > cmpl $2000, %edi > jne .L38 > > For some reason, compiler transforms (x < 2000) to (x <= 1999). Though > such transformation looks semantically legal, not sure it is really > necessary here. Especially taking into account that it impedes > subsequent optimizations. > > It seems that 'maybe_canonicalize_comparison' from gcc/fold-const.c is > responsible for such transformation (I am using 5.3.0, as for trunk it > seems that some part of such logic is moved to gcc/match.pd). > > I wonder why such transformation is necessary. What benefits does it offer?
Canonicalization with x <= 1999 and thus simplifying of x < 2000 && x <= 1999 for example. I don't see how we can get a single compare at GIMPLE so it must be RTL maybe in compare-elim.c doing the recognition. Richard. > Thank you, > Dmytro