On Thu 2024-10-03 14:29:44, Andrew Pinski wrote: > On Thu, Oct 3, 2024 at 7:51 AM Filip Kastl <fka...@suse.cz> wrote: > > > > Hi All, > > > > While toying with the switch conversion GIMPLE pass I noticed that the pass > > generates a dead statement. I wanted to investigate why this happens and > > potentially fix this. However after looking into the part of the pass > > responsible for generating the code in question I still have no idea why the > > dead statement is generated. Can someone more experienced look at this and > > tell me what is going on, please? > > > > Let's say I'm compiling this C testcase > > > > int main() > > { > > switch (a % 4) > > { > > case 0: return 10; > > case 1: return 20; > > case 2: return 30; > > default: return 40; > > } > > } > > > > Since the switch computes a linear function, the linear transformation > > feature > > of switch conversion triggers -- with cofficients A = 10 and B = 10 in this > > case. This is the relevant GCC source code. It is a part of the > > switch_conversion::build_one_array () function: > > > > if (dump_file && coeff_a.to_uhwi () > 0) > > fprintf (dump_file, "Linear transformation with A = %" PRId64 > > " and B = %" PRId64 "\n", coeff_a.to_shwi (), > > coeff_b.to_shwi ()); > > > > /* We must use type of constructor values. */ > > gimple_seq seq = NULL; > > tree tmp = gimple_convert (&seq, type, m_index_expr); > > tree tmp2 = gimple_build (&seq, MULT_EXPR, type, > > wide_int_to_tree (type, coeff_a), tmp); > > tree tmp3 = gimple_build (&seq, PLUS_EXPR, type, tmp2, > > wide_int_to_tree (type, coeff_b)); > > tree tmp4 = gimple_convert (&seq, TREE_TYPE (name), tmp3); > > gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); > > load = gimple_build_assign (name, tmp4); > > Both gimple_build uses gimple_simplify to build the gimple (which does > simplifications). > Note gimple_convert just calls gimple_build (unless it is already the > correct type). > You can find which simplifications is done by adding the `-folding` > option to the dump option (note this option is not documented but that > is PR 114892).
Ah ok, this explains it. Thanks a lot, Andrew! Filip Kastl > > Thanks, > Andrew Pinski > > > > > > Before this code is run, the GIMPLE of the basic block in question looks > > like > > this (output of debug_bb (m_switch_bb)): > > > > a.0_1 = a; > > _2 = a.0_1 % 4; > > _9 = (unsigned int) _2; > > switch (_2) <default: <L4> [INV], case 0: <L6> [INV], case 1: <L1> [INV], > > case 2: <L2> [INV], case 3: <L3> [INV]> > > > > What I would expect to see is something like this (also output of debug_bb > > () > > but this time after the code I listed was run): > > > > a.0_1 = a; > > _2 = a.0_1 % 4; > > _9 = (unsigned int) _2; > > _7 = (unsigned int) _2; > > _8 = 10 * _7; > > _10 = _8 + 10; > > switch (_2) <default: <L4> [INV], case 0: <L6> [INV], case 1: <L1> [INV], > > case 2: <L2> [INV], case 3: <L3> [INV]> > > > > but what I instead see is this: > > > > a.0_1 = a; > > _2 = a.0_1 % 4; > > _9 = (unsigned int) _2; > > _7 = (unsigned int) _2; > > _6 = 10 * _7; > > _5 = _7 + 1; > > _10 = _5 * 10; > > _11 = (int) _10; > > switch (_2) <default: <L4> [INV], case 0: <L6> [INV], case 1: <L1> [INV], > > case 2: <L2> [INV], case 3: <L3> [INV]> > > > > The first thing I noticed is that there are two multiplications instead of > > one > > and that the result of one of them doesn't get used (this redundant > > multiplication is the original reason I started looking into this). But > > there > > is also a cast to int that I don't see how the GCC code created and the > > order > > of the non-dead multiplication and addition is switched and the added > > constant > > (coefficient B) is 1 instead of 10 (which is correct but just not what I > > expect > > from reading the code). > > > > What am I not seeing here? Does gsi_insert_seq_before do some > > optimizations on > > the seq it inserts? > > > > Thanks, > > Filip Kastl