diff options
| -rw-r--r-- | gcc/config/loongarch/loongarch.cc | 39 | ||||
| -rw-r--r-- | gcc/config/loongarch/loongarch.md | 10 | ||||
| -rw-r--r-- | 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 4e53635..4a9604e 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 ba66888..e23c973 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 0000000..d20bd38 --- /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); + } +} + |
