http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52173
--- Comment #10 from rguenther at suse dot de <rguenther at suse dot de> 2012-09-20 07:43:56 UTC --- On Wed, 19 Sep 2012, aldyh at gcc dot gnu.org wrote: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52173 > > Aldy Hernandez <aldyh at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |amacleod at redhat dot com, > | |dnovillo at gcc dot > | |gnu.org, rguenth at gcc dot > | |gnu.org > > --- Comment #9 from Aldy Hernandez <aldyh at gcc dot gnu.org> 2012-09-19 > 19:44:14 UTC --- > Richi, Diego. Perhaps you can shed light on this. > > Here we have a loop unroll that triggers a "virtual def operand missing..." > for > a GIMPLE_TRANSACTION: > > int vec[500]; > > void func() > { > __transaction_relaxed > { > vec[123] = 456; > } > } > > main() > { > int i; > for(i = 0; i < 10; ++i) > func(); > } > > The unroller wants to unroll into something like: > > <bb 2>: > # .MEM_6 = VDEF <.MEM_13> > __transaction_relaxed <-- PROBLEMATIC INSN (VDEF's) > > <bb 3>: > # .MEM_9 = VDEF <.MEM_59> > vec[123] = 456; > # .MEM_2 = VDEF <.MEM_9> > __builtin__ITM_commitTransaction (); > > <bb 4>: > ivtmp_14 = 9; > # .MEM_11 = VDEF <.MEM_13> > __transaction_relaxed > > <bb 5>: > # .MEM_18 = VDEF <.MEM_59> > vec[123] = 456; > # .MEM_19 = VDEF <.MEM_18> > __builtin__ITM_commitTransaction (); > > etc etc etc. > > Putting aside how incredibly inefficient this is... (We should be duplicating > the vector store, not the entire transaction)... > > The problem here is that, after unrolling, the VDEF of the problematic insn is > .MEM_6, but the DEF_OP of the insn is .MEM_59. So gimple_vdef() != > gimple_vdef_op() and we trigger a "virtual def operand missing for stmt". > > The problem is that the unroller's call to gimple_duplicate_bb() will make a > copy of the problematic instruction, maintaining its gimple_vdef, but changing > all its def_ops from under us, thus making gimple_vdef() != gimple_vdef_op(). Setting a DEF will change the vdef. If it does not, the stmt was not updated properly. > Before loop unrolling we have this snippet that is about to be unrolled: > > <bb 3>: > # .MEM_13 = PHI <.MEM_8(6), .MEM_3(D)(2)> > # ivtmp_1 = PHI <ivtmp_10(6), 10(2)> > # .MEM_6 = VDEF <.MEM_13> > __transaction_relaxed > > After loop unrolling the above remains unchanged, but the following is > inserted > *before* bb 3. [Note, the following is after update_ssa(TODO_update_ssa), but > before cleanup_tree_cfg() for clarity.] > > <bb 8>: > # .MEM_12 = PHI <.MEM_3(D)(2)> > # ivtmp_5 = PHI <10(2)> > # .MEM_6 = VDEF <.MEM_13> <-- *************************** --> > ^^^^^^^^^^^^ <-- shouldn't this be <.MEM_12> ????? > <-- *************************** --> Yes. > __transaction_relaxed > ... > ...more unrolling > ... > <bb 40>: > # .MEM_57 = PHI <.MEM_8(39)> > # ivtmp_58 = PHI <ivtmp_10(39)> > # .MEM_53 = VDEF <.MEM_13> <-- ************************** --> > <-- shouldn't this be <.MEM_57> ???? > <-- ************************** --> Yes. > __transaction_relaxed > ... > ... > <bb 3> > .. > > Notice that both BB8 and BB40 invalidate MEM_13 in its virtual definition. > Shouldn't the VDEF<.MEM_13> be rewritten as I have indicated above? > Especially > since now .MEM_13 is defined much further down in bb 3: > > <bb 8> > # invalidates VDEF<.MEM_13> > ... > <bb 40> > # invalidates VDEF<.MEM_13> > .. > <bb 3> > # define .MEM_13 = .... > > It seems gimple_duplicate_bb() renames all the phis and the operands, but does > not update the VDEF's for the transaction. Gimple_duplicate_bb() says it > doesn't maintain SSA form, so I assume this in on purpose (?). So how is this > supposed to be cleaned up? Or is this even the problem? The problem must be in the IL before unrolling I believe. Richard.