On Thu 2024-10-03 14:29:44, Andrew Pinski wrote:
> On Thu, Oct 3, 2024 at 7:51 AM Filip Kastl 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) [INV], case 0: [INV], case 1: [INV],
> > case 2: [INV], case 3: [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) [INV], case 0: [INV], case 1: [INV],
> > case 2: [INV], case 3: [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) [INV], case 0: [INV], case 1: [INV],
> > case 2: [INV], case 3: [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