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>
This commit is contained in:
Jiahao Xu 2024-12-25 17:59:36 +08:00 committed by Lulu Cheng
parent 509df13fbf
commit 81d4707a00
4 changed files with 61 additions and 0 deletions

View file

@ -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")

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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]
}}]
}