[llvm] b5fd6b4 - [RISCV] Teach instruction selection to elide sext.w in some cases.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 2 07:54:41 PDT 2021
Author: Craig Topper
Date: 2021-09-02T07:54:34-07:00
New Revision: b5fd6b46f59e2bf0807621814ba9bef6645eec58
URL: https://github.com/llvm/llvm-project/commit/b5fd6b46f59e2bf0807621814ba9bef6645eec58
DIFF: https://github.com/llvm/llvm-project/commit/b5fd6b46f59e2bf0807621814ba9bef6645eec58.diff
LOG: [RISCV] Teach instruction selection to elide sext.w in some cases.
If a sext_inreg is up for isel, and all its users are W instructions,
we can skip emitting the sext_inreg. This helpful if the producing
instruction can't become a W instruction.
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D108966
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/test/CodeGen/RISCV/rv64zba.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 14d0cc5c6959..3437f1e59d86 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1536,6 +1536,7 @@ bool RISCVDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) {
bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits) const {
assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB ||
Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL ||
+ Node->getOpcode() == ISD::SIGN_EXTEND_INREG ||
isa<ConstantSDNode>(Node)) &&
"Unexpected opcode");
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index ce23dc6cc866..495c39132ca3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1262,10 +1262,18 @@ class overflowingbinopw<SDPatternOperator operator>
return hasAllWUsers(Node);
}]>;
+def sexti32_allwusers : PatFrag<(ops node:$src),
+ (sext_inreg node:$src, i32), [{
+ return hasAllWUsers(Node);
+}]>;
+
let Predicates = [IsRV64] in {
/// sext and zext
+// Sign extend is not needed if all users are W instructions.
+def : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>;
+
def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
/// ALU operations
diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index ad388105e7ed..c418ce682361 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -376,7 +376,6 @@ define i64 @sh3adduw_2(i64 %0, i64 %1) {
; to remove the sext_inreg because it has multiple uses. The ashr will use the
; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
; If the shl is selected as sllw, we don't need the sext_inreg.
-; FIXME: We should not emit a sext.w.
define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
; RV64I-LABEL: sh2add_extra_sext:
; RV64I: # %bb.0:
@@ -390,8 +389,7 @@ define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
; RV64B-LABEL: sh2add_extra_sext:
; RV64B: # %bb.0:
; RV64B-NEXT: sh2add a0, a0, a1
-; RV64B-NEXT: sext.w a1, a0
-; RV64B-NEXT: sllw a1, a2, a1
+; RV64B-NEXT: sllw a1, a2, a0
; RV64B-NEXT: sraiw a0, a0, 2
; RV64B-NEXT: mul a0, a1, a0
; RV64B-NEXT: ret
@@ -399,8 +397,7 @@ define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
; RV64ZBA-LABEL: sh2add_extra_sext:
; RV64ZBA: # %bb.0:
; RV64ZBA-NEXT: sh2add a0, a0, a1
-; RV64ZBA-NEXT: sext.w a1, a0
-; RV64ZBA-NEXT: sllw a1, a2, a1
+; RV64ZBA-NEXT: sllw a1, a2, a0
; RV64ZBA-NEXT: sraiw a0, a0, 2
; RV64ZBA-NEXT: mul a0, a1, a0
; RV64ZBA-NEXT: ret
More information about the llvm-commits
mailing list