[llvm] ca66df3 - [LoongArch] Add more and/or/xor patterns for vector types
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 18:30:48 PST 2023
Author: wanglei
Date: 2023-12-01T10:28:41+08:00
New Revision: ca66df3b021017fedf08f0779f5bfc7898dbdd29
URL: https://github.com/llvm/llvm-project/commit/ca66df3b021017fedf08f0779f5bfc7898dbdd29
DIFF: https://github.com/llvm/llvm-project/commit/ca66df3b021017fedf08f0779f5bfc7898dbdd29.diff
LOG: [LoongArch] Add more and/or/xor patterns for vector types
Added:
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll
llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll
llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll
llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll
Modified:
llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 4487152fb42b827..a5652472481aca2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -1184,10 +1184,6 @@ multiclass PatShiftXrUimm<SDPatternOperator OpNode, string Inst> {
(!cast<LAInst>(Inst#"_D") LASX256:$xj, uimm6:$imm)>;
}
-class PatXrXrB<SDPatternOperator OpNode, LAInst Inst>
- : Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)),
- (Inst LASX256:$xj, LASX256:$xk)>;
-
let Predicates = [HasExtLASX] in {
// XVADD_{B/H/W/D}
@@ -1235,13 +1231,20 @@ defm : PatXrXr<srem, "XVMOD">;
defm : PatXrXrU<urem, "XVMOD">;
// XVAND_V
-def : PatXrXrB<and, XVAND_V>;
-// XVNOR_V
-def : PatXrXrB<or, XVOR_V>;
+foreach vt = [v32i8, v16i16, v8i32, v4i64] in
+def : Pat<(and (vt LASX256:$xj), (vt LASX256:$xk)),
+ (XVAND_V LASX256:$xj, LASX256:$xk)>;
+// XVOR_V
+foreach vt = [v32i8, v16i16, v8i32, v4i64] in
+def : Pat<(or (vt LASX256:$xj), (vt LASX256:$xk)),
+ (XVOR_V LASX256:$xj, LASX256:$xk)>;
// XVXOR_V
-def : PatXrXrB<xor, XVXOR_V>;
+foreach vt = [v32i8, v16i16, v8i32, v4i64] in
+def : Pat<(xor (vt LASX256:$xj), (vt LASX256:$xk)),
+ (XVXOR_V LASX256:$xj, LASX256:$xk)>;
// XVNOR_V
-def : Pat<(vnot (or (v32i8 LASX256:$xj), (v32i8 LASX256:$xk))),
+foreach vt = [v32i8, v16i16, v8i32, v4i64] in
+def : Pat<(vnot (or (vt LASX256:$xj), (vt LASX256:$xk))),
(XVNOR_V LASX256:$xj, LASX256:$xk)>;
// XVANDI_B
diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
index deac5015882ddf2..5645ce51194ac7c 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
@@ -1261,10 +1261,6 @@ multiclass PatShiftVrUimm<SDPatternOperator OpNode, string Inst> {
(!cast<LAInst>(Inst#"_D") LSX128:$vj, uimm6:$imm)>;
}
-class PatVrVrB<SDPatternOperator OpNode, LAInst Inst>
- : Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)),
- (Inst LSX128:$vj, LSX128:$vk)>;
-
let Predicates = [HasExtLSX] in {
// VADD_{B/H/W/D}
@@ -1312,13 +1308,20 @@ defm : PatVrVr<srem, "VMOD">;
defm : PatVrVrU<urem, "VMOD">;
// VAND_V
-def : PatVrVrB<and, VAND_V>;
-// VNOR_V
-def : PatVrVrB<or, VOR_V>;
+foreach vt = [v16i8, v8i16, v4i32, v2i64] in
+def : Pat<(and (vt LSX128:$vj), (vt LSX128:$vk)),
+ (VAND_V LSX128:$vj, LSX128:$vk)>;
+// VOR_V
+foreach vt = [v16i8, v8i16, v4i32, v2i64] in
+def : Pat<(or (vt LSX128:$vj), (vt LSX128:$vk)),
+ (VOR_V LSX128:$vj, LSX128:$vk)>;
// VXOR_V
-def : PatVrVrB<xor, VXOR_V>;
+foreach vt = [v16i8, v8i16, v4i32, v2i64] in
+def : Pat<(xor (vt LSX128:$vj), (vt LSX128:$vk)),
+ (VXOR_V LSX128:$vj, LSX128:$vk)>;
// VNOR_V
-def : Pat<(vnot (or (v16i8 LSX128:$vj), (v16i8 LSX128:$vk))),
+foreach vt = [v16i8, v8i16, v4i32, v2i64] in
+def : Pat<(vnot (or (vt LSX128:$vj), (vt LSX128:$vk))),
(VNOR_V LSX128:$vj, LSX128:$vk)>;
// VANDI_B
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll
new file mode 100644
index 000000000000000..98c87cadeeb5a0c
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
+
+define void @and_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v32i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <32 x i8>, ptr %a0
+ %v1 = load <32 x i8>, ptr %a1
+ %v2 = and <32 x i8> %v0, %v1
+ store <32 x i8> %v2, ptr %res
+ ret void
+}
+
+define void @and_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v16i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i16>, ptr %a0
+ %v1 = load <16 x i16>, ptr %a1
+ %v2 = and <16 x i16> %v0, %v1
+ store <16 x i16> %v2, ptr %res
+ ret void
+}
+
+define void @and_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v8i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i32>, ptr %a0
+ %v1 = load <8 x i32>, ptr %a1
+ %v2 = and <8 x i32> %v0, %v1
+ store <8 x i32> %v2, ptr %res
+ ret void
+}
+
+define void @and_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v4i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i64>, ptr %a0
+ %v1 = load <4 x i64>, ptr %a1
+ %v2 = and <4 x i64> %v0, %v1
+ store <4 x i64> %v2, ptr %res
+ ret void
+}
+
+define void @and_u_v32i8(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v32i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvandi.b $xr0, $xr0, 31
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <32 x i8>, ptr %a0
+ %v1 = and <32 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
+ store <32 x i8> %v1, ptr %res
+ ret void
+}
+
+define void @and_u_v16i16(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v16i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.h $xr1, 31
+; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i16>, ptr %a0
+ %v1 = and <16 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
+ store <16 x i16> %v1, ptr %res
+ ret void
+}
+
+define void @and_u_v8i32(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v8i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.w $xr1, 31
+; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i32>, ptr %a0
+ %v1 = and <8 x i32> %v0, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
+ store <8 x i32> %v1, ptr %res
+ ret void
+}
+
+define void @and_u_v4i64(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v4i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.d $xr1, 31
+; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i64>, ptr %a0
+ %v1 = and <4 x i64> %v0, <i64 31, i64 31, i64 31, i64 31>
+ store <4 x i64> %v1, ptr %res
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll
new file mode 100644
index 000000000000000..f37cbf1cefedc46
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
+
+define void @or_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v32i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <32 x i8>, ptr %a0
+ %v1 = load <32 x i8>, ptr %a1
+ %v2 = or <32 x i8> %v0, %v1
+ store <32 x i8> %v2, ptr %res
+ ret void
+}
+
+define void @or_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v16i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i16>, ptr %a0
+ %v1 = load <16 x i16>, ptr %a1
+ %v2 = or <16 x i16> %v0, %v1
+ store <16 x i16> %v2, ptr %res
+ ret void
+}
+
+define void @or_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v8i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i32>, ptr %a0
+ %v1 = load <8 x i32>, ptr %a1
+ %v2 = or <8 x i32> %v0, %v1
+ store <8 x i32> %v2, ptr %res
+ ret void
+}
+
+define void @or_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v4i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i64>, ptr %a0
+ %v1 = load <4 x i64>, ptr %a1
+ %v2 = or <4 x i64> %v0, %v1
+ store <4 x i64> %v2, ptr %res
+ ret void
+}
+
+define void @or_u_v32i8(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v32i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvori.b $xr0, $xr0, 31
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <32 x i8>, ptr %a0
+ %v1 = or <32 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
+ store <32 x i8> %v1, ptr %res
+ ret void
+}
+
+define void @or_u_v16i16(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v16i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.h $xr1, 31
+; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i16>, ptr %a0
+ %v1 = or <16 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
+ store <16 x i16> %v1, ptr %res
+ ret void
+}
+
+define void @or_u_v8i32(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v8i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.w $xr1, 31
+; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i32>, ptr %a0
+ %v1 = or <8 x i32> %v0, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
+ store <8 x i32> %v1, ptr %res
+ ret void
+}
+
+define void @or_u_v4i64(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v4i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.d $xr1, 31
+; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i64>, ptr %a0
+ %v1 = or <4 x i64> %v0, <i64 31, i64 31, i64 31, i64 31>
+ store <4 x i64> %v1, ptr %res
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll
new file mode 100644
index 000000000000000..c2fb1462b7a2501
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
+
+define void @xor_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v32i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <32 x i8>, ptr %a0
+ %v1 = load <32 x i8>, ptr %a1
+ %v2 = xor <32 x i8> %v0, %v1
+ store <32 x i8> %v2, ptr %res
+ ret void
+}
+
+define void @xor_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v16i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i16>, ptr %a0
+ %v1 = load <16 x i16>, ptr %a1
+ %v2 = xor <16 x i16> %v0, %v1
+ store <16 x i16> %v2, ptr %res
+ ret void
+}
+
+define void @xor_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v8i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i32>, ptr %a0
+ %v1 = load <8 x i32>, ptr %a1
+ %v2 = xor <8 x i32> %v0, %v1
+ store <8 x i32> %v2, ptr %res
+ ret void
+}
+
+define void @xor_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v4i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a2, 0
+; CHECK-NEXT: xvld $xr1, $a1, 0
+; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i64>, ptr %a0
+ %v1 = load <4 x i64>, ptr %a1
+ %v2 = xor <4 x i64> %v0, %v1
+ store <4 x i64> %v2, ptr %res
+ ret void
+}
+
+define void @xor_u_v32i8(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v32i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvxori.b $xr0, $xr0, 31
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <32 x i8>, ptr %a0
+ %v1 = xor <32 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
+ store <32 x i8> %v1, ptr %res
+ ret void
+}
+
+define void @xor_u_v16i16(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v16i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.h $xr1, 31
+; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i16>, ptr %a0
+ %v1 = xor <16 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
+ store <16 x i16> %v1, ptr %res
+ ret void
+}
+
+define void @xor_u_v8i32(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v8i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.w $xr1, 31
+; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i32>, ptr %a0
+ %v1 = xor <8 x i32> %v0, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
+ store <8 x i32> %v1, ptr %res
+ ret void
+}
+
+define void @xor_u_v4i64(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v4i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xvld $xr0, $a1, 0
+; CHECK-NEXT: xvrepli.d $xr1, 31
+; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1
+; CHECK-NEXT: xvst $xr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i64>, ptr %a0
+ %v1 = xor <4 x i64> %v0, <i64 31, i64 31, i64 31, i64 31>
+ store <4 x i64> %v1, ptr %res
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll
new file mode 100644
index 000000000000000..523255159a81152
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
+
+define void @and_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v16i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vand.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i8>, ptr %a0
+ %v1 = load <16 x i8>, ptr %a1
+ %v2 = and <16 x i8> %v0, %v1
+ store <16 x i8> %v2, ptr %res
+ ret void
+}
+
+define void @and_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v8i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vand.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i16>, ptr %a0
+ %v1 = load <8 x i16>, ptr %a1
+ %v2 = and <8 x i16> %v0, %v1
+ store <8 x i16> %v2, ptr %res
+ ret void
+}
+
+define void @and_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v4i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vand.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i32>, ptr %a0
+ %v1 = load <4 x i32>, ptr %a1
+ %v2 = and <4 x i32> %v0, %v1
+ store <4 x i32> %v2, ptr %res
+ ret void
+}
+
+define void @and_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: and_v2i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vand.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <2 x i64>, ptr %a0
+ %v1 = load <2 x i64>, ptr %a1
+ %v2 = and <2 x i64> %v0, %v1
+ store <2 x i64> %v2, ptr %res
+ ret void
+}
+
+define void @and_u_v16i8(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v16i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vandi.b $vr0, $vr0, 31
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i8>, ptr %a0
+ %v1 = and <16 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
+ store <16 x i8> %v1, ptr %res
+ ret void
+}
+
+define void @and_u_v8i16(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v8i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.h $vr1, 31
+; CHECK-NEXT: vand.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i16>, ptr %a0
+ %v1 = and <8 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
+ store <8 x i16> %v1, ptr %res
+ ret void
+}
+
+define void @and_u_v4i32(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v4i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.w $vr1, 31
+; CHECK-NEXT: vand.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i32>, ptr %a0
+ %v1 = and <4 x i32> %v0, <i32 31, i32 31, i32 31, i32 31>
+ store <4 x i32> %v1, ptr %res
+ ret void
+}
+
+define void @and_u_v2i64(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: and_u_v2i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.d $vr1, 31
+; CHECK-NEXT: vand.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <2 x i64>, ptr %a0
+ %v1 = and <2 x i64> %v0, <i64 31, i64 31>
+ store <2 x i64> %v1, ptr %res
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll
new file mode 100644
index 000000000000000..f124512acce73de
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
+
+define void @or_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v16i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i8>, ptr %a0
+ %v1 = load <16 x i8>, ptr %a1
+ %v2 = or <16 x i8> %v0, %v1
+ store <16 x i8> %v2, ptr %res
+ ret void
+}
+
+define void @or_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v8i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i16>, ptr %a0
+ %v1 = load <8 x i16>, ptr %a1
+ %v2 = or <8 x i16> %v0, %v1
+ store <8 x i16> %v2, ptr %res
+ ret void
+}
+
+define void @or_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v4i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i32>, ptr %a0
+ %v1 = load <4 x i32>, ptr %a1
+ %v2 = or <4 x i32> %v0, %v1
+ store <4 x i32> %v2, ptr %res
+ ret void
+}
+
+define void @or_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: or_v2i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <2 x i64>, ptr %a0
+ %v1 = load <2 x i64>, ptr %a1
+ %v2 = or <2 x i64> %v0, %v1
+ store <2 x i64> %v2, ptr %res
+ ret void
+}
+
+define void @or_u_v16i8(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v16i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vori.b $vr0, $vr0, 31
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i8>, ptr %a0
+ %v1 = or <16 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
+ store <16 x i8> %v1, ptr %res
+ ret void
+}
+
+define void @or_u_v8i16(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v8i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.h $vr1, 31
+; CHECK-NEXT: vor.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i16>, ptr %a0
+ %v1 = or <8 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
+ store <8 x i16> %v1, ptr %res
+ ret void
+}
+
+define void @or_u_v4i32(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v4i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.w $vr1, 31
+; CHECK-NEXT: vor.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i32>, ptr %a0
+ %v1 = or <4 x i32> %v0, <i32 31, i32 31, i32 31, i32 31>
+ store <4 x i32> %v1, ptr %res
+ ret void
+}
+
+define void @or_u_v2i64(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: or_u_v2i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.d $vr1, 31
+; CHECK-NEXT: vor.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <2 x i64>, ptr %a0
+ %v1 = or <2 x i64> %v0, <i64 31, i64 31>
+ store <2 x i64> %v1, ptr %res
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll
new file mode 100644
index 000000000000000..ce3e49c990ffb01
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
+
+define void @xor_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v16i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i8>, ptr %a0
+ %v1 = load <16 x i8>, ptr %a1
+ %v2 = xor <16 x i8> %v0, %v1
+ store <16 x i8> %v2, ptr %res
+ ret void
+}
+
+define void @xor_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v8i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i16>, ptr %a0
+ %v1 = load <8 x i16>, ptr %a1
+ %v2 = xor <8 x i16> %v0, %v1
+ store <8 x i16> %v2, ptr %res
+ ret void
+}
+
+define void @xor_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v4i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i32>, ptr %a0
+ %v1 = load <4 x i32>, ptr %a1
+ %v2 = xor <4 x i32> %v0, %v1
+ store <4 x i32> %v2, ptr %res
+ ret void
+}
+
+define void @xor_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind {
+; CHECK-LABEL: xor_v2i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a2, 0
+; CHECK-NEXT: vld $vr1, $a1, 0
+; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <2 x i64>, ptr %a0
+ %v1 = load <2 x i64>, ptr %a1
+ %v2 = xor <2 x i64> %v0, %v1
+ store <2 x i64> %v2, ptr %res
+ ret void
+}
+
+define void @xor_u_v16i8(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v16i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vxori.b $vr0, $vr0, 31
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <16 x i8>, ptr %a0
+ %v1 = xor <16 x i8> %v0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
+ store <16 x i8> %v1, ptr %res
+ ret void
+}
+
+define void @xor_u_v8i16(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v8i16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.h $vr1, 31
+; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <8 x i16>, ptr %a0
+ %v1 = xor <8 x i16> %v0, <i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31>
+ store <8 x i16> %v1, ptr %res
+ ret void
+}
+
+define void @xor_u_v4i32(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v4i32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.w $vr1, 31
+; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <4 x i32>, ptr %a0
+ %v1 = xor <4 x i32> %v0, <i32 31, i32 31, i32 31, i32 31>
+ store <4 x i32> %v1, ptr %res
+ ret void
+}
+
+define void @xor_u_v2i64(ptr %res, ptr %a0) nounwind {
+; CHECK-LABEL: xor_u_v2i64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vld $vr0, $a1, 0
+; CHECK-NEXT: vrepli.d $vr1, 31
+; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1
+; CHECK-NEXT: vst $vr0, $a0, 0
+; CHECK-NEXT: ret
+entry:
+ %v0 = load <2 x i64>, ptr %a0
+ %v1 = xor <2 x i64> %v0, <i64 31, i64 31>
+ store <2 x i64> %v1, ptr %res
+ ret void
+}
More information about the llvm-commits
mailing list