From 70f50114f37e86bd4869a75b1a8313440bd55780 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 23 Sep 2021 14:09:51 -0700 Subject: [PATCH] [RISCV] Add another isel optimization for (and (shl x, c2), c1) Turn (and (shl x, c2), c1) -> (slli (srli x, c3-c2), c3) if c1 is a shifted mask with no leading zeros and c3 trailing zeros where c3 is greater than c2. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 17 +++++++++++++++++ llvm/test/CodeGen/RISCV/shift-and.ll | 15 ++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 25c2989..3e9e19d 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -674,6 +674,23 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { } } + // Turn (and (shl x, c2), c1) -> (slli (srli x, c3-c2), c3) if c1 is a + // shifted mask with no leading zeros and c3 trailing zeros. + if (LeftShift && isShiftedMask_64(C1)) { + uint64_t Leading = XLen - (64 - countLeadingZeros(C1)); + uint64_t C3 = countTrailingZeros(C1); + if (Leading == 0 && C2 < C3 && OneUseOrZExtW && !ZExtOrANDI) { + SDNode *SRLI = CurDAG->getMachineNode( + RISCV::SRLI, DL, XLenVT, X, + CurDAG->getTargetConstant(C3 - C2, DL, XLenVT)); + SDNode *SLLI = + CurDAG->getMachineNode(RISCV::SLLI, DL, XLenVT, SDValue(SRLI, 0), + CurDAG->getTargetConstant(C3, DL, XLenVT)); + ReplaceNode(Node, SLLI); + return; + } + } + break; } case ISD::INTRINSIC_WO_CHAIN: { diff --git a/llvm/test/CodeGen/RISCV/shift-and.ll b/llvm/test/CodeGen/RISCV/shift-and.ll index 8a6de27..288c2cd 100644 --- a/llvm/test/CodeGen/RISCV/shift-and.ll +++ b/llvm/test/CodeGen/RISCV/shift-and.ll @@ -86,9 +86,8 @@ define i64 @test4(i64 %x) { define i32 @test5(i32 %x) { ; RV32I-LABEL: test5: ; RV32I: # %bb.0: -; RV32I-NEXT: slli a0, a0, 6 -; RV32I-NEXT: lui a1, 1048560 -; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: srli a0, a0, 10 +; RV32I-NEXT: slli a0, a0, 16 ; RV32I-NEXT: ret ; ; RV64I-LABEL: test5: @@ -108,16 +107,14 @@ define i64 @test6(i64 %x) { ; RV32I-NEXT: srli a2, a0, 26 ; RV32I-NEXT: slli a1, a1, 6 ; RV32I-NEXT: or a1, a1, a2 -; RV32I-NEXT: slli a0, a0, 6 -; RV32I-NEXT: lui a2, 1048560 -; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: srli a0, a0, 10 +; RV32I-NEXT: slli a0, a0, 16 ; RV32I-NEXT: ret ; ; RV64I-LABEL: test6: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 6 -; RV64I-NEXT: lui a1, 1048560 -; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: srli a0, a0, 10 +; RV64I-NEXT: slli a0, a0, 16 ; RV64I-NEXT: ret %a = shl i64 %x, 6 %b = and i64 %a, -65536 -- 2.7.4