diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 43c04d417c7d9..604234b243153 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1461,7 +1461,12 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { SDValue X = N0.getOperand(0); - if (isMask_64(C1)) { + // Prefer SRAIW + ANDI when possible. + bool Skip = C2 > 32 && isInt<12>(N1C->getSExtValue()) && + X.getOpcode() == ISD::SHL && + isa(X.getOperand(1)) && + X.getConstantOperandVal(1) == 32; + if (isMask_64(C1) && !Skip) { unsigned Leading = XLen - llvm::bit_width(C1); if (C2 > Leading) { SDNode *SRAI = CurDAG->getMachineNode( diff --git a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll index 4749cc656693c..0d96fbfa81279 100644 --- a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll +++ b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll @@ -276,9 +276,8 @@ define i64 @sraiw_andi(i32 signext %0, i32 signext %1) nounwind { ; RV64-LABEL: sraiw_andi: ; RV64: # %bb.0: # %entry ; RV64-NEXT: add a0, a0, a1 -; RV64-NEXT: slli a0, a0, 32 -; RV64-NEXT: srai a0, a0, 2 -; RV64-NEXT: srli a0, a0, 61 +; RV64-NEXT: sraiw a0, a0, 31 +; RV64-NEXT: andi a0, a0, 7 ; RV64-NEXT: ret entry: %3 = add i32 %0, %1