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

--- Comment #16 from chenglulu <chenglulu at loongson dot cn> ---
(In reply to Xi Ruoyao from comment #15)
> (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.

Is it better to modify it this way?

--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -60,6 +60,7 @@ (define_c_enum "unspec" [
   ;; Stack tie
   UNSPEC_TIE

+  UNSPEC_ANY_DIV
   ;; CRC
   UNSPEC_CRC
   UNSPEC_CRCC
@@ -900,7 +901,7 @@ (define_expand "<optab><mode>3"
                     (match_operand:GPR 2 "register_operand")))]
   ""
 {
- if (GET_MODE (operands[0]) == SImode)
+ if (GET_MODE (operands[0]) == SImode && TARGET_64BIT)
   {
     rtx reg1 = gen_reg_rtx (DImode);
     rtx reg2 = gen_reg_rtx (DImode);
@@ -938,9 +939,12 @@ (define_insn "*<optab><mode>3"
 (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:SI
+          [(subreg:SI
+            (any_div:DI (match_operand:DI 1 "register_operand" "r,r,0")
+                        (match_operand:DI 2 "register_operand" "r,r,r")) 0)]
+         UNSPEC_ANY_DIV)))]
+  "TARGET_64BIT"
 {
   return loongarch_output_division ("<insn>.w<u>\t%0,%1,%2", operands);

Reply via email to