[llvm] 6db0afb - [RISCV] Fold (xor (sllw 1, x), -1) -> (rolw ~1, x).
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 19 15:04:57 PDT 2022
Author: Craig Topper
Date: 2022-04-19T15:03:43-07:00
New Revision: 6db0afb44e13cf5f3d3261387079b32358966a61
URL: https://github.com/llvm/llvm-project/commit/6db0afb44e13cf5f3d3261387079b32358966a61
DIFF: https://github.com/llvm/llvm-project/commit/6db0afb44e13cf5f3d3261387079b32358966a61.diff
LOG: [RISCV] Fold (xor (sllw 1, x), -1) -> (rolw ~1, x).
There's an existing generic combine that does this for legal types.
This patch adds a RISCV specific combine for W instructions.
Reviewed By: luismarques
Differential Revision: https://reviews.llvm.org/D123983
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll
llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll
llvm/test/CodeGen/RISCV/sextw-removal.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 695cca18c1f19..2d64acdaee128 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7945,6 +7945,20 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
}
static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+
+ // fold (xor (sllw 1, x), -1) -> (rolw ~1, x)
+ // NOTE: Assumes ROL being legal means ROLW is legal.
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (N0.getOpcode() == RISCVISD::SLLW &&
+ isAllOnesConstant(N1) && isOneConstant(N0.getOperand(0)) &&
+ TLI.isOperationLegal(ISD::ROTL, MVT::i64)) {
+ SDLoc DL(N);
+ return DAG.getNode(RISCVISD::ROLW, DL, MVT::i64,
+ DAG.getConstant(~1, DL, MVT::i64), N0.getOperand(1));
+ }
+
// fold (xor (select cond, 0, y), x) ->
// (select cond, x, (xor x, y))
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false);
diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll
index 0930433568a36..da0a862f26d59 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll
@@ -349,6 +349,59 @@ define i64 @rori_i64_fshr(i64 %a) nounwind {
ret i64 %1
}
+define i32 @not_shl_one_i32(i32 %x) {
+; RV32I-LABEL: not_shl_one_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: li a1, 1
+; RV32I-NEXT: sll a0, a1, a0
+; RV32I-NEXT: not a0, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBP-ZBKB-LABEL: not_shl_one_i32:
+; RV32ZBB-ZBP-ZBKB: # %bb.0:
+; RV32ZBB-ZBP-ZBKB-NEXT: li a1, -2
+; RV32ZBB-ZBP-ZBKB-NEXT: rol a0, a1, a0
+; RV32ZBB-ZBP-ZBKB-NEXT: ret
+ %1 = shl i32 1, %x
+ %2 = xor i32 %1, -1
+ ret i32 %2
+}
+
+define i64 @not_shl_one_i64(i64 %x) {
+; RV32I-LABEL: not_shl_one_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi a3, a0, -32
+; RV32I-NEXT: li a2, 1
+; RV32I-NEXT: li a1, -1
+; RV32I-NEXT: bltz a3, .LBB15_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: sll a0, a2, a3
+; RV32I-NEXT: not a1, a0
+; RV32I-NEXT: li a0, -1
+; RV32I-NEXT: ret
+; RV32I-NEXT: .LBB15_2:
+; RV32I-NEXT: sll a0, a2, a0
+; RV32I-NEXT: not a0, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBP-ZBKB-LABEL: not_shl_one_i64:
+; RV32ZBB-ZBP-ZBKB: # %bb.0:
+; RV32ZBB-ZBP-ZBKB-NEXT: addi a3, a0, -32
+; RV32ZBB-ZBP-ZBKB-NEXT: li a2, -2
+; RV32ZBB-ZBP-ZBKB-NEXT: li a1, -1
+; RV32ZBB-ZBP-ZBKB-NEXT: bltz a3, .LBB15_2
+; RV32ZBB-ZBP-ZBKB-NEXT: # %bb.1:
+; RV32ZBB-ZBP-ZBKB-NEXT: rol a1, a2, a3
+; RV32ZBB-ZBP-ZBKB-NEXT: li a0, -1
+; RV32ZBB-ZBP-ZBKB-NEXT: ret
+; RV32ZBB-ZBP-ZBKB-NEXT: .LBB15_2:
+; RV32ZBB-ZBP-ZBKB-NEXT: rol a0, a2, a0
+; RV32ZBB-ZBP-ZBKB-NEXT: ret
+ %1 = shl i64 1, %x
+ %2 = xor i64 %1, -1
+ ret i64 %2
+}
+
define i8 @srli_i8(i8 %a) nounwind {
; RV32I-LABEL: srli_i8:
; RV32I: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll
index d519b14068868..4a3e4e322673f 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll
@@ -420,6 +420,42 @@ define i64 @rori_i64_fshr(i64 %a) nounwind {
ret i64 %1
}
+define signext i32 @not_shl_one_i32(i32 signext %x) {
+; RV64I-LABEL: not_shl_one_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: li a1, 1
+; RV64I-NEXT: sllw a0, a1, a0
+; RV64I-NEXT: not a0, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBB-ZBP-ZBKB-LABEL: not_shl_one_i32:
+; RV64ZBB-ZBP-ZBKB: # %bb.0:
+; RV64ZBB-ZBP-ZBKB-NEXT: li a1, -2
+; RV64ZBB-ZBP-ZBKB-NEXT: rolw a0, a1, a0
+; RV64ZBB-ZBP-ZBKB-NEXT: ret
+ %1 = shl i32 1, %x
+ %2 = xor i32 %1, -1
+ ret i32 %2
+}
+
+define i64 @not_shl_one_i64(i64 %x) {
+; RV64I-LABEL: not_shl_one_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: li a1, 1
+; RV64I-NEXT: sll a0, a1, a0
+; RV64I-NEXT: not a0, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBB-ZBP-ZBKB-LABEL: not_shl_one_i64:
+; RV64ZBB-ZBP-ZBKB: # %bb.0:
+; RV64ZBB-ZBP-ZBKB-NEXT: li a1, -2
+; RV64ZBB-ZBP-ZBKB-NEXT: rol a0, a1, a0
+; RV64ZBB-ZBP-ZBKB-NEXT: ret
+ %1 = shl i64 1, %x
+ %2 = xor i64 %1, -1
+ ret i64 %2
+}
+
define i8 @srli_i8(i8 %a) nounwind {
; RV64I-LABEL: srli_i8:
; RV64I: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/sextw-removal.ll b/llvm/test/CodeGen/RISCV/sextw-removal.ll
index cceae85a6ecfc..78a661fd94223 100644
--- a/llvm/test/CodeGen/RISCV/sextw-removal.ll
+++ b/llvm/test/CodeGen/RISCV/sextw-removal.ll
@@ -81,17 +81,17 @@ define signext i32 @test2(i32* %p, i32 signext %b) nounwind {
; RV64ZBB-LABEL: test2:
; RV64ZBB: # %bb.0:
; RV64ZBB-NEXT: lw a0, 0(a0)
-; RV64ZBB-NEXT: li a2, 1
-; RV64ZBB-NEXT: sllw a1, a2, a1
-; RV64ZBB-NEXT: andn a0, a0, a1
+; RV64ZBB-NEXT: li a2, -2
+; RV64ZBB-NEXT: rolw a1, a2, a1
+; RV64ZBB-NEXT: and a0, a1, a0
; RV64ZBB-NEXT: ret
;
; NOREMOVAL-LABEL: test2:
; NOREMOVAL: # %bb.0:
; NOREMOVAL-NEXT: lw a0, 0(a0)
-; NOREMOVAL-NEXT: li a2, 1
-; NOREMOVAL-NEXT: sllw a1, a2, a1
-; NOREMOVAL-NEXT: andn a0, a0, a1
+; NOREMOVAL-NEXT: li a2, -2
+; NOREMOVAL-NEXT: rolw a1, a2, a1
+; NOREMOVAL-NEXT: and a0, a1, a0
; NOREMOVAL-NEXT: sext.w a0, a0
; NOREMOVAL-NEXT: ret
%a = load i32, i32* %p
@@ -114,17 +114,17 @@ define signext i32 @test3(i32* %p, i32 signext %b) nounwind {
; RV64ZBB-LABEL: test3:
; RV64ZBB: # %bb.0:
; RV64ZBB-NEXT: lw a0, 0(a0)
-; RV64ZBB-NEXT: li a2, 1
-; RV64ZBB-NEXT: sllw a1, a2, a1
-; RV64ZBB-NEXT: orn a0, a0, a1
+; RV64ZBB-NEXT: li a2, -2
+; RV64ZBB-NEXT: rolw a1, a2, a1
+; RV64ZBB-NEXT: or a0, a1, a0
; RV64ZBB-NEXT: ret
;
; NOREMOVAL-LABEL: test3:
; NOREMOVAL: # %bb.0:
; NOREMOVAL-NEXT: lw a0, 0(a0)
-; NOREMOVAL-NEXT: li a2, 1
-; NOREMOVAL-NEXT: sllw a1, a2, a1
-; NOREMOVAL-NEXT: orn a0, a0, a1
+; NOREMOVAL-NEXT: li a2, -2
+; NOREMOVAL-NEXT: rolw a1, a2, a1
+; NOREMOVAL-NEXT: or a0, a1, a0
; NOREMOVAL-NEXT: sext.w a0, a0
; NOREMOVAL-NEXT: ret
%a = load i32, i32* %p
More information about the llvm-commits
mailing list