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

--- Comment #15 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
(In reply to chenglulu from comment #13)
> (In reply to Xi Ruoyao from comment #12)
> > (In reply to chenglulu from comment #11)
> > > (In reply to Xi Ruoyao from comment #10)
> > > > (In reply to Xi Ruoyao from comment #9)
> > > > 
> > > > >  (define_insn "<optab>di3_fake"
> > > > >    [(set (match_operand:DI 0 "register_operand" "=r,&r,&r")
> > > > > -     (sign_extend:DI
> > > > > -       (any_div:SI (match_operand:DI 1 "register_operand" "r,r,0")
> > > > > -                   (match_operand:DI 2 "register_operand" 
> > > > > "r,r,r"))))]
> > > > > -  ""
> > > > > +     (if_then_else
> > > > > +       (and (eq (match_operand:DI 1 "register_operand" "r,r,0")
> > > > > +                (sign_extend:DI (subreg:SI (match_dup 1) 0)))
> > > > > +            (eq (match_operand:DI 2 "register_operand" "r,r,r")
> > > > > +                (sign_extend:DI (subreg:SI (match_dup 2) 0))))
> > > > > +       (sign_extend:DI
> > > > > +         (any_div:SI (subreg:SI (match_dup 1) 0)
> > > > > +                     (subreg:SI (match_dup 2) 0)))
> > > > > +       (unspec:DI [(const_int 0)] UNSPEC_BAD_DIVW)))]
> > > > 
> > > > With this the compiler will still believe all bad {div,mod}.w{,u}
> > > 
> > > I think this is already defined as UNSPEC. Isn’t the simpler the logic, 
> > > the
> > > better?
> > 
> > Yes, I think we should just use 4 different UNSPEC_ values and the simple
> > version.  But I've not find a way to use 4 different UNSPEC_ values in the
> > RTL template except duplicating everything 4 times...
> 
> I still have a question that I don't quite understand, that is, why that the
> four generated strings are equivalent when using an UNSPEC name? My template
> names are different, and they will not be automatically matched during
> optimization.???

Oh I get it, you mean

 (define_insn "<optab>di3_fake"
   [(set (match_operand:DI 0 "register_operand" "=r,&r,&r")
        (sign_extend:DI
-         (any_div:SI (match_operand:DI 1 "register_operand" "r,r,0")
-                     (match_operand:DI 2 "register_operand" "r,r,r"))))]
+         (unspec:DI [(any_div:DI
+                       (match_operand:DI 1 "register_operand" "r,r,0")
+                       (match_operand:DI 2 "register_operand" "r,r,r"))]
+                    UNSPEC_ANY_DIV)))]
   ""
 {
   return loongarch_output_division ("<insn>.w<u>\t%0,%1,%2", operands);

Good idea! I think it's better than my stupid hacks :).

I'd been thinking about:

 (define_insn "<optab>di3_fake"
   [(set (match_operand:DI 0 "register_operand" "=r,&r,&r")
        (sign_extend:DI
-         (any_div:SI (match_operand:DI 1 "register_operand" "r,r,0")
-                     (match_operand:DI 2 "register_operand" "r,r,r"))))]
+         (unspec:DI [(match_operand:DI 1 "register_operand" "r,r,0")
+                     (match_operand:DI 2 "register_operand" "r,r,r")]
+                    UNSPEC_ANY_DIV)))]
   ""
 {
   return loongarch_output_division ("<insn>.w<u>\t%0,%1,%2", operands);

and this is just wrong.

Reply via email to