https://gcc.gnu.org/g:cbd06e9f66c2d40ff4af7fa648878eaf32928c18

commit r16-5072-gcbd06e9f66c2d40ff4af7fa648878eaf32928c18
Author: Lulu Cheng <[email protected]>
Date:   Thu Dec 12 16:21:38 2024 +0800

    LoongArch: Implement sge and sgeu.
    
    The original implementation of the function loongarch_extend_comparands
    only prevented op1 from being loaded into the register when op1 was
    const0_rtx.  It has now been modified so that op1 is not loaded into
    the register as long as op1 is an immediate value.  This allows
    slt{u}i to be generated instead of slt{u} if the conditions are met.
    
    gcc/ChangeLog:
    
            * config/loongarch/loongarch.cc
            (loongarch_canonicalize_int_order_test): Support GT GTU LT
            and LTU.
            (loongarch_extend_comparands): Expand the scope of op1 from
            0 to all immediate values.
            * config/loongarch/loongarch.md
            (*sge<u>_<X:mode><GPR:mode>): New template.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/loongarch/sign-extend-3.c: New test.

Diff:
---
 gcc/config/loongarch/loongarch.cc                  | 39 +++++++++++++++-------
 gcc/config/loongarch/loongarch.md                  | 10 ++++++
 gcc/testsuite/gcc.target/loongarch/sign-extend-3.c | 29 ++++++++++++++++
 3 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 4e53635a7b98..4a9604eb1eb0 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -5289,29 +5289,41 @@ loongarch_canonicalize_int_order_test (enum rtx_code 
*code, rtx *cmp1,
   if (loongarch_int_order_operand_ok_p (*code, *cmp1))
     return true;
 
-  if (CONST_INT_P (*cmp1))
     switch (*code)
       {
       case LE:
-       plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
-       if (INTVAL (*cmp1) < plus_one)
+       if (CONST_INT_P (*cmp1))
          {
-           *code = LT;
-           *cmp1 = force_reg (mode, GEN_INT (plus_one));
-           return true;
+           plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
+           if (INTVAL (*cmp1) < plus_one)
+             {
+               *code = LT;
+               *cmp1 = force_reg (mode, GEN_INT (plus_one));
+               return true;
+             }
          }
        break;
 
       case LEU:
-       plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
-       if (plus_one != 0)
+       if (CONST_INT_P (*cmp1))
          {
-           *code = LTU;
-           *cmp1 = force_reg (mode, GEN_INT (plus_one));
-           return true;
+           plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
+           if (plus_one != 0)
+             {
+               *code = LTU;
+               *cmp1 = force_reg (mode, GEN_INT (plus_one));
+               return true;
+             }
          }
        break;
 
+      case GT:
+      case GTU:
+      case LT:
+      case LTU:
+       *cmp1 = force_reg (mode, *cmp1);
+       break;
+
       default:
        break;
       }
@@ -5406,7 +5418,10 @@ loongarch_extend_comparands (rtx_code code, rtx *op0, 
rtx *op1)
       else
        {
          *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
-         if (*op1 != const0_rtx)
+         /* Regardless of whether *op1 is any immediate number, it is not
+            loaded into the register, in order to facilitate the generation
+            of slt{u}i.  */
+         if (!CONST_INT_P (*op1))
            *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1);
        }
     }
diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index ba668880ba56..e23c973c38b2 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -518,6 +518,7 @@
 
 ;; These code iterators allow the signed and unsigned scc operations to use
 ;; the same template.
+(define_code_iterator any_ge [ge geu])
 (define_code_iterator any_gt [gt gtu])
 (define_code_iterator any_lt [lt ltu])
 (define_code_iterator any_le [le leu])
@@ -3530,6 +3531,15 @@
   [(set_attr "type" "slt")
    (set_attr "mode" "<X:MODE>")])
 
+(define_insn "*sge<u>_<X:mode><GPR:mode>"
+  [(set (match_operand:GPR           0 "register_operand" "=r")
+       (any_ge:GPR (match_operand:X 1 "register_operand" " r")
+                   (const_int 1)))]
+  ""
+  "slti<u>\t%0,zero,%1"
+  [(set_attr "type" "slt")
+   (set_attr "mode" "<X:MODE>")])
+
 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
   [(set (match_operand:GPR 0 "register_operand" "=r")
        (any_gt:GPR (match_operand:X 1 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-3.c 
b/gcc/testsuite/gcc.target/loongarch/sign-extend-3.c
new file mode 100644
index 000000000000..d20bd38486f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-3.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -O2" } */
+/* { dg-final { scan-assembler "sltui" } } */
+
+union any {
+  int any_i32;
+};
+
+extern char *opname;
+extern void test1 (int, char *);
+extern int iterms;
+
+void
+test (union any cv)
+{
+  int i, on;
+  int ix = cv.any_i32;
+  for (i = 1; i < iterms; i++)
+    {
+      on = (ix == 0 || ix == 1) ? 0 : 1;
+      if (*opname == '!')
+       {
+         on = !on;
+         ++opname;
+       }
+      test1 (on, opname);
+    }
+}
+

Reply via email to