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); 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