diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 4dd53fdd0213..a5cdf9f79f57 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1051,11 +1051,11 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { unsigned ShAmt = N1C->getZExtValue(); uint64_t Mask = N0.getConstantOperandVal(1); - if (ShAmt <= 32 && isShiftedMask_64(Mask)) { + if (isShiftedMask_64(Mask)) { unsigned XLen = Subtarget->getXLen(); unsigned LeadingZeros = XLen - llvm::bit_width(Mask); unsigned TrailingZeros = llvm::countr_zero(Mask); - if (TrailingZeros > 0 && LeadingZeros == 32) { + if (ShAmt <= 32 && TrailingZeros > 0 && LeadingZeros == 32) { // Optimize (shl (and X, C2), C) -> (slli (srliw X, C3), C3+C) // where C2 has 32 leading zeros and C3 trailing zeros. SDNode *SRLIW = CurDAG->getMachineNode( diff --git a/llvm/test/CodeGen/RISCV/and-shl.ll b/llvm/test/CodeGen/RISCV/and-shl.ll index c3cb5d8e2e37..26b4a90d88fb 100644 --- a/llvm/test/CodeGen/RISCV/and-shl.ll +++ b/llvm/test/CodeGen/RISCV/and-shl.ll @@ -77,3 +77,21 @@ define i32 @and_0xfff_shl_2_multi_use(i32 %x) { %r = add i32 %a, %s ret i32 %r } + +define i64 @and_0xfff_shl_33(i64 %x) { +; RV32I-LABEL: and_0xfff_shl_33: +; RV32I: # %bb.0: +; RV32I-NEXT: slli a0, a0, 20 +; RV32I-NEXT: srli a1, a0, 19 +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: and_0xfff_shl_33: +; RV64I: # %bb.0: +; RV64I-NEXT: slli a0, a0, 52 +; RV64I-NEXT: srli a0, a0, 19 +; RV64I-NEXT: ret + %a = and i64 %x, 4095 + %s = shl i64 %a, 33 + ret i64 %s +}