[PATCH] D120597: [RISCV] With Zbb, fold (sext_inreg (abs X)) -> (max X, (negw X))
Craig Topper via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 3 10:24:23 PST 2022
craig.topper updated this revision to Diff 412760.
craig.topper added a comment.
Expand the comment to better explain what is happening.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D120597/new/
https://reviews.llvm.org/D120597
Files:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rv64zbb.ll
Index: llvm/test/CodeGen/RISCV/rv64zbb.ll
===================================================================
--- llvm/test/CodeGen/RISCV/rv64zbb.ll
+++ llvm/test/CodeGen/RISCV/rv64zbb.ll
@@ -960,7 +960,6 @@
ret i32 %abs
}
-; FIXME: We can remove the sext.w on RV64ZBB by using negw.
define signext i32 @abs_i32_sext(i32 signext %x) {
; RV64I-LABEL: abs_i32_sext:
; RV64I: # %bb.0:
@@ -971,9 +970,8 @@
;
; RV64ZBB-LABEL: abs_i32_sext:
; RV64ZBB: # %bb.0:
-; RV64ZBB-NEXT: neg a1, a0
+; RV64ZBB-NEXT: negw a1, a0
; RV64ZBB-NEXT: max a0, a0, a1
-; RV64ZBB-NEXT: sext.w a0, a0
; RV64ZBB-NEXT: ret
%abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
ret i32 %abs
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1041,7 +1041,7 @@
}
setTargetDAGCombine(ISD::ANY_EXTEND);
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN);
- if (Subtarget.hasStdExtZfh())
+ if (Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZbb())
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
if (Subtarget.hasStdExtF()) {
setTargetDAGCombine(ISD::ZERO_EXTEND);
@@ -7617,15 +7617,43 @@
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false);
}
-static SDValue performSIGN_EXTEND_INREG(SDNode *N, SelectionDAG &DAG) {
+static SDValue
+performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
+ const RISCVSubtarget &Subtarget) {
SDValue Src = N->getOperand(0);
+ EVT VT = N->getValueType(0);
// Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X)
if (Src.getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
cast<VTSDNode>(N->getOperand(1))->getVT().bitsGE(MVT::i16))
- return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), N->getValueType(0),
+ return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), VT,
Src.getOperand(0));
+ // Fold (i64 (sext_inreg (abs X), i32)) ->
+ // (i64 (smax (sext_inreg (neg X), i32), X)) if X has more than 32 sign bits.
+ // The (sext_inreg (neg X), i32) will be selected to negw by isel. This
+ // pattern occurs after type legalization of (i32 (abs X)) on RV64 if the user
+ // of the (i32 (abs X)) is a sext or setcc or something else that causes type
+ // legalization to add a sext_inreg after the abs. The (i32 (abs X)) will have
+ // been type legalized to (i64 (abs (sext_inreg X, i32))), but the sext_inreg
+ // may get combined into an earlier operation so we need to use
+ // ComputeNumSignBits.
+ // NOTE: (i64 (sext_inreg (abs X), i32)) can also be created for
+ // (i64 (ashr (shl (abs X), 32), 32)) without any type legalization so
+ // we can't assume that X has 33 sign bits. We must check.
+ if (Subtarget.hasStdExtZbb() && Subtarget.is64Bit() &&
+ Src.getOpcode() == ISD::ABS && Src.hasOneUse() && VT == MVT::i64 &&
+ cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32 &&
+ DAG.ComputeNumSignBits(Src.getOperand(0)) > 32) {
+ SDLoc DL(N);
+ SDValue Freeze = DAG.getFreeze(Src.getOperand(0));
+ SDValue Neg =
+ DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, MVT::i64), Freeze);
+ Neg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, Neg,
+ DAG.getValueType(MVT::i32));
+ return DAG.getNode(ISD::SMAX, DL, MVT::i64, Freeze, Neg);
+ }
+
return SDValue();
}
@@ -8244,7 +8272,7 @@
case ISD::XOR:
return performXORCombine(N, DAG);
case ISD::SIGN_EXTEND_INREG:
- return performSIGN_EXTEND_INREG(N, DAG);
+ return performSIGN_EXTEND_INREGCombine(N, DAG, Subtarget);
case ISD::ANY_EXTEND:
return performANY_EXTENDCombine(N, DCI, Subtarget);
case ISD::ZERO_EXTEND:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D120597.412760.patch
Type: text/x-patch
Size: 3822 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220303/e65b5f8e/attachment.bin>
More information about the llvm-commits
mailing list