[llvm] 5cd98f9 - [RISCV] Select add(vec, splat(scalar)) to PADD_*S for P extension (#190303)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 3 17:33:02 PDT 2026
Author: SiHuaN
Date: 2026-04-04T08:32:56+08:00
New Revision: 5cd98f966e7883212ef161d8986d42a23297cfc3
URL: https://github.com/llvm/llvm-project/commit/5cd98f966e7883212ef161d8986d42a23297cfc3
DIFF: https://github.com/llvm/llvm-project/commit/5cd98f966e7883212ef161d8986d42a23297cfc3.diff
LOG: [RISCV] Select add(vec, splat(scalar)) to PADD_*S for P extension (#190303)
Added:
Modified:
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/lib/Target/RISCV/RISCVInstrInfoP.td
llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 8aea2f91468c1..ef56275118f2e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1375,6 +1375,11 @@ class PatGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
class PatGprGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
: Pat<(vt (OpNode (vt GPR:$rs1), (vt GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>;
+class PatGprSplatGpr<SDPatternOperator OpNode, RVInst Inst, ValueType VecVT,
+ ValueType ScalarVT = XLenVT>
+ : Pat<(VecVT (OpNode GPR:$rs1, (splat_vector (ScalarVT GPR:$rs2)))),
+ (Inst GPR:$rs1, GPR:$rs2)>;
+
class PatGprImm<SDPatternOperator OpNode, RVInst Inst, SDPatternOperator ImmType,
ValueType vt = XLenVT>
: Pat<(vt (OpNode (vt GPR:$rs1), ImmType:$imm)),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index f6dfb856fef7b..426fc332debc5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1796,10 +1796,12 @@ let Predicates = [HasStdExtP] in {
// Basic 8-bit arithmetic patterns
def : PatGprGpr<add, PADD_B, XLenVecI8VT>;
def : PatGprGpr<sub, PSUB_B, XLenVecI8VT>;
+ def : PatGprSplatGpr<add, PADD_BS, XLenVecI8VT>;
// Basic 16-bit arithmetic patterns
def : PatGprGpr<add, PADD_H, XLenVecI16VT>;
def : PatGprGpr<sub, PSUB_H, XLenVecI16VT>;
+ def : PatGprSplatGpr<add, PADD_HS, XLenVecI16VT>;
// 8-bit bitwise operation patterns
def : PatGprGpr<and, AND, XLenVecI8VT>;
@@ -2014,6 +2016,7 @@ let Predicates = [HasStdExtP, IsRV64] in {
// Basic 32-bit arithmetic patterns
def : PatGprGpr<add, PADD_W, v2i32>;
def : PatGprGpr<sub, PSUB_W, v2i32>;
+ def : PatGprSplatGpr<add, PADD_WS, v2i32>;
// 32-bit bitwise operation patterns
def : PatGprGpr<and, AND, v2i32>;
diff --git a/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll b/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
index e70eea7263325..3c03eaebeb06b 100644
--- a/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
@@ -625,6 +625,51 @@ define <2 x i16> @test_non_const_splat_i16(i16 %elt) {
ret <2 x i16> %splat
}
+; Test add(vec, splat(scalar)) pattern
+define <4 x i8> @test_padd_bs_splat_lhs(<4 x i8> %a, i8 %b) {
+; CHECK-LABEL: test_padd_bs_splat_lhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.bs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <4 x i8> poison, i8 %b, i32 0
+ %splat = shufflevector <4 x i8> %insert, <4 x i8> poison, <4 x i32> zeroinitializer
+ %res = add <4 x i8> %splat, %a
+ ret <4 x i8> %res
+}
+
+define <4 x i8> @test_padd_bs_splat_rhs(<4 x i8> %a, i8 %b) {
+; CHECK-LABEL: test_padd_bs_splat_rhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.bs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <4 x i8> poison, i8 %b, i32 0
+ %splat = shufflevector <4 x i8> %insert, <4 x i8> poison, <4 x i32> zeroinitializer
+ %res = add <4 x i8> %a, %splat
+ ret <4 x i8> %res
+}
+
+define <2 x i16> @test_padd_hs_splat_lhs(<2 x i16> %a, i16 %b) {
+; CHECK-LABEL: test_padd_hs_splat_lhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.hs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <2 x i16> poison, i16 %b, i32 0
+ %splat = shufflevector <2 x i16> %insert, <2 x i16> poison, <2 x i32> zeroinitializer
+ %res = add <2 x i16> %splat, %a
+ ret <2 x i16> %res
+}
+
+define <2 x i16> @test_padd_hs_splat_rhs(<2 x i16> %a, i16 %b) {
+; CHECK-LABEL: test_padd_hs_splat_rhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.hs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <2 x i16> poison, i16 %b, i32 0
+ %splat = shufflevector <2 x i16> %insert, <2 x i16> poison, <2 x i32> zeroinitializer
+ %res = add <2 x i16> %a, %splat
+ ret <2 x i16> %res
+}
+
define <4 x i8> @test_build_vector_i8(i8 %a, i8 %c, i8 %b, i8 %d) {
; CHECK-RV32-LABEL: test_build_vector_i8:
; CHECK-RV32: # %bb.0:
@@ -1918,10 +1963,10 @@ define <2 x i16> @test_select_v2i16(i1 %cond, <2 x i16> %a, <2 x i16> %b) {
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a0, 1
; CHECK-NEXT: mv a0, a1
-; CHECK-NEXT: bnez a3, .LBB134_2
+; CHECK-NEXT: bnez a3, .LBB138_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a0, a2
-; CHECK-NEXT: .LBB134_2:
+; CHECK-NEXT: .LBB138_2:
; CHECK-NEXT: ret
%res = select i1 %cond, <2 x i16> %a, <2 x i16> %b
ret <2 x i16> %res
@@ -1932,10 +1977,10 @@ define <4 x i8> @test_select_v4i8(i1 %cond, <4 x i8> %a, <4 x i8> %b) {
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a0, 1
; CHECK-NEXT: mv a0, a1
-; CHECK-NEXT: bnez a3, .LBB135_2
+; CHECK-NEXT: bnez a3, .LBB139_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a0, a2
-; CHECK-NEXT: .LBB135_2:
+; CHECK-NEXT: .LBB139_2:
; CHECK-NEXT: ret
%res = select i1 %cond, <4 x i8> %a, <4 x i8> %b
ret <4 x i8> %res
diff --git a/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll b/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
index 2d1c6d737a640..c431d8a2a1197 100644
--- a/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
@@ -863,6 +863,73 @@ define <2 x i32> @test_non_const_splat_i32(i32 %elt) {
ret <2 x i32> %splat
}
+; Test add(vec, splat(scalar)) pattern
+define <8 x i8> @test_padd_bs_splat_lhs(<8 x i8> %a, i8 %b) {
+; CHECK-LABEL: test_padd_bs_splat_lhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.bs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <8 x i8> poison, i8 %b, i32 0
+ %splat = shufflevector <8 x i8> %insert, <8 x i8> poison, <8 x i32> zeroinitializer
+ %res = add <8 x i8> %splat, %a
+ ret <8 x i8> %res
+}
+
+define <8 x i8> @test_padd_bs_splat_rhs(<8 x i8> %a, i8 %b) {
+; CHECK-LABEL: test_padd_bs_splat_rhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.bs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <8 x i8> poison, i8 %b, i32 0
+ %splat = shufflevector <8 x i8> %insert, <8 x i8> poison, <8 x i32> zeroinitializer
+ %res = add <8 x i8> %a, %splat
+ ret <8 x i8> %res
+}
+
+define <4 x i16> @test_padd_hs_splat_lhs(<4 x i16> %a, i16 %b) {
+; CHECK-LABEL: test_padd_hs_splat_lhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.hs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <4 x i16> poison, i16 %b, i32 0
+ %splat = shufflevector <4 x i16> %insert, <4 x i16> poison, <4 x i32> zeroinitializer
+ %res = add <4 x i16> %splat, %a
+ ret <4 x i16> %res
+}
+
+define <4 x i16> @test_padd_hs_splat_rhs(<4 x i16> %a, i16 %b) {
+; CHECK-LABEL: test_padd_hs_splat_rhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.hs a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <4 x i16> poison, i16 %b, i32 0
+ %splat = shufflevector <4 x i16> %insert, <4 x i16> poison, <4 x i32> zeroinitializer
+ %res = add <4 x i16> %a, %splat
+ ret <4 x i16> %res
+}
+
+define <2 x i32> @test_padd_ws_splat_lhs(<2 x i32> %a, i32 %b) {
+; CHECK-LABEL: test_padd_ws_splat_lhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.ws a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <2 x i32> poison, i32 %b, i32 0
+ %splat = shufflevector <2 x i32> %insert, <2 x i32> poison, <2 x i32> zeroinitializer
+ %res = add <2 x i32> %splat, %a
+ ret <2 x i32> %res
+}
+
+define <2 x i32> @test_padd_ws_splat_rhs(<2 x i32> %a, i32 %b) {
+; CHECK-LABEL: test_padd_ws_splat_rhs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: padd.ws a0, a0, a1
+; CHECK-NEXT: ret
+ %insert = insertelement <2 x i32> poison, i32 %b, i32 0
+ %splat = shufflevector <2 x i32> %insert, <2 x i32> poison, <2 x i32> zeroinitializer
+ %res = add <2 x i32> %a, %splat
+ ret <2 x i32> %res
+}
+
define <8 x i8> @test_build_vector_i8(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f, i8 %g, i8 %h) {
; CHECK-LABEL: test_build_vector_i8:
; CHECK: # %bb.0:
@@ -2440,10 +2507,10 @@ define <4 x i16> @test_select_v4i16(i1 %cond, <4 x i16> %a, <4 x i16> %b) {
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a0, 1
; CHECK-NEXT: mv a0, a1
-; CHECK-NEXT: bnez a3, .LBB196_2
+; CHECK-NEXT: bnez a3, .LBB202_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a0, a2
-; CHECK-NEXT: .LBB196_2:
+; CHECK-NEXT: .LBB202_2:
; CHECK-NEXT: ret
%res = select i1 %cond, <4 x i16> %a, <4 x i16> %b
ret <4 x i16> %res
@@ -2454,10 +2521,10 @@ define <8 x i8> @test_select_v8i8(i1 %cond, <8 x i8> %a, <8 x i8> %b) {
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a0, 1
; CHECK-NEXT: mv a0, a1
-; CHECK-NEXT: bnez a3, .LBB197_2
+; CHECK-NEXT: bnez a3, .LBB203_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a0, a2
-; CHECK-NEXT: .LBB197_2:
+; CHECK-NEXT: .LBB203_2:
; CHECK-NEXT: ret
%res = select i1 %cond, <8 x i8> %a, <8 x i8> %b
ret <8 x i8> %res
@@ -2468,10 +2535,10 @@ define <2 x i32> @test_select_v2i32(i1 %cond, <2 x i32> %a, <2 x i32> %b) {
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a0, 1
; CHECK-NEXT: mv a0, a1
-; CHECK-NEXT: bnez a3, .LBB198_2
+; CHECK-NEXT: bnez a3, .LBB204_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a0, a2
-; CHECK-NEXT: .LBB198_2:
+; CHECK-NEXT: .LBB204_2:
; CHECK-NEXT: ret
%res = select i1 %cond, <2 x i32> %a, <2 x i32> %b
ret <2 x i32> %res
More information about the llvm-commits
mailing list