From: Lulu Cheng Date: Thu, 12 Dec 2024 08:21:38 +0000 (+0800) Subject: LoongArch: Implement sge and sgeu. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cbd06e9f66c2d40ff4af7fa648878eaf32928c18;p=thirdparty%2Fgcc.git 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_): New template. gcc/testsuite/ChangeLog: * gcc.target/loongarch/sign-extend-3.c: New test. --- diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 4e53635a7b9..4a9604eb1eb 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 ba668880ba5..e23c973c38b 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" "")]) +(define_insn "*sge_" + [(set (match_operand:GPR 0 "register_operand" "=r") + (any_ge:GPR (match_operand:X 1 "register_operand" " r") + (const_int 1)))] + "" + "slti\t%0,zero,%1" + [(set_attr "type" "slt") + (set_attr "mode" "")]) + (define_insn "*sgt_" [(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 00000000000..d20bd38486f --- /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); + } +} +