Skip to content

Commit 9cf8c09

Browse files
authored
[RISCV][DAGCombine] Combine sext_inreg (shl X, Y), i32 into sllw X, Y (#111101)
Alive2: https://alive2.llvm.org/ce/z/ncf36D
1 parent 1753de2 commit 9cf8c09

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
14891489
ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::MUL,
14901490
ISD::AND, ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT});
14911491
setTargetDAGCombine(ISD::SRA);
1492+
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
14921493

14931494
if (Subtarget.hasStdExtFOrZfinx())
14941495
setTargetDAGCombine({ISD::FADD, ISD::FMAXNUM, ISD::FMINNUM, ISD::FMUL});
@@ -1502,8 +1503,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
15021503

15031504
if (Subtarget.hasStdExtZbkb())
15041505
setTargetDAGCombine(ISD::BITREVERSE);
1505-
if (Subtarget.hasStdExtZfhminOrZhinxmin())
1506-
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
1506+
15071507
if (Subtarget.hasStdExtFOrZfinx())
15081508
setTargetDAGCombine({ISD::ZERO_EXTEND, ISD::FP_TO_SINT, ISD::FP_TO_UINT,
15091509
ISD::FP_TO_SINT_SAT, ISD::FP_TO_UINT_SAT});
@@ -14456,15 +14456,23 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
1445614456
const RISCVSubtarget &Subtarget) {
1445714457
SDValue Src = N->getOperand(0);
1445814458
EVT VT = N->getValueType(0);
14459+
EVT SrcVT = cast<VTSDNode>(N->getOperand(1))->getVT();
14460+
unsigned Opc = Src.getOpcode();
1445914461

1446014462
// Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X)
1446114463
// Don't do this with Zhinx. We need to explicitly sign extend the GPR.
14462-
if (Src.getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
14463-
cast<VTSDNode>(N->getOperand(1))->getVT().bitsGE(MVT::i16) &&
14464+
if (Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.bitsGE(MVT::i16) &&
1446414465
Subtarget.hasStdExtZfhmin())
1446514466
return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), VT,
1446614467
Src.getOperand(0));
1446714468

14469+
// Fold (sext_inreg (shl X, Y), i32) -> (sllw X, Y) iff Y u< 32
14470+
if (Opc == ISD::SHL && Subtarget.is64Bit() && SrcVT == MVT::i32 &&
14471+
VT == MVT::i64 && !isa<ConstantSDNode>(Src.getOperand(1)) &&
14472+
DAG.computeKnownBits(Src.getOperand(1)).countMaxActiveBits() <= 5)
14473+
return DAG.getNode(RISCVISD::SLLW, SDLoc(N), VT, Src.getOperand(0),
14474+
Src.getOperand(1));
14475+
1446814476
return SDValue();
1446914477
}
1447014478

llvm/test/CodeGen/RISCV/rv64zbs.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,3 +1210,36 @@ define i1 @icmp_eq_nonpow2(i32 signext %x) nounwind {
12101210
%cmp = icmp eq i32 %x, 32767
12111211
ret i1 %cmp
12121212
}
1213+
1214+
define signext i32 @fold_sextinreg_shl_to_sllw(i64 %x) nounwind {
1215+
; CHECK-LABEL: fold_sextinreg_shl_to_sllw:
1216+
; CHECK: # %bb.0: # %entry
1217+
; CHECK-NEXT: li a1, 1
1218+
; CHECK-NEXT: sllw a0, a1, a0
1219+
; CHECK-NEXT: ret
1220+
entry:
1221+
%mask = and i64 %x, 31
1222+
%shl = shl i64 1, %mask
1223+
%trunc = trunc i64 %shl to i32
1224+
ret i32 %trunc
1225+
}
1226+
1227+
define signext i32 @fold_sextinreg_shl_to_sllw_large_shamt(i64 %x) nounwind {
1228+
; RV64I-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
1229+
; RV64I: # %bb.0: # %entry
1230+
; RV64I-NEXT: li a1, 1
1231+
; RV64I-NEXT: sll a0, a1, a0
1232+
; RV64I-NEXT: sext.w a0, a0
1233+
; RV64I-NEXT: ret
1234+
;
1235+
; RV64ZBS-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
1236+
; RV64ZBS: # %bb.0: # %entry
1237+
; RV64ZBS-NEXT: bset a0, zero, a0
1238+
; RV64ZBS-NEXT: sext.w a0, a0
1239+
; RV64ZBS-NEXT: ret
1240+
entry:
1241+
%mask = and i64 %x, 63
1242+
%shl = shl i64 1, %mask
1243+
%trunc = trunc i64 %shl to i32
1244+
ret i32 %trunc
1245+
}

0 commit comments

Comments
 (0)