Through the test cases, it was found that when performing vectorizations
with the statement "~x|1", the "not" operation can be eliminated for
optimization.
for example:
//test.c
void func (int *restrict a, int *restrict b, int n) {
for (int i = 0; i < n; i++)
b[i] = ~a[i] | 1;
}
before:
xvld $xr1,$r12,32 //r12->a
xvld $xr0,$r12,0
xvnor.v $xr1,$xr1,$xr1
xvnor.v $xr0,$xr0,$xr0
xvbitseti.w $xr1,$xr1,0
xvbitseti.w $xr0,$xr0,0
xvst $xr1,$r13,32 //r13->b
xvst $xr0,$r13,0
...
after:
xvld $xr1,$r12,32
xvld $xr0,$r12,0
xvrepli.w $xr2,1
xvorn.v $xr1,$xr2,$xr1
xvorn.v $xr0,$xr2,$xr0
xvst $xr1,$r13,32
xvst $xr0,$r13,0
...
gcc/ChangeLog:
* config/loongarch/lasx.md: Add support for the same constant
vector on the operand 1 register type.
* config/loongarch/lsx.md: Dito.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/vector/lasx/vect-vorn-andn.c: New test.
* gcc.target/loongarch/vector/lsx/vect-vorn-andn.c: New test.
---
gcc/config/loongarch/lasx.md | 10 ++++++----
gcc/config/loongarch/lsx.md | 4 ++--
.../loongarch/vector/lasx/vect-vorn-andn.c | 14 ++++++++++++++
.../loongarch/vector/lsx/vect-vorn-andn.c | 14 ++++++++++++++
4 files changed, 36 insertions(+), 6 deletions(-)
create mode 100644
gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-vorn-andn.c
create mode 100644
gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-vorn-andn.c
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index d9c057f4c6d..0d91d0b1a56 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -2486,8 +2486,9 @@ (define_insn "lasx_vext2xv_d<u>_b<u>"
;; Extend loongson-sx to loongson-asx.
(define_insn "andn<mode>3"
[(set (match_operand:LASX 0 "register_operand" "=f")
- (and:LASX (not:LASX (match_operand:LASX 2 "register_operand" "f"))
- (match_operand:LASX 1 "register_operand" "f")))]
+ (and:LASX
+ (not:LASX (match_operand:LASX 2 "register_operand" "f"))
+ (match_operand:LASX 1 "reg_or_vector_same_val_operand" "f")))]
"ISA_HAS_LASX"
"xvandn.v\t%u0,%u2,%u1"
[(set_attr "type" "simd_logic")
@@ -3592,8 +3593,9 @@ (define_insn "lasx_xvssrlrn_<hlasxfmt>_<lasxfmt>"
(define_insn "iorn<mode>3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
- (ior:ILASX (not:ILASX (match_operand:ILASX 2 "register_operand" "f"))
- (match_operand:ILASX 1 "register_operand" "f")))]
+ (ior:ILASX
+ (not:ILASX (match_operand:ILASX 2 "register_operand" "f"))
+ (match_operand:ILASX 1 "reg_or_vector_same_val_operand" "f")))]
"ISA_HAS_LASX"
"xvorn.v\t%u0,%u1,%u2"
[(set_attr "type" "simd_logic")
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index d1280ccd415..2c43f21d2b8 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -2036,7 +2036,7 @@ (define_insn_and_split "vec_concatv4sf"
(define_insn "andn<mode>3"
[(set (match_operand:LSX 0 "register_operand" "=f")
(and:LSX (not:LSX (match_operand:LSX 2 "register_operand" "f"))
- (match_operand:LSX 1 "register_operand" "f")))]
+ (match_operand:LSX 1 "reg_or_vector_same_val_operand" "f")))]
"ISA_HAS_LSX"
"vandn.v\t%w0,%w2,%w1"
[(set_attr "type" "simd_logic")
@@ -2704,7 +2704,7 @@ (define_insn "lsx_vssrlrn_<hlsxfmt>_<lsxfmt>"
(define_insn "iorn<mode>3"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(ior:ILSX (not:ILSX (match_operand:ILSX 2 "register_operand" "f"))
- (match_operand:ILSX 1 "register_operand" "f")))]
+ (match_operand:ILSX 1 "reg_or_vector_same_val_operand" "f")))]
"ISA_HAS_LSX"
"vorn.v\t%w0,%w1,%w2"
[(set_attr "type" "simd_logic")
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-vorn-andn.c
b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-vorn-andn.c
new file mode 100644
index 00000000000..efd60267148
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-vorn-andn.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-mabi=lp64d -Ofast -mlasx " } */
+/* { dg-final { scan-assembler-times "xvnor.v" 0 } } */
+/* { dg-final { scan-assembler-times "xvandn.v" 2 } } */
+
+void foo1(int *restrict a, int *restrict b, int n) {
+ for (int i = 0; i < n; i++)
+ b[i] = ~a[i] | 1;
+}
+
+void foo2(int *restrict a, int *restrict b, int n) {
+ for (int i = 0; i < n; i++)
+ b[i] = ~a[i] & ~1;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-vorn-andn.c
b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-vorn-andn.c
new file mode 100644
index 00000000000..01a6520ac3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-vorn-andn.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-mabi=lp64d -Ofast -mlsx " } */
+/* { dg-final { scan-assembler-times "vnor.v" 0 } } */
+/* { dg-final { scan-assembler-times "vandn.v" 2 } } */
+
+void foo1(int *restrict a, int *restrict b, int n) {
+ for (int i = 0; i < n; i++)
+ b[i] = ~a[i] | 1;
+}
+
+void foo2(int *restrict a, int *restrict b, int n) {
+ for (int i = 0; i < n; i++)
+ b[i] = ~a[i] & ~1;
+}
--
2.20.1