[llvm-branch-commits] [llvm] 5836e52 - [RISCV] Add isel patterns to use SBSET for (1 << X) by using X0 as the input.
Craig Topper via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Nov 26 15:57:42 PST 2020
Author: Craig Topper
Date: 2020-11-26T15:35:13-08:00
New Revision: 5836e52063763e5d1e5f6e08b84a5bf832d0da5d
URL: https://github.com/llvm/llvm-project/commit/5836e52063763e5d1e5f6e08b84a5bf832d0da5d
DIFF: https://github.com/llvm/llvm-project/commit/5836e52063763e5d1e5f6e08b84a5bf832d0da5d.diff
LOG: [RISCV] Add isel patterns to use SBSET for (1 << X) by using X0 as the input.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVInstrInfoB.td
llvm/test/CodeGen/RISCV/rv32Zbs.ll
llvm/test/CodeGen/RISCV/rv64Zbs.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
index e80ef9987b45..7a8a1bc364e1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -689,6 +689,9 @@ def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
(SBINV GPR:$rs1, GPR:$rs2)>;
def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
(SBEXT GPR:$rs1, GPR:$rs2)>;
+
+def : Pat<(shiftop<shl> 1, GPR:$rs2),
+ (SBSET X0, GPR:$rs2)>;
}
let Predicates = [HasStdExtZbb] in {
@@ -905,6 +908,9 @@ def : Pat<(sext_inreg (xor (riscv_sllw 1, GPR:$rs2), GPR:$rs1), i32),
(SBINVW GPR:$rs1, GPR:$rs2)>;
def : Pat<(and (riscv_srlw GPR:$rs1, GPR:$rs2), 1),
(SBEXTW GPR:$rs1, GPR:$rs2)>;
+
+def : Pat<(riscv_sllw 1, GPR:$rs2),
+ (SBSETW X0, GPR:$rs2)>;
} // Predicates = [HasStdExtZbs, IsRV64]
let Predicates = [HasStdExtZbb, IsRV64] in {
diff --git a/llvm/test/CodeGen/RISCV/rv32Zbs.ll b/llvm/test/CodeGen/RISCV/rv32Zbs.ll
index 56e8ac57bc7c..355389340da5 100644
--- a/llvm/test/CodeGen/RISCV/rv32Zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv32Zbs.ll
@@ -79,36 +79,34 @@ define i64 @sbclr_i64(i64 %a, i64 %b) nounwind {
; RV32IB-LABEL: sbclr_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: andi a3, a2, 63
-; RV32IB-NEXT: addi a4, a3, -32
-; RV32IB-NEXT: addi a3, zero, 1
-; RV32IB-NEXT: bltz a4, .LBB2_2
+; RV32IB-NEXT: addi a3, a3, -32
+; RV32IB-NEXT: bltz a3, .LBB2_2
; RV32IB-NEXT: # %bb.1:
; RV32IB-NEXT: mv a2, zero
-; RV32IB-NEXT: sll a4, a3, a4
+; RV32IB-NEXT: sbset a3, zero, a3
; RV32IB-NEXT: j .LBB2_3
; RV32IB-NEXT: .LBB2_2:
-; RV32IB-NEXT: mv a4, zero
-; RV32IB-NEXT: sll a2, a3, a2
+; RV32IB-NEXT: mv a3, zero
+; RV32IB-NEXT: sbset a2, zero, a2
; RV32IB-NEXT: .LBB2_3:
; RV32IB-NEXT: andn a0, a0, a2
-; RV32IB-NEXT: andn a1, a1, a4
+; RV32IB-NEXT: andn a1, a1, a3
; RV32IB-NEXT: ret
;
; RV32IBS-LABEL: sbclr_i64:
; RV32IBS: # %bb.0:
; RV32IBS-NEXT: andi a3, a2, 63
-; RV32IBS-NEXT: addi a4, a3, -32
-; RV32IBS-NEXT: addi a3, zero, 1
-; RV32IBS-NEXT: bltz a4, .LBB2_2
+; RV32IBS-NEXT: addi a3, a3, -32
+; RV32IBS-NEXT: bltz a3, .LBB2_2
; RV32IBS-NEXT: # %bb.1:
; RV32IBS-NEXT: mv a2, zero
-; RV32IBS-NEXT: sll a4, a3, a4
+; RV32IBS-NEXT: sbset a3, zero, a3
; RV32IBS-NEXT: j .LBB2_3
; RV32IBS-NEXT: .LBB2_2:
-; RV32IBS-NEXT: mv a4, zero
-; RV32IBS-NEXT: sll a2, a3, a2
+; RV32IBS-NEXT: mv a3, zero
+; RV32IBS-NEXT: sbset a2, zero, a2
; RV32IBS-NEXT: .LBB2_3:
-; RV32IBS-NEXT: not a3, a4
+; RV32IBS-NEXT: not a3, a3
; RV32IBS-NEXT: not a2, a2
; RV32IBS-NEXT: and a0, a2, a0
; RV32IBS-NEXT: and a1, a3, a1
@@ -165,6 +163,27 @@ define i32 @sbset_i32_no_mask(i32 %a, i32 %b) nounwind {
ret i32 %or
}
+; We can use sbsetw for 1 << x by setting the first source to zero.
+define signext i32 @sbset_i32_zero(i32 signext %a) nounwind {
+; RV32I-LABEL: sbset_i32_zero:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi a1, zero, 1
+; RV32I-NEXT: sll a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32IB-LABEL: sbset_i32_zero:
+; RV32IB: # %bb.0:
+; RV32IB-NEXT: sbset a0, zero, a0
+; RV32IB-NEXT: ret
+;
+; RV32IBS-LABEL: sbset_i32_zero:
+; RV32IBS: # %bb.0:
+; RV32IBS-NEXT: sbset a0, zero, a0
+; RV32IBS-NEXT: ret
+ %shl = shl i32 1, %a
+ ret i32 %shl
+}
+
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
; don't have yet any matching bit manipulation instructions on RV32.
; This test is presented here in case future expansions of the experimental-b
@@ -182,8 +201,7 @@ define i64 @sbset_i64(i64 %a, i64 %b) nounwind {
;
; RV32IB-LABEL: sbset_i64:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: addi a3, zero, 1
-; RV32IB-NEXT: sll a3, a3, a2
+; RV32IB-NEXT: sbset a3, zero, a2
; RV32IB-NEXT: srai a3, a3, 31
; RV32IB-NEXT: sbset a0, a0, a2
; RV32IB-NEXT: or a1, a3, a1
@@ -191,8 +209,7 @@ define i64 @sbset_i64(i64 %a, i64 %b) nounwind {
;
; RV32IBS-LABEL: sbset_i64:
; RV32IBS: # %bb.0:
-; RV32IBS-NEXT: addi a3, zero, 1
-; RV32IBS-NEXT: sll a3, a3, a2
+; RV32IBS-NEXT: sbset a3, zero, a2
; RV32IBS-NEXT: srai a3, a3, 31
; RV32IBS-NEXT: sbset a0, a0, a2
; RV32IBS-NEXT: or a1, a3, a1
@@ -205,6 +222,50 @@ define i64 @sbset_i64(i64 %a, i64 %b) nounwind {
ret i64 %or
}
+define signext i64 @sbset_i64_zero(i64 signext %a) nounwind {
+; RV32I-LABEL: sbset_i64_zero:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi a1, a0, -32
+; RV32I-NEXT: addi a2, zero, 1
+; RV32I-NEXT: bltz a1, .LBB7_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: mv a0, zero
+; RV32I-NEXT: sll a1, a2, a1
+; RV32I-NEXT: ret
+; RV32I-NEXT: .LBB7_2:
+; RV32I-NEXT: mv a1, zero
+; RV32I-NEXT: sll a0, a2, a0
+; RV32I-NEXT: ret
+;
+; RV32IB-LABEL: sbset_i64_zero:
+; RV32IB: # %bb.0:
+; RV32IB-NEXT: addi a1, a0, -32
+; RV32IB-NEXT: bltz a1, .LBB7_2
+; RV32IB-NEXT: # %bb.1:
+; RV32IB-NEXT: mv a0, zero
+; RV32IB-NEXT: sbset a1, zero, a1
+; RV32IB-NEXT: ret
+; RV32IB-NEXT: .LBB7_2:
+; RV32IB-NEXT: mv a1, zero
+; RV32IB-NEXT: sbset a0, zero, a0
+; RV32IB-NEXT: ret
+;
+; RV32IBS-LABEL: sbset_i64_zero:
+; RV32IBS: # %bb.0:
+; RV32IBS-NEXT: addi a1, a0, -32
+; RV32IBS-NEXT: bltz a1, .LBB7_2
+; RV32IBS-NEXT: # %bb.1:
+; RV32IBS-NEXT: mv a0, zero
+; RV32IBS-NEXT: sbset a1, zero, a1
+; RV32IBS-NEXT: ret
+; RV32IBS-NEXT: .LBB7_2:
+; RV32IBS-NEXT: mv a1, zero
+; RV32IBS-NEXT: sbset a0, zero, a0
+; RV32IBS-NEXT: ret
+ %shl = shl i64 1, %a
+ ret i64 %shl
+}
+
define i32 @sbinv_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: sbinv_i32:
; RV32I: # %bb.0:
@@ -245,8 +306,7 @@ define i64 @sbinv_i64(i64 %a, i64 %b) nounwind {
;
; RV32IB-LABEL: sbinv_i64:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: addi a3, zero, 1
-; RV32IB-NEXT: sll a3, a3, a2
+; RV32IB-NEXT: sbset a3, zero, a2
; RV32IB-NEXT: srai a3, a3, 31
; RV32IB-NEXT: sbinv a0, a0, a2
; RV32IB-NEXT: xor a1, a3, a1
@@ -254,8 +314,7 @@ define i64 @sbinv_i64(i64 %a, i64 %b) nounwind {
;
; RV32IBS-LABEL: sbinv_i64:
; RV32IBS: # %bb.0:
-; RV32IBS-NEXT: addi a3, zero, 1
-; RV32IBS-NEXT: sll a3, a3, a2
+; RV32IBS-NEXT: sbset a3, zero, a2
; RV32IBS-NEXT: srai a3, a3, 31
; RV32IBS-NEXT: sbinv a0, a0, a2
; RV32IBS-NEXT: xor a1, a3, a1
@@ -321,18 +380,18 @@ define i64 @sbext_i64(i64 %a, i64 %b) nounwind {
; RV32I: # %bb.0:
; RV32I-NEXT: andi a3, a2, 63
; RV32I-NEXT: addi a4, a3, -32
-; RV32I-NEXT: bltz a4, .LBB10_2
+; RV32I-NEXT: bltz a4, .LBB12_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srl a0, a1, a4
-; RV32I-NEXT: j .LBB10_3
-; RV32I-NEXT: .LBB10_2:
+; RV32I-NEXT: j .LBB12_3
+; RV32I-NEXT: .LBB12_2:
; RV32I-NEXT: srl a0, a0, a2
; RV32I-NEXT: addi a2, zero, 31
; RV32I-NEXT: sub a2, a2, a3
; RV32I-NEXT: slli a1, a1, 1
; RV32I-NEXT: sll a1, a1, a2
; RV32I-NEXT: or a0, a0, a1
-; RV32I-NEXT: .LBB10_3:
+; RV32I-NEXT: .LBB12_3:
; RV32I-NEXT: andi a0, a0, 1
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: ret
@@ -341,18 +400,18 @@ define i64 @sbext_i64(i64 %a, i64 %b) nounwind {
; RV32IB: # %bb.0:
; RV32IB-NEXT: andi a3, a2, 63
; RV32IB-NEXT: addi a4, a3, -32
-; RV32IB-NEXT: bltz a4, .LBB10_2
+; RV32IB-NEXT: bltz a4, .LBB12_2
; RV32IB-NEXT: # %bb.1:
; RV32IB-NEXT: srl a0, a1, a4
-; RV32IB-NEXT: j .LBB10_3
-; RV32IB-NEXT: .LBB10_2:
+; RV32IB-NEXT: j .LBB12_3
+; RV32IB-NEXT: .LBB12_2:
; RV32IB-NEXT: srl a0, a0, a2
; RV32IB-NEXT: addi a2, zero, 31
; RV32IB-NEXT: sub a2, a2, a3
; RV32IB-NEXT: slli a1, a1, 1
; RV32IB-NEXT: sll a1, a1, a2
; RV32IB-NEXT: or a0, a0, a1
-; RV32IB-NEXT: .LBB10_3:
+; RV32IB-NEXT: .LBB12_3:
; RV32IB-NEXT: andi a0, a0, 1
; RV32IB-NEXT: mv a1, zero
; RV32IB-NEXT: ret
@@ -361,18 +420,18 @@ define i64 @sbext_i64(i64 %a, i64 %b) nounwind {
; RV32IBS: # %bb.0:
; RV32IBS-NEXT: andi a3, a2, 63
; RV32IBS-NEXT: addi a4, a3, -32
-; RV32IBS-NEXT: bltz a4, .LBB10_2
+; RV32IBS-NEXT: bltz a4, .LBB12_2
; RV32IBS-NEXT: # %bb.1:
; RV32IBS-NEXT: srl a0, a1, a4
-; RV32IBS-NEXT: j .LBB10_3
-; RV32IBS-NEXT: .LBB10_2:
+; RV32IBS-NEXT: j .LBB12_3
+; RV32IBS-NEXT: .LBB12_2:
; RV32IBS-NEXT: srl a0, a0, a2
; RV32IBS-NEXT: addi a2, zero, 31
; RV32IBS-NEXT: sub a2, a2, a3
; RV32IBS-NEXT: slli a1, a1, 1
; RV32IBS-NEXT: sll a1, a1, a2
; RV32IBS-NEXT: or a0, a0, a1
-; RV32IBS-NEXT: .LBB10_3:
+; RV32IBS-NEXT: .LBB12_3:
; RV32IBS-NEXT: andi a0, a0, 1
; RV32IBS-NEXT: mv a1, zero
; RV32IBS-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rv64Zbs.ll b/llvm/test/CodeGen/RISCV/rv64Zbs.ll
index 85d1bd5b3c2f..e50b7a24c536 100644
--- a/llvm/test/CodeGen/RISCV/rv64Zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv64Zbs.ll
@@ -205,6 +205,27 @@ define signext i32 @sbset_i32_load(i32* %p, i32 signext %b) nounwind {
ret i32 %or
}
+; We can use sbsetw for 1 << x by setting the first source to zero.
+define signext i32 @sbset_i32_zero(i32 signext %a) nounwind {
+; RV64I-LABEL: sbset_i32_zero:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi a1, zero, 1
+; RV64I-NEXT: sllw a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64IB-LABEL: sbset_i32_zero:
+; RV64IB: # %bb.0:
+; RV64IB-NEXT: sbsetw a0, zero, a0
+; RV64IB-NEXT: ret
+;
+; RV64IBS-LABEL: sbset_i32_zero:
+; RV64IBS: # %bb.0:
+; RV64IBS-NEXT: sbsetw a0, zero, a0
+; RV64IBS-NEXT: ret
+ %shl = shl i32 1, %a
+ ret i32 %shl
+}
+
define i64 @sbset_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: sbset_i64:
; RV64I: # %bb.0:
@@ -250,6 +271,27 @@ define i64 @sbset_i64_no_mask(i64 %a, i64 %b) nounwind {
ret i64 %or
}
+; We can use sbsetw for 1 << x by setting the first source to zero.
+define signext i64 @sbset_i64_zero(i64 signext %a) nounwind {
+; RV64I-LABEL: sbset_i64_zero:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi a1, zero, 1
+; RV64I-NEXT: sll a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64IB-LABEL: sbset_i64_zero:
+; RV64IB: # %bb.0:
+; RV64IB-NEXT: sbset a0, zero, a0
+; RV64IB-NEXT: ret
+;
+; RV64IBS-LABEL: sbset_i64_zero:
+; RV64IBS: # %bb.0:
+; RV64IBS-NEXT: sbset a0, zero, a0
+; RV64IBS-NEXT: ret
+ %shl = shl i64 1, %a
+ ret i64 %shl
+}
+
define signext i32 @sbinv_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: sbinv_i32:
; RV64I: # %bb.0:
More information about the llvm-branch-commits
mailing list