https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112374

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rguenth at gcc dot gnu.org

--- Comment #28 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
E.g. on the referenced r14-5076 commit, I'm completely lost in what that
+       {
+       /* In case of a COND_OP (mask, op1, op2, op1) reduction we might have
+          op1 twice (once as definition, once as else) in the same operation.
+          Allow this.  */
+         if (cond_fn_p)
+           {
+             gcall *call = dyn_cast<gcall *> (use_stmt);
+             unsigned else_pos
+               = internal_fn_else_index (internal_fn (op.code));
+
+             for (unsigned int j = 0; j < gimple_call_num_args (call); ++j)
+               {
+                 if (j == else_pos)
+                   continue;
+                 if (gimple_call_arg (call, j) == op.ops[opi])
+                   cnt++;
+               }
+           }
hunk wants to do.  This is in
4103          FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op.ops[opi])
loop which iterates over immediate use statements, but this new stuff doesn't
refer to the immediate use statements at all (op_use_stmt).  So, effectively it
repeats the same stuff unconditionally on the original use_stmt as many times
as there are immediate uses, including GIMPLE_DEBUG statements.
On the original i386-expand.o, I see e.g.
(gdb) p debug_gimple_stmt (use_stmt)
_ifc__247 = .COND_IOR (_346, mask_505, _367, mask_505);
where op.ops[opi] is mask_505, it iterates on the
_ifc__247 = .COND_IOR (_346, mask_505, _367, mask_505);
op_use_stmt statement where it increments cnt together by 1, then on
# DEBUG D#437 => D#438 | mask_505
where it doesn't use op_use_stmt but use_stmt (i.e. the above stmt again) and
increments again by 1 and then because cnt != 1 will fail.

Robin, did you mean to test if (cond_fn_p && op_use_stmt == use_stmt) instead,
or actually
use op_use_stmt instead of use_stmt (and only if it actually is also a call),
or something else?

Reply via email to