Skip to content

Commit

Permalink
[LoongArch] Add more and/or/xor patterns for vector types
Browse files Browse the repository at this point in the history
  • Loading branch information
wangleiat committed Dec 1, 2023
1 parent 56bbf81 commit ca66df3
Show file tree
Hide file tree
Showing 8 changed files with 774 additions and 18 deletions.
21 changes: 12 additions & 9 deletions llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down
21 changes: 12 additions & 9 deletions llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down
125 changes: 125 additions & 0 deletions llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll
Original file line number Diff line number Diff line change
@@ -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
}
125 changes: 125 additions & 0 deletions llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit ca66df3

Please sign in to comment.