[llvm] 7cbfb4e - [RISCV] Select (srl (and X, C2) as (slli (srliw X, C3), C3-C).
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 29 09:17:11 PDT 2022
Author: Craig Topper
Date: 2022-06-29T09:15:09-07:00
New Revision: 7cbfb4eb7a9e24ede4a59e9c08d91747d8475e03
URL: https://github.com/llvm/llvm-project/commit/7cbfb4eb7a9e24ede4a59e9c08d91747d8475e03
DIFF: https://github.com/llvm/llvm-project/commit/7cbfb4eb7a9e24ede4a59e9c08d91747d8475e03.diff
LOG: [RISCV] Select (srl (and X, C2) as (slli (srliw X, C3), C3-C).
If C2 has 32 leading zeros and C3 trailing zeros.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/test/CodeGen/RISCV/copysign-casts.ll
llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 3c3412e82a171..74dda1fe6e91c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -712,13 +712,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
return;
}
case ISD::SRL: {
- // Optimize (srl (and X, C2), C) ->
- // (srli (slli X, (XLen-C3), (XLen-C3) + C)
- // Where C2 is a mask with C3 trailing ones.
- // Taking into account that the C2 may have had lower bits unset by
- // SimplifyDemandedBits. This avoids materializing the C2 immediate.
- // This pattern occurs when type legalizing right shifts for types with
- // less than XLen bits.
auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
if (!N1C)
break;
@@ -728,6 +721,32 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
break;
unsigned ShAmt = N1C->getZExtValue();
uint64_t Mask = N0.getConstantOperandVal(1);
+
+ // Optimize (srl (and X, C2), C) -> (slli (srliw X, C3), C3-C) where C2 has
+ // 32 leading zeros and C3 trailing zeros.
+ if (isShiftedMask_64(Mask)) {
+ unsigned XLen = Subtarget->getXLen();
+ unsigned LeadingZeros = XLen - (64 - countLeadingZeros(Mask));
+ unsigned TrailingZeros = countTrailingZeros(Mask);
+ if (LeadingZeros == 32 && TrailingZeros > ShAmt) {
+ SDNode *SRLIW = CurDAG->getMachineNode(
+ RISCV::SRLIW, DL, VT, N0->getOperand(0),
+ CurDAG->getTargetConstant(TrailingZeros, DL, VT));
+ SDNode *SLLI = CurDAG->getMachineNode(
+ RISCV::SLLI, DL, VT, SDValue(SRLIW, 0),
+ CurDAG->getTargetConstant(TrailingZeros - ShAmt, DL, VT));
+ ReplaceNode(Node, SLLI);
+ return;
+ }
+ }
+
+ // Optimize (srl (and X, C2), C) ->
+ // (srli (slli X, (XLen-C3), (XLen-C3) + C)
+ // Where C2 is a mask with C3 trailing ones.
+ // Taking into account that the C2 may have had lower bits unset by
+ // SimplifyDemandedBits. This avoids materializing the C2 immediate.
+ // This pattern occurs when type legalizing right shifts for types with
+ // less than XLen bits.
Mask |= maskTrailingOnes<uint64_t>(ShAmt);
if (!isMask_64(Mask))
break;
diff --git a/llvm/test/CodeGen/RISCV/copysign-casts.ll b/llvm/test/CodeGen/RISCV/copysign-casts.ll
index 42ea6958a9d1b..8d44178437807 100644
--- a/llvm/test/CodeGen/RISCV/copysign-casts.ll
+++ b/llvm/test/CodeGen/RISCV/copysign-casts.ll
@@ -341,10 +341,8 @@ define half @fold_demote_h_s(half %a, float %b) nounwind {
;
; RV64I-LABEL: fold_demote_h_s:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 1
-; RV64I-NEXT: slli a2, a2, 31
-; RV64I-NEXT: and a1, a1, a2
-; RV64I-NEXT: srli a1, a1, 16
+; RV64I-NEXT: srliw a1, a1, 31
+; RV64I-NEXT: slli a1, a1, 15
; RV64I-NEXT: slli a0, a0, 49
; RV64I-NEXT: srli a0, a0, 49
; RV64I-NEXT: or a0, a0, a1
diff --git a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
index a10c6945b7d0b..94366071849ac 100644
--- a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
+++ b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
@@ -37,10 +37,8 @@ define i32 @neg_sel_special_constant(i32 signext %a) {
;
; RV64-LABEL: neg_sel_special_constant:
; RV64: # %bb.0:
-; RV64-NEXT: li a1, 1
-; RV64-NEXT: slli a1, a1, 31
-; RV64-NEXT: and a0, a0, a1
-; RV64-NEXT: srli a0, a0, 22
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: slli a0, a0, 9
; RV64-NEXT: ret
%tmp.1 = icmp slt i32 %a, 0
%retval = select i1 %tmp.1, i32 512, i32 0
More information about the llvm-commits
mailing list