aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiahao Xu <xujiahao@loongson.cn>2024-12-25 17:59:36 +0800
committerLulu Cheng <chenglulu@loongson.cn>2024-12-31 17:36:03 +0800
commit81d4707a00a2d74a9caf2d806e5b0ebe13e1247c (patch)
tree8f77c944e20710f36fa50c21775848becbf2c141
parent509df13fbf0b3544cd39a9e0a5de11ce841bb185 (diff)
downloadgcc-81d4707a00a2d74a9caf2d806e5b0ebe13e1247c.zip
gcc-81d4707a00a2d74a9caf2d806e5b0ebe13e1247c.tar.gz
gcc-81d4707a00a2d74a9caf2d806e5b0ebe13e1247c.tar.bz2
LoongArch: Implement vector cbranch optab for LSX and LASX
In order to support vectorization of loops with multiple exits, this patch adds the implementation of the conditional branch optab for LoongArch LSX/LASX instructions. This patch causes the gen-vect-{2,25}.c tests to fail. This is because the support for vectorizing loops with multiple exits has vectorized the loop checking the results. The failure is due to an issue in the test case's own implementation. gcc/ChangeLog: * config/loongarch/simd.md (cbranch<mode>4): New expander. gcc/testsuite/ChangeLog: * lib/target-supports.exp (check_effective_target_vect_early_break_hw, check_effective_target_vect_early_break): Support LoongArch LSX. * gcc.target/loongarch/vector/lasx/lasx-vseteqz.c: New test. * gcc.target/loongarch/vector/lsx/lsx-vseteqz.c: New test. Co-authored-by: Deng Jianbo <dengjianbo@loongson.cn>
-rw-r--r--gcc/config/loongarch/simd.md30
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vseteqz.c14
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vseteqz.c15
-rw-r--r--gcc/testsuite/lib/target-supports.exp2
4 files changed, 61 insertions, 0 deletions
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index fc3d98a..4d00690 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -516,6 +516,36 @@
DONE;
})
+;; cbranch
+(define_expand "cbranch<mode>4"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "equality_operator"
+ [(match_operand:IVEC 1 "register_operand")
+ (match_operand:IVEC 2 "reg_or_vector_same_val_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+{
+ RTX_CODE code = GET_CODE (operands[0]);
+ rtx tmp = operands[1];
+ rtx const0 = CONST0_RTX (SImode);
+
+ /* If comparing against a non-zero vector we have to do a comparison first
+ so we can have a != 0 comparison with the result. */
+ if (operands[2] != CONST0_RTX (<MODE>mode))
+ {
+ tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_xor<mode>3 (tmp, operands[1], operands[2]));
+ }
+
+ if (code == NE)
+ emit_jump_insn (gen_<simd_isa>_<x>bnz_v_b (operands[3], tmp, const0));
+ else
+ emit_jump_insn (gen_<simd_isa>_<x>bz_v_b (operands[3], tmp, const0));
+ DONE;
+})
+
; The LoongArch SX Instructions.
(include "lsx.md")
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vseteqz.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vseteqz.c
new file mode 100644
index 0000000..1f69a80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vseteqz.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mlasx" } */
+/* { dg-final { scan-assembler "\txvset.*.v\t" } } */
+/* { dg-final { scan-assembler "bcnez" } } */
+
+int
+foo (int N)
+{
+ for (int i = 0; i <= N; i++)
+ if (i * i == N)
+ return i;
+ return -1;
+}
+
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vseteqz.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vseteqz.c
new file mode 100644
index 0000000..2536bb7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vseteqz.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mlsx" } */
+/* { dg-final { scan-assembler "\tvset.*.v\t" } } */
+/* { dg-final { scan-assembler "bcnez" } } */
+
+int
+foo (int N)
+{
+ for (int i = 0; i <= N; i++)
+ if (i * i == N)
+ return i;
+
+ return -1;
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index a16e953..30ee528 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4431,6 +4431,7 @@ proc check_effective_target_vect_early_break { } {
|| [check_effective_target_sse4]
|| [istarget amdgcn-*-*]
|| [check_effective_target_riscv_v]
+ || [check_effective_target_loongarch_sx]
}}]
}
@@ -4447,6 +4448,7 @@ proc check_effective_target_vect_early_break_hw { } {
|| [check_sse4_hw_available]
|| [istarget amdgcn-*-*]
|| [check_effective_target_riscv_v_ok]
+ || [check_effective_target_loongarch_sx_hw]
}}]
}