From 93664d2315d8783e589eae4982aca707fc3e58ff Mon Sep 17 00:00:00 2001
From: Piotr Fusik
Date: Thu, 6 Nov 2025 12:50:20 +0100
Subject: [PATCH 1/2] [RISCV] For (2^N +/- 2^M) muls, prefer ADD to SUB
ADD is more compressible.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 8 +-
llvm/test/CodeGen/RISCV/mul.ll | 56 +-
llvm/test/CodeGen/RISCV/pr145360.ll | 16 +-
llvm/test/CodeGen/RISCV/rv32xtheadba.ll | 16 +-
llvm/test/CodeGen/RISCV/rv32zba.ll | 20 +-
llvm/test/CodeGen/RISCV/rv64xtheadba.ll | 24 +-
llvm/test/CodeGen/RISCV/rv64zba.ll | 44 +-
.../CodeGen/RISCV/rvv/calling-conv-fastcc.ll | 23 +-
.../CodeGen/RISCV/rvv/extract-subvector.ll | 6 +-
.../CodeGen/RISCV/rvv/vector-deinterleave.ll | 75 +-
.../CodeGen/RISCV/rvv/vector-interleave.ll | 1240 ++++++++---------
.../RISCV/rvv/vreductions-fp-sdnode.ll | 12 +-
.../CodeGen/RISCV/srem-seteq-illegal-types.ll | 40 +-
llvm/test/CodeGen/RISCV/xqciac.ll | 4 +-
14 files changed, 771 insertions(+), 813 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 995ae75da1c30..411ca744b1e7e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16477,12 +16477,12 @@ static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
ISD::NodeType Op;
uint64_t ShiftAmt1;
- if (isPowerOf2_64(MulAmt + MulAmtLowBit)) {
- Op = ISD::SUB;
- ShiftAmt1 = MulAmt + MulAmtLowBit;
- } else if (isPowerOf2_64(MulAmt - MulAmtLowBit)) {
+ if (isPowerOf2_64(MulAmt - MulAmtLowBit)) {
Op = ISD::ADD;
ShiftAmt1 = MulAmt - MulAmtLowBit;
+ } else if (isPowerOf2_64(MulAmt + MulAmtLowBit)) {
+ Op = ISD::SUB;
+ ShiftAmt1 = MulAmt + MulAmtLowBit;
} else {
return SDValue();
}
diff --git a/llvm/test/CodeGen/RISCV/mul.ll b/llvm/test/CodeGen/RISCV/mul.ll
index 4c9a98cabb15f..4533e14c672e7 100644
--- a/llvm/test/CodeGen/RISCV/mul.ll
+++ b/llvm/test/CodeGen/RISCV/mul.ll
@@ -1185,29 +1185,29 @@ define i32 @muli32_p384(i32 %a) nounwind {
; RV32I-LABEL: muli32_p384:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a1, a0, 7
-; RV32I-NEXT: slli a0, a0, 9
-; RV32I-NEXT: sub a0, a0, a1
+; RV32I-NEXT: slli a0, a0, 8
+; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV32IM-LABEL: muli32_p384:
; RV32IM: # %bb.0:
; RV32IM-NEXT: slli a1, a0, 7
-; RV32IM-NEXT: slli a0, a0, 9
-; RV32IM-NEXT: sub a0, a0, a1
+; RV32IM-NEXT: slli a0, a0, 8
+; RV32IM-NEXT: add a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p384:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 7
-; RV64I-NEXT: slli a0, a0, 9
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 8
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p384:
; RV64IM: # %bb.0:
; RV64IM-NEXT: slli a1, a0, 7
-; RV64IM-NEXT: slli a0, a0, 9
-; RV64IM-NEXT: subw a0, a0, a1
+; RV64IM-NEXT: slli a0, a0, 8
+; RV64IM-NEXT: addw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 384
ret i32 %1
@@ -1217,29 +1217,29 @@ define i32 @muli32_p12288(i32 %a) nounwind {
; RV32I-LABEL: muli32_p12288:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a1, a0, 12
-; RV32I-NEXT: slli a0, a0, 14
-; RV32I-NEXT: sub a0, a0, a1
+; RV32I-NEXT: slli a0, a0, 13
+; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV32IM-LABEL: muli32_p12288:
; RV32IM: # %bb.0:
; RV32IM-NEXT: slli a1, a0, 12
-; RV32IM-NEXT: slli a0, a0, 14
-; RV32IM-NEXT: sub a0, a0, a1
+; RV32IM-NEXT: slli a0, a0, 13
+; RV32IM-NEXT: add a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p12288:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 12
-; RV64I-NEXT: slli a0, a0, 14
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 13
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p12288:
; RV64IM: # %bb.0:
; RV64IM-NEXT: slli a1, a0, 12
-; RV64IM-NEXT: slli a0, a0, 14
-; RV64IM-NEXT: subw a0, a0, a1
+; RV64IM-NEXT: slli a0, a0, 13
+; RV64IM-NEXT: addw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 12288
ret i32 %1
@@ -2117,14 +2117,14 @@ define i64 @muland_demand(i64 %x) nounwind {
; RV32IM: # %bb.0:
; RV32IM-NEXT: andi a0, a0, -8
; RV32IM-NEXT: slli a2, a1, 2
-; RV32IM-NEXT: slli a1, a1, 4
-; RV32IM-NEXT: sub a1, a1, a2
+; RV32IM-NEXT: slli a1, a1, 3
+; RV32IM-NEXT: add a1, a1, a2
; RV32IM-NEXT: li a2, 12
; RV32IM-NEXT: mulhu a2, a0, a2
; RV32IM-NEXT: add a1, a2, a1
; RV32IM-NEXT: slli a2, a0, 2
-; RV32IM-NEXT: slli a0, a0, 4
-; RV32IM-NEXT: sub a0, a0, a2
+; RV32IM-NEXT: slli a0, a0, 3
+; RV32IM-NEXT: add a0, a0, a2
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muland_demand:
@@ -2133,16 +2133,16 @@ define i64 @muland_demand(i64 %x) nounwind {
; RV64I-NEXT: srli a1, a1, 2
; RV64I-NEXT: and a0, a0, a1
; RV64I-NEXT: slli a1, a0, 2
-; RV64I-NEXT: slli a0, a0, 4
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 3
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muland_demand:
; RV64IM: # %bb.0:
; RV64IM-NEXT: andi a0, a0, -8
; RV64IM-NEXT: slli a1, a0, 2
-; RV64IM-NEXT: slli a0, a0, 4
-; RV64IM-NEXT: sub a0, a0, a1
+; RV64IM-NEXT: slli a0, a0, 3
+; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
%and = and i64 %x, 4611686018427387896
%mul = mul i64 %and, 12
@@ -2171,15 +2171,15 @@ define i64 @mulzext_demand(i32 signext %x) nounwind {
; RV64I-LABEL: mulzext_demand:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 32
-; RV64I-NEXT: slli a0, a0, 34
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 33
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: mulzext_demand:
; RV64IM: # %bb.0:
; RV64IM-NEXT: slli a1, a0, 32
-; RV64IM-NEXT: slli a0, a0, 34
-; RV64IM-NEXT: sub a0, a0, a1
+; RV64IM-NEXT: slli a0, a0, 33
+; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
%ext = zext i32 %x to i64
%mul = mul i64 %ext, 12884901888
diff --git a/llvm/test/CodeGen/RISCV/pr145360.ll b/llvm/test/CodeGen/RISCV/pr145360.ll
index 1c77fadbd4b7d..013bab4ce6292 100644
--- a/llvm/test/CodeGen/RISCV/pr145360.ll
+++ b/llvm/test/CodeGen/RISCV/pr145360.ll
@@ -27,11 +27,11 @@ define i32 @unsigned(i32 %0, ptr %1) {
; CHECK-NEXT: slli a4, a3, 32
; CHECK-NEXT: mulhu a2, a2, a4
; CHECK-NEXT: srli a2, a2, 36
-; CHECK-NEXT: slli a4, a2, 5
-; CHECK-NEXT: slli a2, a2, 3
-; CHECK-NEXT: sub a2, a2, a4
+; CHECK-NEXT: slli a4, a2, 3
+; CHECK-NEXT: slli a2, a2, 4
+; CHECK-NEXT: add a2, a2, a4
; CHECK-NEXT: srliw a4, a0, 3
-; CHECK-NEXT: add a2, a0, a2
+; CHECK-NEXT: sub a2, a0, a2
; CHECK-NEXT: mulw a0, a4, a3
; CHECK-NEXT: sw a2, 0(a1)
; CHECK-NEXT: ret
@@ -68,10 +68,10 @@ define i32 @unsigned_div_first(i32 %0, ptr %1) {
; CHECK-NEXT: slli a3, a3, 32
; CHECK-NEXT: mulhu a2, a2, a3
; CHECK-NEXT: srli a2, a2, 36
-; CHECK-NEXT: slli a3, a2, 5
-; CHECK-NEXT: slli a4, a2, 3
-; CHECK-NEXT: sub a4, a4, a3
-; CHECK-NEXT: add a0, a0, a4
+; CHECK-NEXT: slli a3, a2, 3
+; CHECK-NEXT: slli a4, a2, 4
+; CHECK-NEXT: add a3, a4, a3
+; CHECK-NEXT: sub a0, a0, a3
; CHECK-NEXT: sw a0, 0(a1)
; CHECK-NEXT: mv a0, a2
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadba.ll b/llvm/test/CodeGen/RISCV/rv32xtheadba.ll
index 0e4a5c07020ee..fd341da86599f 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadba.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadba.ll
@@ -98,8 +98,8 @@ define i32 @addmul6(i32 %a, i32 %b) {
; RV32I-LABEL: addmul6:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a2, a0, 1
-; RV32I-NEXT: slli a0, a0, 3
-; RV32I-NEXT: sub a0, a0, a2
+; RV32I-NEXT: slli a0, a0, 2
+; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -136,8 +136,8 @@ define i32 @addmul12(i32 %a, i32 %b) {
; RV32I-LABEL: addmul12:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a2, a0, 2
-; RV32I-NEXT: slli a0, a0, 4
-; RV32I-NEXT: sub a0, a0, a2
+; RV32I-NEXT: slli a0, a0, 3
+; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -193,8 +193,8 @@ define i32 @addmul24(i32 %a, i32 %b) {
; RV32I-LABEL: addmul24:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a2, a0, 3
-; RV32I-NEXT: slli a0, a0, 5
-; RV32I-NEXT: sub a0, a0, a2
+; RV32I-NEXT: slli a0, a0, 4
+; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -269,8 +269,8 @@ define i32 @mul96(i32 %a) {
; RV32I-LABEL: mul96:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a1, a0, 5
-; RV32I-NEXT: slli a0, a0, 7
-; RV32I-NEXT: sub a0, a0, a1
+; RV32I-NEXT: slli a0, a0, 6
+; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV32XTHEADBA-LABEL: mul96:
diff --git a/llvm/test/CodeGen/RISCV/rv32zba.ll b/llvm/test/CodeGen/RISCV/rv32zba.ll
index a6dbd94caad4f..ea9d117f2e2e3 100644
--- a/llvm/test/CodeGen/RISCV/rv32zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zba.ll
@@ -85,8 +85,8 @@ define i32 @addmul6(i32 %a, i32 %b) {
; RV32I-LABEL: addmul6:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a2, a0, 1
-; RV32I-NEXT: slli a0, a0, 3
-; RV32I-NEXT: sub a0, a0, a2
+; RV32I-NEXT: slli a0, a0, 2
+; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -135,8 +135,8 @@ define i32 @addmul12(i32 %a, i32 %b) {
; RV32I-LABEL: addmul12:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a2, a0, 2
-; RV32I-NEXT: slli a0, a0, 4
-; RV32I-NEXT: sub a0, a0, a2
+; RV32I-NEXT: slli a0, a0, 3
+; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -210,8 +210,8 @@ define i32 @addmul24(i32 %a, i32 %b) {
; RV32I-LABEL: addmul24:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a2, a0, 3
-; RV32I-NEXT: slli a0, a0, 5
-; RV32I-NEXT: sub a0, a0, a2
+; RV32I-NEXT: slli a0, a0, 4
+; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -310,8 +310,8 @@ define i32 @mul96(i32 %a) {
; RV32I-LABEL: mul96:
; RV32I: # %bb.0:
; RV32I-NEXT: slli a1, a0, 5
-; RV32I-NEXT: slli a0, a0, 7
-; RV32I-NEXT: sub a0, a0, a1
+; RV32I-NEXT: slli a0, a0, 6
+; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV32ZBA-LABEL: mul96:
@@ -1272,8 +1272,8 @@ define ptr @shl_add_knownbits(ptr %p, i32 %i) {
; RV32I-NEXT: slli a1, a1, 18
; RV32I-NEXT: srli a1, a1, 18
; RV32I-NEXT: slli a2, a1, 1
-; RV32I-NEXT: slli a1, a1, 3
-; RV32I-NEXT: sub a1, a1, a2
+; RV32I-NEXT: slli a1, a1, 2
+; RV32I-NEXT: add a1, a1, a2
; RV32I-NEXT: srli a1, a1, 3
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rv64xtheadba.ll b/llvm/test/CodeGen/RISCV/rv64xtheadba.ll
index f4964288e3541..c57dfca1389b6 100644
--- a/llvm/test/CodeGen/RISCV/rv64xtheadba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xtheadba.ll
@@ -94,8 +94,8 @@ define i64 @addmul6(i64 %a, i64 %b) {
; RV64I-LABEL: addmul6:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 1
-; RV64I-NEXT: slli a0, a0, 3
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 2
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -113,8 +113,8 @@ define i64 @disjointormul6(i64 %a, i64 %b) {
; RV64I-LABEL: disjointormul6:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 1
-; RV64I-NEXT: slli a0, a0, 3
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 2
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: or a0, a0, a1
; RV64I-NEXT: ret
;
@@ -151,8 +151,8 @@ define i64 @addmul12(i64 %a, i64 %b) {
; RV64I-LABEL: addmul12:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 2
-; RV64I-NEXT: slli a0, a0, 4
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 3
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -227,8 +227,8 @@ define i64 @addmul24(i64 %a, i64 %b) {
; RV64I-LABEL: addmul24:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 3
-; RV64I-NEXT: slli a0, a0, 5
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 4
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -527,8 +527,8 @@ define i64 @mul96(i64 %a) {
; RV64I-LABEL: mul96:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 5
-; RV64I-NEXT: slli a0, a0, 7
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 6
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64XTHEADBA-LABEL: mul96:
@@ -990,8 +990,8 @@ define signext i32 @mulw192(i32 signext %a) {
; RV64I-LABEL: mulw192:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 6
-; RV64I-NEXT: slli a0, a0, 8
-; RV64I-NEXT: subw a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 7
+; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV64XTHEADBA-LABEL: mulw192:
diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index d4b228828c04d..cc3a7a195e3b4 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -489,8 +489,8 @@ define i64 @addmul6(i64 %a, i64 %b) {
; RV64I-LABEL: addmul6:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 1
-; RV64I-NEXT: slli a0, a0, 3
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 2
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -514,8 +514,8 @@ define i64 @disjointormul6(i64 %a, i64 %b) {
; RV64I-LABEL: disjointormul6:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 1
-; RV64I-NEXT: slli a0, a0, 3
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 2
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: or a0, a0, a1
; RV64I-NEXT: ret
;
@@ -564,8 +564,8 @@ define i64 @addmul12(i64 %a, i64 %b) {
; RV64I-LABEL: addmul12:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 2
-; RV64I-NEXT: slli a0, a0, 4
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 3
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -692,8 +692,8 @@ define i64 @addmul24(i64 %a, i64 %b) {
; RV64I-LABEL: addmul24:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a2, a0, 3
-; RV64I-NEXT: slli a0, a0, 5
-; RV64I-NEXT: sub a0, a0, a2
+; RV64I-NEXT: slli a0, a0, 4
+; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -1250,8 +1250,8 @@ define i64 @mul96(i64 %a) {
; RV64I-LABEL: mul96:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 5
-; RV64I-NEXT: slli a0, a0, 7
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 6
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: mul96:
@@ -1490,8 +1490,8 @@ define i64 @zext_mul96(i32 signext %a) {
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a1, a0, 27
-; RV64I-NEXT: srli a0, a0, 25
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: srli a0, a0, 26
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: zext_mul96:
@@ -1568,8 +1568,8 @@ define i64 @zext_mul12884901888(i32 signext %a) {
; RV64I-LABEL: zext_mul12884901888:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 32
-; RV64I-NEXT: slli a0, a0, 34
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 33
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: zext_mul12884901888:
@@ -2180,8 +2180,8 @@ define signext i32 @mulw192(i32 signext %a) {
; RV64I-LABEL: mulw192:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 6
-; RV64I-NEXT: slli a0, a0, 8
-; RV64I-NEXT: subw a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 7
+; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: mulw192:
@@ -3899,8 +3899,8 @@ define i64 @regression(i32 signext %x, i32 signext %y) {
; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a1, a0, 29
-; RV64I-NEXT: srli a0, a0, 27
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: srli a0, a0, 28
+; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: regression:
@@ -4034,8 +4034,8 @@ define i64 @bext_mul12(i32 %1, i32 %2) {
; RV64I-NEXT: srlw a0, a0, a1
; RV64I-NEXT: andi a0, a0, 1
; RV64I-NEXT: slli a1, a0, 2
-; RV64I-NEXT: slli a0, a0, 4
-; RV64I-NEXT: sub a0, a0, a1
+; RV64I-NEXT: slli a0, a0, 3
+; RV64I-NEXT: or a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBANOZBB-LABEL: bext_mul12:
@@ -4832,8 +4832,8 @@ define ptr @shl_add_knownbits(ptr %p, i64 %i) {
; RV64I-NEXT: slli a1, a1, 50
; RV64I-NEXT: srli a1, a1, 50
; RV64I-NEXT: slli a2, a1, 1
-; RV64I-NEXT: slli a1, a1, 3
-; RV64I-NEXT: sub a1, a1, a2
+; RV64I-NEXT: slli a1, a1, 2
+; RV64I-NEXT: add a1, a1, a2
; RV64I-NEXT: srli a1, a1, 3
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll b/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
index bd912193c4fed..39732602cc85e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
@@ -72,9 +72,8 @@ define fastcc @ret_split_nxv64i32(ptr %x) {
; CHECK-NEXT: csrr a2, vlenb
; CHECK-NEXT: vl8re32.v v8, (a1)
; CHECK-NEXT: slli a3, a2, 3
-; CHECK-NEXT: slli a4, a2, 5
; CHECK-NEXT: slli a2, a2, 4
-; CHECK-NEXT: sub a4, a4, a3
+; CHECK-NEXT: add a4, a2, a3
; CHECK-NEXT: add a5, a1, a2
; CHECK-NEXT: vl8re32.v v16, (a5)
; CHECK-NEXT: add a5, a1, a3
@@ -112,16 +111,16 @@ define fastcc @ret_split_nxv128i32(ptr %x) {
; CHECK-NEXT: addi a3, a3, 16
; CHECK-NEXT: vs8r.v v8, (a3) # vscale x 64-byte Folded Spill
; CHECK-NEXT: slli a3, a2, 3
-; CHECK-NEXT: slli a4, a2, 5
-; CHECK-NEXT: slli a5, a2, 4
+; CHECK-NEXT: slli a4, a2, 4
+; CHECK-NEXT: slli a5, a2, 5
; CHECK-NEXT: slli a2, a2, 6
-; CHECK-NEXT: sub a6, a4, a3
-; CHECK-NEXT: add a7, a4, a3
-; CHECK-NEXT: sub t0, a2, a5
+; CHECK-NEXT: add a6, a4, a3
+; CHECK-NEXT: add a7, a5, a3
+; CHECK-NEXT: add t0, a5, a4
; CHECK-NEXT: sub a2, a2, a3
; CHECK-NEXT: add t1, a1, a3
-; CHECK-NEXT: add t2, a1, a5
-; CHECK-NEXT: add t3, a1, a4
+; CHECK-NEXT: add t2, a1, a4
+; CHECK-NEXT: add t3, a1, a5
; CHECK-NEXT: vl8re32.v v8, (t1)
; CHECK-NEXT: csrr t1, vlenb
; CHECK-NEXT: slli t1, t1, 4
@@ -157,12 +156,12 @@ define fastcc @ret_split_nxv128i32(ptr %x) {
; CHECK-NEXT: addi a1, a1, 16
; CHECK-NEXT: vl8r.v v0, (a1) # vscale x 64-byte Folded Reload
; CHECK-NEXT: vs8r.v v0, (a0)
-; CHECK-NEXT: add a4, a0, a4
-; CHECK-NEXT: vs8r.v v16, (a4)
; CHECK-NEXT: add a5, a0, a5
+; CHECK-NEXT: vs8r.v v16, (a5)
+; CHECK-NEXT: add a4, a0, a4
; CHECK-NEXT: addi a1, sp, 16
; CHECK-NEXT: vl8r.v v16, (a1) # vscale x 64-byte Folded Reload
-; CHECK-NEXT: vs8r.v v16, (a5)
+; CHECK-NEXT: vs8r.v v16, (a4)
; CHECK-NEXT: add a3, a0, a3
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 4
diff --git a/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll
index 7c9a283dd54bc..ed0eb810aa04a 100644
--- a/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll
@@ -291,7 +291,8 @@ define @extract_nxv32i8_nxv2i8_6( %vec) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: srli a0, a0, 1
+; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma
; CHECK-NEXT: vslidedown.vx v8, v8, a0
; CHECK-NEXT: ret
@@ -314,7 +315,8 @@ define @extract_nxv32i8_nxv2i8_22( %vec) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: srli a0, a0, 1
+; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma
; CHECK-NEXT: vslidedown.vx v8, v10, a0
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
index ac9f26314a9ab..2590d2b0b77ee 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
@@ -475,16 +475,15 @@ define {, , , , , , , , , , , , , , , @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv112i8_nxv16i8( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv56i16_nxv8i16( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv28i32_nxv4i32( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv14i64_nxv2i64( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56f16_nxv8f16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv56bf16_nxv8bf16( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv28f32_nxv4f32( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( @vector_interleave_nxv14f64_nxv2f64( %v, half %s) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: srli a0, a0, 1
+; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma
; CHECK-NEXT: vfmv.s.f v10, fa0
; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma
@@ -943,8 +944,7 @@ define half @vreduce_ord_fadd_nxv12f16( %v, half %s) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 1
-; CHECK-NEXT: slli a0, a0, 1
-; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma
; CHECK-NEXT: vfmv.s.f v12, fa0
; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
@@ -982,7 +982,8 @@ define half @vreduce_fadd_nxv6f16( %v, half %s) {
; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma
; CHECK-NEXT: vfmv.s.f v10, fa0
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: srli a0, a0, 1
+; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: lui a1, 1048568
; CHECK-NEXT: vmv.s.x v11, a1
; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma
@@ -1020,8 +1021,7 @@ define half @vreduce_fmax_nxv12f16( %v) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 1
-; CHECK-NEXT: slli a0, a0, 1
-; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: li a1, -512
; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma
; CHECK-NEXT: vmv.s.x v12, a1
diff --git a/llvm/test/CodeGen/RISCV/srem-seteq-illegal-types.ll b/llvm/test/CodeGen/RISCV/srem-seteq-illegal-types.ll
index bc23388315de7..06bbe5209df35 100644
--- a/llvm/test/CodeGen/RISCV/srem-seteq-illegal-types.ll
+++ b/llvm/test/CodeGen/RISCV/srem-seteq-illegal-types.ll
@@ -169,10 +169,10 @@ define i1 @test_srem_even(i4 %X) nounwind {
; RV32M-NEXT: srli a2, a1, 31
; RV32M-NEXT: srli a1, a1, 4
; RV32M-NEXT: add a1, a1, a2
-; RV32M-NEXT: slli a2, a1, 3
-; RV32M-NEXT: slli a1, a1, 1
-; RV32M-NEXT: sub a1, a1, a2
-; RV32M-NEXT: add a0, a0, a1
+; RV32M-NEXT: slli a2, a1, 1
+; RV32M-NEXT: slli a1, a1, 2
+; RV32M-NEXT: add a1, a1, a2
+; RV32M-NEXT: sub a0, a0, a1
; RV32M-NEXT: andi a0, a0, 15
; RV32M-NEXT: addi a0, a0, -1
; RV32M-NEXT: seqz a0, a0
@@ -187,10 +187,10 @@ define i1 @test_srem_even(i4 %X) nounwind {
; RV64M-NEXT: srli a2, a1, 63
; RV64M-NEXT: srli a1, a1, 4
; RV64M-NEXT: add a1, a1, a2
-; RV64M-NEXT: slli a2, a1, 3
-; RV64M-NEXT: slli a1, a1, 1
-; RV64M-NEXT: sub a1, a1, a2
-; RV64M-NEXT: add a0, a0, a1
+; RV64M-NEXT: slli a2, a1, 1
+; RV64M-NEXT: slli a1, a1, 2
+; RV64M-NEXT: add a1, a1, a2
+; RV64M-NEXT: sub a0, a0, a1
; RV64M-NEXT: andi a0, a0, 15
; RV64M-NEXT: addi a0, a0, -1
; RV64M-NEXT: seqz a0, a0
@@ -205,10 +205,10 @@ define i1 @test_srem_even(i4 %X) nounwind {
; RV32MV-NEXT: srli a2, a1, 31
; RV32MV-NEXT: srli a1, a1, 4
; RV32MV-NEXT: add a1, a1, a2
-; RV32MV-NEXT: slli a2, a1, 3
-; RV32MV-NEXT: slli a1, a1, 1
-; RV32MV-NEXT: sub a1, a1, a2
-; RV32MV-NEXT: add a0, a0, a1
+; RV32MV-NEXT: slli a2, a1, 1
+; RV32MV-NEXT: slli a1, a1, 2
+; RV32MV-NEXT: add a1, a1, a2
+; RV32MV-NEXT: sub a0, a0, a1
; RV32MV-NEXT: andi a0, a0, 15
; RV32MV-NEXT: addi a0, a0, -1
; RV32MV-NEXT: seqz a0, a0
@@ -223,10 +223,10 @@ define i1 @test_srem_even(i4 %X) nounwind {
; RV64MV-NEXT: srli a2, a1, 63
; RV64MV-NEXT: srli a1, a1, 4
; RV64MV-NEXT: add a1, a1, a2
-; RV64MV-NEXT: slli a2, a1, 3
-; RV64MV-NEXT: slli a1, a1, 1
-; RV64MV-NEXT: sub a1, a1, a2
-; RV64MV-NEXT: add a0, a0, a1
+; RV64MV-NEXT: slli a2, a1, 1
+; RV64MV-NEXT: slli a1, a1, 2
+; RV64MV-NEXT: add a1, a1, a2
+; RV64MV-NEXT: sub a0, a0, a1
; RV64MV-NEXT: andi a0, a0, 15
; RV64MV-NEXT: addi a0, a0, -1
; RV64MV-NEXT: seqz a0, a0
@@ -823,16 +823,16 @@ define void @test_srem_vec(ptr %X) nounwind {
; RV64MV-NEXT: srai a4, a4, 1
; RV64MV-NEXT: mulh a6, a3, a6
; RV64MV-NEXT: add a4, a4, a7
-; RV64MV-NEXT: slli a7, a5, 3
-; RV64MV-NEXT: slli a5, a5, 1
-; RV64MV-NEXT: sub a5, a5, a7
+; RV64MV-NEXT: slli a7, a5, 1
+; RV64MV-NEXT: slli a5, a5, 2
+; RV64MV-NEXT: add a5, a5, a7
; RV64MV-NEXT: srli a7, a6, 63
; RV64MV-NEXT: srai a6, a6, 1
; RV64MV-NEXT: add a6, a6, a7
; RV64MV-NEXT: add a2, a2, a4
; RV64MV-NEXT: slli a4, a4, 3
; RV64MV-NEXT: sub a2, a2, a4
-; RV64MV-NEXT: add a1, a1, a5
+; RV64MV-NEXT: sub a1, a1, a5
; RV64MV-NEXT: li a4, -1
; RV64MV-NEXT: srli a4, a4, 31
; RV64MV-NEXT: vsext.vf8 v8, v10
diff --git a/llvm/test/CodeGen/RISCV/xqciac.ll b/llvm/test/CodeGen/RISCV/xqciac.ll
index 918468bdf03d3..92be4c977dd82 100644
--- a/llvm/test/CodeGen/RISCV/xqciac.ll
+++ b/llvm/test/CodeGen/RISCV/xqciac.ll
@@ -172,8 +172,8 @@ define dso_local i32 @pow2minuspow2(i32 %a, i32 %b) local_unnamed_addr #0 {
; RV32IM-LABEL: pow2minuspow2:
; RV32IM: # %bb.0: # %entry
; RV32IM-NEXT: slli a2, a1, 7
-; RV32IM-NEXT: slli a1, a1, 9
-; RV32IM-NEXT: sub a1, a1, a2
+; RV32IM-NEXT: slli a1, a1, 8
+; RV32IM-NEXT: add a1, a1, a2
; RV32IM-NEXT: add a0, a1, a0
; RV32IM-NEXT: ret
;
From e6f369fee3c6afaf4d04ccd737a7f7f3d5eb1ac2 Mon Sep 17 00:00:00 2001
From: Piotr Fusik
Date: Thu, 13 Nov 2025 17:02:40 +0100
Subject: [PATCH 2/2] [RISCV] Prefer SUB if `(X << C + 2)` is free
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 21 +++++-
.../CodeGen/RISCV/rvv/extract-subvector.ll | 6 +-
.../CodeGen/RISCV/rvv/vector-deinterleave.ll | 75 ++++++++++---------
.../RISCV/rvv/vreductions-fp-sdnode.ll | 6 +-
4 files changed, 60 insertions(+), 48 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 411ca744b1e7e..6a2f71219f8f2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16475,12 +16475,25 @@ static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
uint64_t MulAmt) {
uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
+ SDValue X = N->getOperand(0);
ISD::NodeType Op;
uint64_t ShiftAmt1;
- if (isPowerOf2_64(MulAmt - MulAmtLowBit)) {
+ bool CanSub = isPowerOf2_64(MulAmt + MulAmtLowBit);
+ auto PreferSub = [X, MulAmtLowBit]() {
+ // For MulAmt == 3 << M both (X << M + 2) - (X << M)
+ // and (X << M + 1) + (X << M) are valid expansions.
+ // Prefer SUB if we can get (X << M + 2) for free,
+ // because X is exact (Y >> M + 2).
+ uint64_t ShAmt = Log2_64(MulAmtLowBit) + 2;
+ using namespace SDPatternMatch;
+ return sd_match(X, m_AnyOf(m_Sra(m_Value(), m_SpecificInt(ShAmt)),
+ m_Srl(m_Value(), m_SpecificInt(ShAmt)))) &&
+ X->getFlags().hasExact();
+ };
+ if (isPowerOf2_64(MulAmt - MulAmtLowBit) && !(CanSub && PreferSub())) {
Op = ISD::ADD;
ShiftAmt1 = MulAmt - MulAmtLowBit;
- } else if (isPowerOf2_64(MulAmt + MulAmtLowBit)) {
+ } else if (CanSub) {
Op = ISD::SUB;
ShiftAmt1 = MulAmt + MulAmtLowBit;
} else {
@@ -16488,9 +16501,9 @@ static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
}
EVT VT = N->getValueType(0);
SDLoc DL(N);
- SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+ SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, X,
DAG.getConstant(Log2_64(ShiftAmt1), DL, VT));
- SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+ SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, X,
DAG.getConstant(Log2_64(MulAmtLowBit), DL, VT));
return DAG.getNode(Op, DL, VT, Shift1, Shift2);
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll
index ed0eb810aa04a..7c9a283dd54bc 100644
--- a/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll
@@ -291,8 +291,7 @@ define @extract_nxv32i8_nxv2i8_6( %vec) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: srli a0, a0, 1
-; CHECK-NEXT: add a0, a0, a1
+; CHECK-NEXT: sub a0, a0, a1
; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma
; CHECK-NEXT: vslidedown.vx v8, v8, a0
; CHECK-NEXT: ret
@@ -315,8 +314,7 @@ define @extract_nxv32i8_nxv2i8_22( %vec) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: srli a0, a0, 1
-; CHECK-NEXT: add a0, a0, a1
+; CHECK-NEXT: sub a0, a0, a1
; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma
; CHECK-NEXT: vslidedown.vx v8, v10, a0
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
index 2590d2b0b77ee..ac9f26314a9ab 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
@@ -475,15 +475,16 @@ define {, , , , , , , , , , , , , , , %v, half %s) {
; CHECK: # %bb.0:
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: srli a0, a0, 1
-; CHECK-NEXT: add a0, a0, a1
+; CHECK-NEXT: sub a0, a0, a1
; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma
; CHECK-NEXT: vfmv.s.f v10, fa0
; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma
@@ -982,8 +981,7 @@ define half @vreduce_fadd_nxv6f16( %v, half %s) {
; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma
; CHECK-NEXT: vfmv.s.f v10, fa0
; CHECK-NEXT: srli a1, a0, 2
-; CHECK-NEXT: srli a0, a0, 1
-; CHECK-NEXT: add a0, a0, a1
+; CHECK-NEXT: sub a0, a0, a1
; CHECK-NEXT: lui a1, 1048568
; CHECK-NEXT: vmv.s.x v11, a1
; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma