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

--- Comment #21 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Hongtao.liu from comment #19)
> (In reply to H.J. Lu from comment #18)
> > (In reply to Segher Boessenkool from comment #16)
> > > Hi Roger,
> > > 
> > > (In reply to Roger Sayle from comment #15)
> > > > Yes, a COMPARE rtx can be used to set various flags on x86, but many 
> > > > other
> > > > operations also legitimately set and/or use MODE_CC, often in a parallel
> > > > with the primary operation.
> > > 
> > > *Any* MODE_CC setter sets the flags as-if from a compare.  This is what
> > > MODE_CC *is*.
> > > 
> > > Setting something as ne:CC and then using it as somethingelse:CC has no
> > > defined meaning.
> > 
> > This
> > 
> > (parallel [
> >             (set (reg:SI 97) 
> >                 (neg:SI (ltu:SI (reg:CCC 17 flags)
> >                         (const_int 0 [0]))))
> >             (clobber (reg:CC 17 flags))
> >         ])
> > 
> > still won't work correctly if reg:CCC 17 flags is set by a compare of
> > 2 known values.
> 
> I guess Segher means it should be NE instead of LTU in the
> x86_mov<mode>cc_0_m1_neg, since the setters is NE to const 0.

Yes.

>  (ne:CCC (reg:SI 87 [ a_lsm.8 ])
>                     (const_int 0 [0])))
> 
>  (define_expand "x86_mov<mode>cc_0_m1_neg"
>    [(parallel
>      [(set (match_operand:SWI48 0 "register_operand")
> -         (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
> +         (neg:SWI48 (ne:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
>       (clobber (reg:CC FLAGS_REG))])])
> 
> It can pass the PR, but failed pr101617.c, the f1 case.
> 
> generate:
>         testl   %edi, %edi
>         movl    $1, %edx
>         movl    $-1, %eax
>         cmove   %edx, %eax
> 
> origin:
>         negl    %edi
>         sbbl    %eax, %eax
>         orl     $1, %eax

And this is why using a relation (e.g. ltu, an RTX_COMPARE) instead of a
compare (an RTX_BIN_ARITH) as setter cannot work.  The setter and the getter
are modified independently by very many parts of the compiler, and then
everything falls apart.

The only valid things on the RHS of a MODE_CC set are a reg, a compare, or
an unspec.  Everything else is undefined and problematical as well.

Reply via email to