Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoP.td
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,18 @@ let Predicates = [HasStdExtP] in {
def: Pat<(XLenVecI16VT (add GPR:$rs1, GPR:$rs2)), (PADD_H GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI16VT (sub GPR:$rs1, GPR:$rs2)), (PSUB_H GPR:$rs1, GPR:$rs2)>;

// 8-bit bitwise operation patterns
def: Pat<(XLenVecI8VT (and GPR:$rs1, GPR:$rs2)), (AND GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI8VT (or GPR:$rs1, GPR:$rs2)), (OR GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI8VT (xor GPR:$rs1, GPR:$rs2)), (XOR GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI8VT (vnot GPR:$rs1)), (XORI GPR:$rs1, -1)>;

// 16-bit bitwise operation patterns
def: Pat<(XLenVecI16VT (and GPR:$rs1, GPR:$rs2)), (AND GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI16VT (or GPR:$rs1, GPR:$rs2)), (OR GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI16VT (xor GPR:$rs1, GPR:$rs2)), (XOR GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI16VT (vnot GPR:$rs1)), (XORI GPR:$rs1, -1)>;

// 8-bit saturating add/sub patterns
def: Pat<(XLenVecI8VT (saddsat GPR:$rs1, GPR:$rs2)), (PSADD_B GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI8VT (uaddsat GPR:$rs1, GPR:$rs2)), (PSADDU_B GPR:$rs1, GPR:$rs2)>;
Expand Down Expand Up @@ -1611,6 +1623,12 @@ let Predicates = [HasStdExtP, IsRV64] in {
def: Pat<(v2i32 (add GPR:$rs1, GPR:$rs2)), (PADD_W GPR:$rs1, GPR:$rs2)>;
def: Pat<(v2i32 (sub GPR:$rs1, GPR:$rs2)), (PSUB_W GPR:$rs1, GPR:$rs2)>;

// 32-bit bitwise operation patterns
def: Pat<(v2i32 (and GPR:$rs1, GPR:$rs2)), (AND GPR:$rs1, GPR:$rs2)>;
def: Pat<(v2i32 (or GPR:$rs1, GPR:$rs2)), (OR GPR:$rs1, GPR:$rs2)>;
def: Pat<(v2i32 (xor GPR:$rs1, GPR:$rs2)), (XOR GPR:$rs1, GPR:$rs2)>;
def: Pat<(v2i32 (vnot GPR:$rs1)), (XORI GPR:$rs1, -1)>;

// 32-bit saturating add/sub patterns
def: Pat<(v2i32 (saddsat GPR:$rs1, GPR:$rs2)), (PSADD_W GPR:$rs1, GPR:$rs2)>;
def: Pat<(v2i32 (uaddsat GPR:$rs1, GPR:$rs2)), (PSADDU_W GPR:$rs1, GPR:$rs2)>;
Expand Down
118 changes: 118 additions & 0 deletions llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,124 @@ define void @test_psub_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
ret void
}

; Test bitwise operations for v2i16 (use scalar instructions)
define void @test_and_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_and_h:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: lw a2, 0(a2)
; CHECK-NEXT: and a1, a1, a2
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i16>, ptr %a_ptr
%b = load <2 x i16>, ptr %b_ptr
%res = and <2 x i16> %a, %b
store <2 x i16> %res, ptr %ret_ptr
ret void
}

define void @test_or_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_or_h:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: lw a2, 0(a2)
; CHECK-NEXT: or a1, a1, a2
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i16>, ptr %a_ptr
%b = load <2 x i16>, ptr %b_ptr
%res = or <2 x i16> %a, %b
store <2 x i16> %res, ptr %ret_ptr
ret void
}

define void @test_xor_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_xor_h:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: lw a2, 0(a2)
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i16>, ptr %a_ptr
%b = load <2 x i16>, ptr %b_ptr
%res = xor <2 x i16> %a, %b
store <2 x i16> %res, ptr %ret_ptr
ret void
}

; Test bitwise operations for v4i8 (use scalar instructions)
define void @test_and_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_and_b:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: lw a2, 0(a2)
; CHECK-NEXT: and a1, a1, a2
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i8>, ptr %a_ptr
%b = load <4 x i8>, ptr %b_ptr
%res = and <4 x i8> %a, %b
store <4 x i8> %res, ptr %ret_ptr
ret void
}

define void @test_or_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_or_b:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: lw a2, 0(a2)
; CHECK-NEXT: or a1, a1, a2
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i8>, ptr %a_ptr
%b = load <4 x i8>, ptr %b_ptr
%res = or <4 x i8> %a, %b
store <4 x i8> %res, ptr %ret_ptr
ret void
}

define void @test_xor_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_xor_b:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: lw a2, 0(a2)
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i8>, ptr %a_ptr
%b = load <4 x i8>, ptr %b_ptr
%res = xor <4 x i8> %a, %b
store <4 x i8> %res, ptr %ret_ptr
ret void
}

