@@ -997,6 +997,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
997
997
if (Subtarget.hasStdExtZbb())
998
998
setTargetDAGCombine({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN});
999
999
1000
+ if (Subtarget.hasStdExtZbs() && Subtarget.is64Bit())
1001
+ setTargetDAGCombine(ISD::TRUNCATE);
1002
+
1000
1003
if (Subtarget.hasStdExtZbkb())
1001
1004
setTargetDAGCombine(ISD::BITREVERSE);
1002
1005
if (Subtarget.hasStdExtZfh())
@@ -8259,6 +8262,29 @@ static SDValue combineDeMorganOfBoolean(SDNode *N, SelectionDAG &DAG) {
8259
8262
return DAG.getNode(ISD::XOR, DL, VT, Logic, DAG.getConstant(1, DL, VT));
8260
8263
}
8261
8264
8265
+ static SDValue performTRUNCATECombine(SDNode *N, SelectionDAG &DAG,
8266
+ const RISCVSubtarget &Subtarget) {
8267
+ SDValue N0 = N->getOperand(0);
8268
+ EVT VT = N->getValueType(0);
8269
+
8270
+ // Pre-promote (i1 (truncate (srl X, Y))) on RV64 with Zbs without zero
8271
+ // extending X. This is safe since we only need the LSB after the shift and
8272
+ // shift amounts larger than 31 would produce poison. If we wait until
8273
+ // type legalization, we'll create RISCVISD::SRLW and we can't recover it
8274
+ // to use a BEXT instruction.
8275
+ if (Subtarget.is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
8276
+ N0.getValueType() == MVT::i32 && N0.getOpcode() == ISD::SRL &&
8277
+ !isa<ConstantSDNode>(N0.getOperand(1)) && N0.hasOneUse()) {
8278
+ SDLoc DL(N0);
8279
+ SDValue Op0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N0.getOperand(0));
8280
+ SDValue Op1 = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N0.getOperand(1));
8281
+ SDValue Srl = DAG.getNode(ISD::SRL, DL, MVT::i64, Op0, Op1);
8282
+ return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, Srl);
8283
+ }
8284
+
8285
+ return SDValue();
8286
+ }
8287
+
8262
8288
static SDValue performANDCombine(SDNode *N,
8263
8289
TargetLowering::DAGCombinerInfo &DCI,
8264
8290
const RISCVSubtarget &Subtarget) {
@@ -9573,6 +9599,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
9573
9599
}
9574
9600
}
9575
9601
return SDValue();
9602
+ case ISD::TRUNCATE:
9603
+ return performTRUNCATECombine(N, DAG, Subtarget);
9576
9604
case RISCVISD::SELECT_CC: {
9577
9605
// Transform
9578
9606
SDValue LHS = N->getOperand(0);
0 commit comments