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

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Georg-Johann Lay from comment #6)
> (In reply to Andrew Pinski from comment #5)
> >       /* Expand X*Y as X&-Y when Y must be zero or one.  */
> > ...
> >           if (bit0_p || bit1_p)
> >             {
> >               bool speed = optimize_insn_for_speed_p ();
> >               int cost = add_cost (speed, mode) + neg_cost (speed, mode);
> >               struct algorithm algorithm;
> >               enum mult_variant variant;
> >               if (CONST_INT_P (op1)
> >                   ? !choose_mult_variant (mode, INTVAL (op1),
> >                                           &algorithm, &variant, cost)
> >                   : cost < mul_cost (speed, mode))
> > 
> > 
> > Note this should have a debug print in dump_file but that is a different
> > story.
> > 
> > So maybe we are not doing the right costs here.
> That place just replaces a multiplication by some other tricks like negate +
> bit_and on the extended mode.  I don't see how tweaking the costs there
> would give a branch-on-bit around the target operation (bit_xor in the
> example).
> 
> You cannot roll back that in the backend by, say, a combine pattern that
> yould read
> 
> (xor:HI (and:HI (neg:HI (sign_extract:HI (subreg:QI (reg:HI) 0)
>                                          (const_int 1)
>                                          (const_int 0))))
>         (reg:HI))
> 
> > Or we should have another choice of how to expand `a * onezero` into
> > `onezero ? a : 0`
> 
> The propblem is that this is just the preparation for the 2nd xor operand to
> be 0u (when the bit is 0) or -1u (when the bit is 1).  What you want is a
> branch depending on the bit, avoiding the 2nd operand altogether.  Just do
> 
> if (bit == 0)
>    goto skip;
> c ^= a;
> skip:;
> 
> instead of:
> 
> // Do crazy things to coax bit == 1 into some operand coax and then
> c ^= coax;
> 
> I don't see where the payload operation (the c ^= a) is in the expr.cc code
> from above, it's just setting up coax.
> 
> And this doesn't only occur with bit == 1 but also with bit == 0.
> And this doesn't only occur wihh bit_xor but also with bit_ior and plus.

I can look into improving this situtation but it won't be until GCC 16's
stage1. RISCV also is looking into having this improved too.

Reply via email to