[llvm] fd4d584 - [RISCV] Add DAGCombine to fold (bitreverse (bswap X)) to brev8 with Zbkb.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 12 17:01:47 PST 2022
Author: Craig Topper
Date: 2022-03-12T16:39:39-08:00
New Revision: fd4d584d6b5c8c1e8d4fd9cbf171247f72fa9b21
URL: https://github.com/llvm/llvm-project/commit/fd4d584d6b5c8c1e8d4fd9cbf171247f72fa9b21
DIFF: https://github.com/llvm/llvm-project/commit/fd4d584d6b5c8c1e8d4fd9cbf171247f72fa9b21.diff
LOG: [RISCV] Add DAGCombine to fold (bitreverse (bswap X)) to brev8 with Zbkb.
If the type is less than XLenVT, type legalization will turn this
into (srl (bitreverse (bswap (srl (bswap X), C))), C). We can't
completely recover from these shifts. They introduce zeros into
the upper bits of the result and we can't easily tell if they are
needed. By doing a DAG combine early, we avoid introducing these
shifts.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index dc345b60b1a57..09151a091b601 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1039,6 +1039,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setTargetDAGCombine(ISD::ROTL);
setTargetDAGCombine(ISD::ROTR);
}
+ if (Subtarget.hasStdExtZbkb())
+ setTargetDAGCombine(ISD::BITREVERSE);
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN);
if (Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZbb())
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
@@ -6767,17 +6769,22 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
}
case RISCVISD::GREV:
case RISCVISD::GORC: {
- assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
+ MVT VT = N->getSimpleValueType(0);
+ MVT XLenVT = Subtarget.getXLenVT();
+ assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.is64Bit())) &&
"Unexpected custom legalisation");
assert(isa<ConstantSDNode>(N->getOperand(1)) && "Expected constant");
- SDValue NewOp0 =
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0));
+ assert((Subtarget.hasStdExtZbp() ||
+ (Subtarget.hasStdExtZbkb() && N->getOpcode() == RISCVISD::GREV &&
+ N->getConstantOperandVal(1) == 7)) &&
+ "Unexpected extension");
+ SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, N->getOperand(0));
SDValue NewOp1 =
- DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N->getOperand(1));
- SDValue NewRes = DAG.getNode(N->getOpcode(), DL, MVT::i64, NewOp0, NewOp1);
+ DAG.getNode(ISD::ZERO_EXTEND, DL, XLenVT, N->getOperand(1));
+ SDValue NewRes = DAG.getNode(N->getOpcode(), DL, XLenVT, NewOp0, NewOp1);
// ReplaceNodeResults requires we maintain the same type for the return
// value.
- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes));
+ Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NewRes));
break;
}
case RISCVISD::SHFL: {
@@ -8051,6 +8058,26 @@ static SDValue performFP_TO_INT_SATCombine(SDNode *N,
return DAG.getSelectCC(DL, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
}
+// Combine (bitreverse (bswap X)) to the BREV8 GREVI encoding if the type is
+// smaller than XLenVT.
+static SDValue performBITREVERSECombine(SDNode *N, SelectionDAG &DAG,
+ const RISCVSubtarget &Subtarget) {
+ assert(Subtarget.hasStdExtZbkb() && "Unexpected extension");
+
+ SDValue Src = N->getOperand(0);
+ if (Src.getOpcode() != ISD::BSWAP)
+ return SDValue();
+
+ EVT VT = N->getValueType(0);
+ if (!VT.isScalarInteger() || VT.getSizeInBits() >= Subtarget.getXLen() ||
+ !isPowerOf2_32(VT.getSizeInBits()))
+ return SDValue();
+
+ SDLoc DL(N);
+ return DAG.getNode(RISCVISD::GREV, DL, VT, Src.getOperand(0),
+ DAG.getConstant(7, DL, VT));
+}
+
SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
@@ -8390,6 +8417,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
}
break;
}
+ case ISD::BITREVERSE:
+ return performBITREVERSECombine(N, DAG, Subtarget);
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
return performFP_TO_INTCombine(N, DCI, Subtarget);
diff --git a/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll b/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
index 489e117b6401d..61543f5c9273b 100644
--- a/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
+++ b/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
@@ -822,7 +822,6 @@ define i64 @test_bitreverse_i64(i64 %a) nounwind {
ret i64 %tmp
}
-; FIXME: Merge the away the two rev8s in the Zbkb code.
define i16 @test_bswap_bitreverse_i16(i16 %a) nounwind {
; RV32I-LABEL: test_bswap_bitreverse_i16:
; RV32I: # %bb.0:
@@ -926,20 +925,12 @@ define i16 @test_bswap_bitreverse_i16(i16 %a) nounwind {
;
; RV32ZBKB-LABEL: test_bswap_bitreverse_i16:
; RV32ZBKB: # %bb.0:
-; RV32ZBKB-NEXT: rev8 a0, a0
-; RV32ZBKB-NEXT: srli a0, a0, 16
-; RV32ZBKB-NEXT: rev8 a0, a0
; RV32ZBKB-NEXT: brev8 a0, a0
-; RV32ZBKB-NEXT: srli a0, a0, 16
; RV32ZBKB-NEXT: ret
;
; RV64ZBKB-LABEL: test_bswap_bitreverse_i16:
; RV64ZBKB: # %bb.0:
-; RV64ZBKB-NEXT: rev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 48
-; RV64ZBKB-NEXT: rev8 a0, a0
; RV64ZBKB-NEXT: brev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 48
; RV64ZBKB-NEXT: ret
;
; RV32ZBP-LABEL: test_bswap_bitreverse_i16:
@@ -956,7 +947,6 @@ define i16 @test_bswap_bitreverse_i16(i16 %a) nounwind {
ret i16 %tmp2
}
-; FIXME: Merge the away the two rev8s in the Zbkb code.
define i32 @test_bswap_bitreverse_i32(i32 %a) nounwind {
; RV32I-LABEL: test_bswap_bitreverse_i32:
; RV32I: # %bb.0:
@@ -1065,11 +1055,7 @@ define i32 @test_bswap_bitreverse_i32(i32 %a) nounwind {
;
; RV64ZBKB-LABEL: test_bswap_bitreverse_i32:
; RV64ZBKB: # %bb.0:
-; RV64ZBKB-NEXT: rev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 32
-; RV64ZBKB-NEXT: rev8 a0, a0
; RV64ZBKB-NEXT: brev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 32
; RV64ZBKB-NEXT: ret
;
; RV32ZBP-LABEL: test_bswap_bitreverse_i32:
@@ -1243,7 +1229,6 @@ define i64 @test_bswap_bitreverse_i64(i64 %a) nounwind {
ret i64 %tmp2
}
-; FIXME: Merge the away the two rev8s in the Zbkb code.
define i16 @test_bitreverse_bswap_i16(i16 %a) nounwind {
; RV32I-LABEL: test_bitreverse_bswap_i16:
; RV32I: # %bb.0:
@@ -1347,20 +1332,12 @@ define i16 @test_bitreverse_bswap_i16(i16 %a) nounwind {
;
; RV32ZBKB-LABEL: test_bitreverse_bswap_i16:
; RV32ZBKB: # %bb.0:
-; RV32ZBKB-NEXT: rev8 a0, a0
-; RV32ZBKB-NEXT: srli a0, a0, 16
-; RV32ZBKB-NEXT: rev8 a0, a0
; RV32ZBKB-NEXT: brev8 a0, a0
-; RV32ZBKB-NEXT: srli a0, a0, 16
; RV32ZBKB-NEXT: ret
;
; RV64ZBKB-LABEL: test_bitreverse_bswap_i16:
; RV64ZBKB: # %bb.0:
-; RV64ZBKB-NEXT: rev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 48
-; RV64ZBKB-NEXT: rev8 a0, a0
; RV64ZBKB-NEXT: brev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 48
; RV64ZBKB-NEXT: ret
;
; RV32ZBP-LABEL: test_bitreverse_bswap_i16:
@@ -1377,7 +1354,6 @@ define i16 @test_bitreverse_bswap_i16(i16 %a) nounwind {
ret i16 %tmp2
}
-; FIXME: Merge the away the two rev8s in the Zbkb code.
define i32 @test_bitreverse_bswap_i32(i32 %a) nounwind {
; RV32I-LABEL: test_bitreverse_bswap_i32:
; RV32I: # %bb.0:
@@ -1486,11 +1462,7 @@ define i32 @test_bitreverse_bswap_i32(i32 %a) nounwind {
;
; RV64ZBKB-LABEL: test_bitreverse_bswap_i32:
; RV64ZBKB: # %bb.0:
-; RV64ZBKB-NEXT: rev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 32
-; RV64ZBKB-NEXT: rev8 a0, a0
; RV64ZBKB-NEXT: brev8 a0, a0
-; RV64ZBKB-NEXT: srli a0, a0, 32
; RV64ZBKB-NEXT: ret
;
; RV32ZBP-LABEL: test_bitreverse_bswap_i32:
More information about the llvm-commits
mailing list