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: _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits