[llvm] 7e15ea1 - [RISCV] Add a DAG combine to pre-promote (i1 (truncate (i32 (srl X, Y)))) with Zbs on RV64.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 16 19:11:06 PST 2022
Author: Craig Topper
Date: 2022-11-16T19:07:33-08:00
New Revision: 7e15ea102f10061b47b43e230b6841e8e1274d22
URL: https://github.com/llvm/llvm-project/commit/7e15ea102f10061b47b43e230b6841e8e1274d22
DIFF: https://github.com/llvm/llvm-project/commit/7e15ea102f10061b47b43e230b6841e8e1274d22.diff
LOG: [RISCV] Add a DAG combine to pre-promote (i1 (truncate (i32 (srl X, Y)))) with Zbs on RV64.
Type legalization will want to turn (srl X, Y) into RISCVISD::SRLW,
which will prevent us from using a BEXT instruction.
This is similar to what we do for (i32 (and (srl X, Y), 1)).
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rv64zbs.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2c344590ddf4e..f7e8c7dec90fc 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -997,6 +997,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
if (Subtarget.hasStdExtZbb())
setTargetDAGCombine({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN});
+ if (Subtarget.hasStdExtZbs() && Subtarget.is64Bit())
+ setTargetDAGCombine(ISD::TRUNCATE);
+
if (Subtarget.hasStdExtZbkb())
setTargetDAGCombine(ISD::BITREVERSE);
if (Subtarget.hasStdExtZfh())
@@ -8259,6 +8262,29 @@ static SDValue combineDeMorganOfBoolean(SDNode *N, SelectionDAG &DAG) {
return DAG.getNode(ISD::XOR, DL, VT, Logic, DAG.getConstant(1, DL, VT));
}
+static SDValue performTRUNCATECombine(SDNode *N, SelectionDAG &DAG,
+ const RISCVSubtarget &Subtarget) {
+ SDValue N0 = N->getOperand(0);
+ EVT VT = N->getValueType(0);
+
+ // Pre-promote (i1 (truncate (srl X, Y))) on RV64 with Zbs without zero
+ // extending X. This is safe since we only need the LSB after the shift and
+ // shift amounts larger than 31 would produce poison. If we wait until
+ // type legalization, we'll create RISCVISD::SRLW and we can't recover it
+ // to use a BEXT instruction.
+ if (Subtarget.is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
+ N0.getValueType() == MVT::i32 && N0.getOpcode() == ISD::SRL &&
+ !isa<ConstantSDNode>(N0.getOperand(1)) && N0.hasOneUse()) {
+ SDLoc DL(N0);
+ SDValue Op0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N0.getOperand(0));
+ SDValue Op1 = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N0.getOperand(1));
+ SDValue Srl = DAG.getNode(ISD::SRL, DL, MVT::i64, Op0, Op1);
+ return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, Srl);
+ }
+
+ return SDValue();
+}
+
static SDValue performANDCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const RISCVSubtarget &Subtarget) {
@@ -9573,6 +9599,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
}
}
return SDValue();
+ case ISD::TRUNCATE:
+ return performTRUNCATECombine(N, DAG, Subtarget);
case RISCVISD::SELECT_CC: {
// Transform
SDValue LHS = N->getOperand(0);
diff --git a/llvm/test/CodeGen/RISCV/rv64zbs.ll b/llvm/test/CodeGen/RISCV/rv64zbs.ll
index 6ccb371529647..19ea17ba69862 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbs.ll
@@ -363,6 +363,42 @@ define signext i32 @bext_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
ret i32 %and1
}
+; This gets previous converted to (i1 (truncate (srl X, Y)). Make sure we are
+; able to use bext.
+define void @bext_i32_trunc(i32 signext %0, i32 signext %1) {
+; RV64I-LABEL: bext_i32_trunc:
+; RV64I: # %bb.0:
+; RV64I-NEXT: srlw a0, a0, a1
+; RV64I-NEXT: andi a0, a0, 1
+; RV64I-NEXT: beqz a0, .LBB19_2
+; RV64I-NEXT: # %bb.1:
+; RV64I-NEXT: ret
+; RV64I-NEXT: .LBB19_2:
+; RV64I-NEXT: tail bar at plt
+;
+; RV64ZBS-LABEL: bext_i32_trunc:
+; RV64ZBS: # %bb.0:
+; RV64ZBS-NEXT: bext a0, a0, a1
+; RV64ZBS-NEXT: beqz a0, .LBB19_2
+; RV64ZBS-NEXT: # %bb.1:
+; RV64ZBS-NEXT: ret
+; RV64ZBS-NEXT: .LBB19_2:
+; RV64ZBS-NEXT: tail bar at plt
+ %3 = shl i32 1, %1
+ %4 = and i32 %3, %0
+ %5 = icmp eq i32 %4, 0
+ br i1 %5, label %6, label %7
+
+6: ; preds = %2
+ tail call void @bar()
+ br label %7
+
+7: ; preds = %6, %2
+ ret void
+}
+
+declare void @bar()
+
define i64 @bext_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: bext_i64:
; RV64I: # %bb.0:
More information about the llvm-commits
mailing list