define void @test_not_h(ptr %ret_ptr, ptr %a_ptr) {
; CHECK-LABEL: test_not_h:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: not a1, a1
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i16>, ptr %a_ptr
%res = xor <2 x i16> %a, splat(i16 -1)
store <2 x i16> %res, ptr %ret_ptr
ret void
}

define void @test_not_b(ptr %ret_ptr, ptr %a_ptr) {
; CHECK-LABEL: test_not_b:
; CHECK: # %bb.0:
; CHECK-NEXT: lw a1, 0(a1)
; CHECK-NEXT: not a1, a1
; CHECK-NEXT: sw a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i8>, ptr %a_ptr
%res = xor <4 x i8> %a, splat(i8 -1)
store <4 x i8> %res, ptr %ret_ptr
ret void
}

; Test saturating add operations for v2i16
define void @test_psadd_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_psadd_h:
Expand Down
177 changes: 177 additions & 0 deletions llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,183 @@ define void @test_psub_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
ret void
}

; Test bitwise operations for v4i16 (use scalar instructions)
define void @test_and_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_and_h:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: and a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i16>, ptr %a_ptr
%b = load <4 x i16>, ptr %b_ptr
%res = and <4 x i16> %a, %b
store <4 x i16> %res, ptr %ret_ptr
ret void
}

define void @test_or_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_or_h:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: or a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i16>, ptr %a_ptr
%b = load <4 x i16>, ptr %b_ptr
%res = or <4 x i16> %a, %b
store <4 x i16> %res, ptr %ret_ptr
ret void
}

define void @test_xor_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_xor_h:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i16>, ptr %a_ptr
%b = load <4 x i16>, ptr %b_ptr
%res = xor <4 x i16> %a, %b
store <4 x i16> %res, ptr %ret_ptr
ret void
}

; Test bitwise operations for v8i8 (use scalar instructions)
define void @test_and_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_and_b:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: and a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <8 x i8>, ptr %a_ptr
%b = load <8 x i8>, ptr %b_ptr
%res = and <8 x i8> %a, %b
store <8 x i8> %res, ptr %ret_ptr
ret void
}

define void @test_or_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_or_b:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: or a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <8 x i8>, ptr %a_ptr
%b = load <8 x i8>, ptr %b_ptr
%res = or <8 x i8> %a, %b
store <8 x i8> %res, ptr %ret_ptr
ret void
}

define void @test_xor_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_xor_b:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <8 x i8>, ptr %a_ptr
%b = load <8 x i8>, ptr %b_ptr
%res = xor <8 x i8> %a, %b
store <8 x i8> %res, ptr %ret_ptr
ret void
}

; Test bitwise operations for v2i32 (use scalar instructions)
define void @test_and_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_and_w:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: and a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i32>, ptr %a_ptr
%b = load <2 x i32>, ptr %b_ptr
%res = and <2 x i32> %a, %b
store <2 x i32> %res, ptr %ret_ptr
ret void
}

define void @test_or_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_or_w:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: or a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i32>, ptr %a_ptr
%b = load <2 x i32>, ptr %b_ptr
%res = or <2 x i32> %a, %b
store <2 x i32> %res, ptr %ret_ptr
ret void
}

define void @test_xor_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_xor_w:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: ld a2, 0(a2)
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i32>, ptr %a_ptr
%b = load <2 x i32>, ptr %b_ptr
%res = xor <2 x i32> %a, %b
store <2 x i32> %res, ptr %ret_ptr
ret void
}

define void @test_not_h(ptr %ret_ptr, ptr %a_ptr) {
; CHECK-LABEL: test_not_h:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: not a1, a1
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <4 x i16>, ptr %a_ptr
%res = xor <4 x i16> %a, splat(i16 -1)
store <4 x i16> %res, ptr %ret_ptr
ret void
}

define void @test_not_b(ptr %ret_ptr, ptr %a_ptr) {
; CHECK-LABEL: test_not_b:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: not a1, a1
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <8 x i8>, ptr %a_ptr
%res = xor <8 x i8> %a, splat(i8 -1)
store <8 x i8> %res, ptr %ret_ptr
ret void
}

define void @test_not_w(ptr %ret_ptr, ptr %a_ptr) {
; CHECK-LABEL: test_not_w:
; CHECK: # %bb.0:
; CHECK-NEXT: ld a1, 0(a1)
; CHECK-NEXT: not a1, a1
; CHECK-NEXT: sd a1, 0(a0)
; CHECK-NEXT: ret
%a = load <2 x i32>, ptr %a_ptr
%res = xor <2 x i32> %a, splat(i32 -1)
store <2 x i32> %res, ptr %ret_ptr
ret void
}

; Test saturating add operations for v4i16
define void @test_psadd_h(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
; CHECK-LABEL: test_psadd_h:
Expand Down