[llvm] [RISCV] and x (sub 0, y) -> andn x y (PR #129253)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 28 07:22:05 PST 2025
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/129253
>From a1094b21d0226d8993ab43bfd39fdf32490b4db6 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Fri, 28 Feb 2025 15:38:00 +0100
Subject: [PATCH 1/2] [RISCV][SelDAG] and x (sub 0, y) -> andn x y
---
llvm/lib/Target/RISCV/RISCVInstrInfoZb.td | 1 +
.../CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll | 329 +++++++++++++-----
.../CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll | 27 ++
llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll | 94 +++--
llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll | 27 ++
5 files changed, 362 insertions(+), 116 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index 2ce909c5d0e21..92d126fb8bcf9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -483,6 +483,7 @@ def invLogicImm : ComplexPattern<XLenVT, 1, "selectInvLogicImm", [], [], 0>;
let Predicates = [HasStdExtZbbOrZbkb] in {
def : Pat<(XLenVT (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
+def : Pat<(XLenVT (and GPR:$rs1, (sub 0, GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
def : Pat<(XLenVT (or GPR:$rs1, (not GPR:$rs2))), (ORN GPR:$rs1, GPR:$rs2)>;
def : Pat<(XLenVT (xor GPR:$rs1, (not GPR:$rs2))), (XNOR GPR:$rs1, GPR:$rs2)>;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll
index ababec16f7f8f..03a3e4b3ff742 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll
@@ -22,6 +22,22 @@ define i32 @andn_i32(i32 %a, i32 %b) nounwind {
ret i32 %and
}
+define i32 @andn_i32_from_sub(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: andn_i32_from_sub:
+; RV32I: # %bb.0:
+; RV32I-NEXT: neg a1, a1
+; RV32I-NEXT: and a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: andn_i32_from_sub:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1
+; RV32ZBB-ZBKB-NEXT: ret
+ %neg = sub i32 0, %b
+ %and = and i32 %neg, %a
+ ret i32 %and
+}
+
define i64 @andn_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: andn_i64:
; RV32I: # %bb.0:
@@ -41,6 +57,30 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
ret i64 %and
}
+define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
+; RV32I-LABEL: andn_i64_from_sub:
+; RV32I: # %bb.0:
+; RV32I-NEXT: neg a4, a2
+; RV32I-NEXT: snez a2, a2
+; RV32I-NEXT: neg a3, a3
+; RV32I-NEXT: sub a3, a3, a2
+; RV32I-NEXT: and a0, a4, a0
+; RV32I-NEXT: and a1, a3, a1
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: andn_i64_from_sub:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: snez a4, a2
+; RV32ZBB-ZBKB-NEXT: neg a3, a3
+; RV32ZBB-ZBKB-NEXT: sub a3, a3, a4
+; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2
+; RV32ZBB-ZBKB-NEXT: and a1, a3, a1
+; RV32ZBB-ZBKB-NEXT: ret
+ %neg = sub i64 0, %b
+ %and = and i64 %neg, %a
+ ret i64 %and
+}
+
define i32 @orn_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: orn_i32:
; RV32I: # %bb.0:
@@ -136,53 +176,102 @@ define i32 @rol_i32(i32 %a, i32 %b) nounwind {
declare i64 @llvm.fshl.i64(i64, i64, i64)
define i64 @rol_i64(i64 %a, i64 %b) nounwind {
-; CHECK-LABEL: rol_i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: andi a6, a2, 63
-; CHECK-NEXT: li a4, 32
-; CHECK-NEXT: bltu a6, a4, .LBB7_2
-; CHECK-NEXT: # %bb.1:
-; CHECK-NEXT: li a3, 0
-; CHECK-NEXT: sll a7, a0, a6
-; CHECK-NEXT: j .LBB7_3
-; CHECK-NEXT: .LBB7_2:
-; CHECK-NEXT: sll a3, a0, a2
-; CHECK-NEXT: neg a5, a6
-; CHECK-NEXT: srl a5, a0, a5
-; CHECK-NEXT: sll a7, a1, a2
-; CHECK-NEXT: or a7, a5, a7
-; CHECK-NEXT: .LBB7_3:
-; CHECK-NEXT: neg a5, a2
-; CHECK-NEXT: mv a2, a1
-; CHECK-NEXT: beqz a6, .LBB7_5
-; CHECK-NEXT: # %bb.4:
-; CHECK-NEXT: mv a2, a7
-; CHECK-NEXT: .LBB7_5:
-; CHECK-NEXT: andi a6, a5, 63
-; CHECK-NEXT: bltu a6, a4, .LBB7_7
-; CHECK-NEXT: # %bb.6:
-; CHECK-NEXT: srl a7, a1, a6
-; CHECK-NEXT: bnez a6, .LBB7_8
-; CHECK-NEXT: j .LBB7_9
-; CHECK-NEXT: .LBB7_7:
-; CHECK-NEXT: srl a7, a0, a5
-; CHECK-NEXT: neg t0, a6
-; CHECK-NEXT: sll t0, a1, t0
-; CHECK-NEXT: or a7, a7, t0
-; CHECK-NEXT: beqz a6, .LBB7_9
-; CHECK-NEXT: .LBB7_8:
-; CHECK-NEXT: mv a0, a7
-; CHECK-NEXT: .LBB7_9:
-; CHECK-NEXT: bltu a6, a4, .LBB7_11
-; CHECK-NEXT: # %bb.10:
-; CHECK-NEXT: li a1, 0
-; CHECK-NEXT: j .LBB7_12
-; CHECK-NEXT: .LBB7_11:
-; CHECK-NEXT: srl a1, a1, a5
-; CHECK-NEXT: .LBB7_12:
-; CHECK-NEXT: or a0, a3, a0
-; CHECK-NEXT: or a1, a2, a1
-; CHECK-NEXT: ret
+; RV32I-LABEL: rol_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: andi a6, a2, 63
+; RV32I-NEXT: li a4, 32
+; RV32I-NEXT: bltu a6, a4, .LBB9_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: li a3, 0
+; RV32I-NEXT: sll a7, a0, a6
+; RV32I-NEXT: j .LBB9_3
+; RV32I-NEXT: .LBB9_2:
+; RV32I-NEXT: sll a3, a0, a2
+; RV32I-NEXT: neg a5, a6
+; RV32I-NEXT: srl a5, a0, a5
+; RV32I-NEXT: sll a7, a1, a2
+; RV32I-NEXT: or a7, a5, a7
+; RV32I-NEXT: .LBB9_3:
+; RV32I-NEXT: neg a5, a2
+; RV32I-NEXT: mv a2, a1
+; RV32I-NEXT: beqz a6, .LBB9_5
+; RV32I-NEXT: # %bb.4:
+; RV32I-NEXT: mv a2, a7
+; RV32I-NEXT: .LBB9_5:
+; RV32I-NEXT: andi a6, a5, 63
+; RV32I-NEXT: bltu a6, a4, .LBB9_7
+; RV32I-NEXT: # %bb.6:
+; RV32I-NEXT: srl a7, a1, a6
+; RV32I-NEXT: bnez a6, .LBB9_8
+; RV32I-NEXT: j .LBB9_9
+; RV32I-NEXT: .LBB9_7:
+; RV32I-NEXT: srl a7, a0, a5
+; RV32I-NEXT: neg t0, a6
+; RV32I-NEXT: sll t0, a1, t0
+; RV32I-NEXT: or a7, a7, t0
+; RV32I-NEXT: beqz a6, .LBB9_9
+; RV32I-NEXT: .LBB9_8:
+; RV32I-NEXT: mv a0, a7
+; RV32I-NEXT: .LBB9_9:
+; RV32I-NEXT: bltu a6, a4, .LBB9_11
+; RV32I-NEXT: # %bb.10:
+; RV32I-NEXT: li a1, 0
+; RV32I-NEXT: j .LBB9_12
+; RV32I-NEXT: .LBB9_11:
+; RV32I-NEXT: srl a1, a1, a5
+; RV32I-NEXT: .LBB9_12:
+; RV32I-NEXT: or a0, a3, a0
+; RV32I-NEXT: or a1, a2, a1
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: rol_i64:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: andi a6, a2, 63
+; RV32ZBB-ZBKB-NEXT: li a4, 32
+; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_2
+; RV32ZBB-ZBKB-NEXT: # %bb.1:
+; RV32ZBB-ZBKB-NEXT: li a3, 0
+; RV32ZBB-ZBKB-NEXT: sll a7, a0, a6
+; RV32ZBB-ZBKB-NEXT: j .LBB9_3
+; RV32ZBB-ZBKB-NEXT: .LBB9_2:
+; RV32ZBB-ZBKB-NEXT: sll a3, a0, a2
+; RV32ZBB-ZBKB-NEXT: neg a5, a6
+; RV32ZBB-ZBKB-NEXT: srl a5, a0, a5
+; RV32ZBB-ZBKB-NEXT: sll a7, a1, a2
+; RV32ZBB-ZBKB-NEXT: or a7, a5, a7
+; RV32ZBB-ZBKB-NEXT: .LBB9_3:
+; RV32ZBB-ZBKB-NEXT: li t0, 63
+; RV32ZBB-ZBKB-NEXT: mv a5, a1
+; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB9_5
+; RV32ZBB-ZBKB-NEXT: # %bb.4:
+; RV32ZBB-ZBKB-NEXT: mv a5, a7
+; RV32ZBB-ZBKB-NEXT: .LBB9_5:
+; RV32ZBB-ZBKB-NEXT: andn a6, t0, a2
+; RV32ZBB-ZBKB-NEXT: neg a2, a2
+; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_7
+; RV32ZBB-ZBKB-NEXT: # %bb.6:
+; RV32ZBB-ZBKB-NEXT: srl a7, a1, a6
+; RV32ZBB-ZBKB-NEXT: bnez a6, .LBB9_8
+; RV32ZBB-ZBKB-NEXT: j .LBB9_9
+; RV32ZBB-ZBKB-NEXT: .LBB9_7:
+; RV32ZBB-ZBKB-NEXT: srl a7, a0, a2
+; RV32ZBB-ZBKB-NEXT: neg t0, a6
+; RV32ZBB-ZBKB-NEXT: sll t0, a1, t0
+; RV32ZBB-ZBKB-NEXT: or a7, a7, t0
+; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB9_9
+; RV32ZBB-ZBKB-NEXT: .LBB9_8:
+; RV32ZBB-ZBKB-NEXT: mv a0, a7
+; RV32ZBB-ZBKB-NEXT: .LBB9_9:
+; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_11
+; RV32ZBB-ZBKB-NEXT: # %bb.10:
+; RV32ZBB-ZBKB-NEXT: li a1, 0
+; RV32ZBB-ZBKB-NEXT: j .LBB9_12
+; RV32ZBB-ZBKB-NEXT: .LBB9_11:
+; RV32ZBB-ZBKB-NEXT: srl a1, a1, a2
+; RV32ZBB-ZBKB-NEXT: .LBB9_12:
+; RV32ZBB-ZBKB-NEXT: or a0, a3, a0
+; RV32ZBB-ZBKB-NEXT: or a1, a5, a1
+; RV32ZBB-ZBKB-NEXT: ret
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
ret i64 %or
}
@@ -212,54 +301,104 @@ define i32 @ror_i32(i32 %a, i32 %b) nounwind {
declare i64 @llvm.fshr.i64(i64, i64, i64)
define i64 @ror_i64(i64 %a, i64 %b) nounwind {
-; CHECK-LABEL: ror_i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: andi a5, a2, 63
-; CHECK-NEXT: li a4, 32
-; CHECK-NEXT: bltu a5, a4, .LBB9_2
-; CHECK-NEXT: # %bb.1:
-; CHECK-NEXT: srl a6, a1, a5
-; CHECK-NEXT: mv a3, a0
-; CHECK-NEXT: bnez a5, .LBB9_3
-; CHECK-NEXT: j .LBB9_4
-; CHECK-NEXT: .LBB9_2:
-; CHECK-NEXT: srl a3, a0, a2
-; CHECK-NEXT: neg a6, a5
-; CHECK-NEXT: sll a6, a1, a6
-; CHECK-NEXT: or a6, a3, a6
-; CHECK-NEXT: mv a3, a0
-; CHECK-NEXT: beqz a5, .LBB9_4
-; CHECK-NEXT: .LBB9_3:
-; CHECK-NEXT: mv a3, a6
-; CHECK-NEXT: .LBB9_4:
-; CHECK-NEXT: neg a6, a2
-; CHECK-NEXT: bltu a5, a4, .LBB9_7
-; CHECK-NEXT: # %bb.5:
-; CHECK-NEXT: li a2, 0
-; CHECK-NEXT: andi a5, a6, 63
-; CHECK-NEXT: bgeu a5, a4, .LBB9_8
-; CHECK-NEXT: .LBB9_6:
-; CHECK-NEXT: sll a4, a0, a6
-; CHECK-NEXT: neg a7, a5
-; CHECK-NEXT: srl a0, a0, a7
-; CHECK-NEXT: sll a6, a1, a6
-; CHECK-NEXT: or a0, a0, a6
-; CHECK-NEXT: bnez a5, .LBB9_9
-; CHECK-NEXT: j .LBB9_10
-; CHECK-NEXT: .LBB9_7:
-; CHECK-NEXT: srl a2, a1, a2
-; CHECK-NEXT: andi a5, a6, 63
-; CHECK-NEXT: bltu a5, a4, .LBB9_6
-; CHECK-NEXT: .LBB9_8:
-; CHECK-NEXT: li a4, 0
-; CHECK-NEXT: sll a0, a0, a5
-; CHECK-NEXT: beqz a5, .LBB9_10
-; CHECK-NEXT: .LBB9_9:
-; CHECK-NEXT: mv a1, a0
-; CHECK-NEXT: .LBB9_10:
-; CHECK-NEXT: or a0, a3, a4
-; CHECK-NEXT: or a1, a2, a1
-; CHECK-NEXT: ret
+; RV32I-LABEL: ror_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: andi a5, a2, 63
+; RV32I-NEXT: li a4, 32
+; RV32I-NEXT: bltu a5, a4, .LBB11_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: srl a6, a1, a5
+; RV32I-NEXT: mv a3, a0
+; RV32I-NEXT: bnez a5, .LBB11_3
+; RV32I-NEXT: j .LBB11_4
+; RV32I-NEXT: .LBB11_2:
+; RV32I-NEXT: srl a3, a0, a2
+; RV32I-NEXT: neg a6, a5
+; RV32I-NEXT: sll a6, a1, a6
+; RV32I-NEXT: or a6, a3, a6
+; RV32I-NEXT: mv a3, a0
+; RV32I-NEXT: beqz a5, .LBB11_4
+; RV32I-NEXT: .LBB11_3:
+; RV32I-NEXT: mv a3, a6
+; RV32I-NEXT: .LBB11_4:
+; RV32I-NEXT: neg a6, a2
+; RV32I-NEXT: bltu a5, a4, .LBB11_7
+; RV32I-NEXT: # %bb.5:
+; RV32I-NEXT: li a2, 0
+; RV32I-NEXT: andi a5, a6, 63
+; RV32I-NEXT: bgeu a5, a4, .LBB11_8
+; RV32I-NEXT: .LBB11_6:
+; RV32I-NEXT: sll a4, a0, a6
+; RV32I-NEXT: neg a7, a5
+; RV32I-NEXT: srl a0, a0, a7
+; RV32I-NEXT: sll a6, a1, a6
+; RV32I-NEXT: or a0, a0, a6
+; RV32I-NEXT: bnez a5, .LBB11_9
+; RV32I-NEXT: j .LBB11_10
+; RV32I-NEXT: .LBB11_7:
+; RV32I-NEXT: srl a2, a1, a2
+; RV32I-NEXT: andi a5, a6, 63
+; RV32I-NEXT: bltu a5, a4, .LBB11_6
+; RV32I-NEXT: .LBB11_8:
+; RV32I-NEXT: li a4, 0
+; RV32I-NEXT: sll a0, a0, a5
+; RV32I-NEXT: beqz a5, .LBB11_10
+; RV32I-NEXT: .LBB11_9:
+; RV32I-NEXT: mv a1, a0
+; RV32I-NEXT: .LBB11_10:
+; RV32I-NEXT: or a0, a3, a4
+; RV32I-NEXT: or a1, a2, a1
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: ror_i64:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: andi a4, a2, 63
+; RV32ZBB-ZBKB-NEXT: li a5, 32
+; RV32ZBB-ZBKB-NEXT: bltu a4, a5, .LBB11_2
+; RV32ZBB-ZBKB-NEXT: # %bb.1:
+; RV32ZBB-ZBKB-NEXT: srl a6, a1, a4
+; RV32ZBB-ZBKB-NEXT: mv a3, a0
+; RV32ZBB-ZBKB-NEXT: bnez a4, .LBB11_3
+; RV32ZBB-ZBKB-NEXT: j .LBB11_4
+; RV32ZBB-ZBKB-NEXT: .LBB11_2:
+; RV32ZBB-ZBKB-NEXT: srl a3, a0, a2
+; RV32ZBB-ZBKB-NEXT: neg a6, a4
+; RV32ZBB-ZBKB-NEXT: sll a6, a1, a6
+; RV32ZBB-ZBKB-NEXT: or a6, a3, a6
+; RV32ZBB-ZBKB-NEXT: mv a3, a0
+; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB11_4
+; RV32ZBB-ZBKB-NEXT: .LBB11_3:
+; RV32ZBB-ZBKB-NEXT: mv a3, a6
+; RV32ZBB-ZBKB-NEXT: .LBB11_4:
+; RV32ZBB-ZBKB-NEXT: li a6, 63
+; RV32ZBB-ZBKB-NEXT: bltu a4, a5, .LBB11_7
+; RV32ZBB-ZBKB-NEXT: # %bb.5:
+; RV32ZBB-ZBKB-NEXT: li a4, 0
+; RV32ZBB-ZBKB-NEXT: andn a6, a6, a2
+; RV32ZBB-ZBKB-NEXT: bgeu a6, a5, .LBB11_8
+; RV32ZBB-ZBKB-NEXT: .LBB11_6:
+; RV32ZBB-ZBKB-NEXT: neg a5, a2
+; RV32ZBB-ZBKB-NEXT: neg a7, a6
+; RV32ZBB-ZBKB-NEXT: sll a2, a0, a5
+; RV32ZBB-ZBKB-NEXT: srl a0, a0, a7
+; RV32ZBB-ZBKB-NEXT: sll a5, a1, a5
+; RV32ZBB-ZBKB-NEXT: or a0, a0, a5
+; RV32ZBB-ZBKB-NEXT: bnez a6, .LBB11_9
+; RV32ZBB-ZBKB-NEXT: j .LBB11_10
+; RV32ZBB-ZBKB-NEXT: .LBB11_7:
+; RV32ZBB-ZBKB-NEXT: srl a4, a1, a2
+; RV32ZBB-ZBKB-NEXT: andn a6, a6, a2
+; RV32ZBB-ZBKB-NEXT: bltu a6, a5, .LBB11_6
+; RV32ZBB-ZBKB-NEXT: .LBB11_8:
+; RV32ZBB-ZBKB-NEXT: li a2, 0
+; RV32ZBB-ZBKB-NEXT: sll a0, a0, a6
+; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB11_10
+; RV32ZBB-ZBKB-NEXT: .LBB11_9:
+; RV32ZBB-ZBKB-NEXT: mv a1, a0
+; RV32ZBB-ZBKB-NEXT: .LBB11_10:
+; RV32ZBB-ZBKB-NEXT: or a0, a3, a2
+; RV32ZBB-ZBKB-NEXT: or a1, a4, a1
+; RV32ZBB-ZBKB-NEXT: ret
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
ret i64 %or
}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
index 79d08772e8853..842ef1b215cd1 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
@@ -6,6 +6,17 @@
; RUN: llc -mtriple=riscv64 -global-isel -mattr=+zbkb -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBB-ZBKB,RV64ZBKB
+define signext i32 @andn_i32_from_sub(i32 signext %a, i32 signext %b) nounwind {
+; CHECK-LABEL: andn_i32_from_sub:
+; CHECK: # %bb.0:
+; CHECK-NEXT: negw a1, a1
+; CHECK-NEXT: and a0, a1, a0
+; CHECK-NEXT: ret
+ %neg = sub i32 0, %b
+ %and = and i32 %neg, %a
+ ret i32 %and
+}
+
define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: andn_i32:
; RV64I: # %bb.0:
@@ -38,6 +49,22 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
ret i64 %and
}
+define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
+; RV64I-LABEL: andn_i64_from_sub:
+; RV64I: # %bb.0:
+; RV64I-NEXT: neg a1, a1
+; RV64I-NEXT: and a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBB-ZBKB-LABEL: andn_i64_from_sub:
+; RV64ZBB-ZBKB: # %bb.0:
+; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1
+; RV64ZBB-ZBKB-NEXT: ret
+ %neg = sub i64 0, %b
+ %and = and i64 %neg, %a
+ ret i64 %and
+}
+
define signext i32 @orn_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: orn_i32:
; RV64I: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll
index b6344f88cddaa..045d0939d0764 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll
@@ -22,6 +22,22 @@ define i32 @andn_i32(i32 %a, i32 %b) nounwind {
ret i32 %and
}
+define i32 @andn_i32_from_sub(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: andn_i32_from_sub:
+; RV32I: # %bb.0:
+; RV32I-NEXT: neg a1, a1
+; RV32I-NEXT: and a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: andn_i32_from_sub:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1
+; RV32ZBB-ZBKB-NEXT: ret
+ %neg = sub i32 0, %b
+ %and = and i32 %neg, %a
+ ret i32 %and
+}
+
define i64 @andn_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: andn_i64:
; RV32I: # %bb.0:
@@ -41,6 +57,29 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
ret i64 %and
}
+define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
+; RV32I-LABEL: andn_i64_from_sub:
+; RV32I: # %bb.0:
+; RV32I-NEXT: snez a4, a2
+; RV32I-NEXT: neg a3, a3
+; RV32I-NEXT: neg a2, a2
+; RV32I-NEXT: sub a3, a3, a4
+; RV32I-NEXT: and a0, a2, a0
+; RV32I-NEXT: and a1, a3, a1
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: andn_i64_from_sub:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: snez a4, a2
+; RV32ZBB-ZBKB-NEXT: add a3, a3, a4
+; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2
+; RV32ZBB-ZBKB-NEXT: andn a1, a1, a3
+; RV32ZBB-ZBKB-NEXT: ret
+ %neg = sub i64 0, %b
+ %and = and i64 %neg, %a
+ ret i64 %and
+}
+
define i32 @orn_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: orn_i32:
; RV32I: # %bb.0:
@@ -141,15 +180,15 @@ define i64 @rol_i64(i64 %a, i64 %b) nounwind {
; CHECK-NEXT: slli a5, a2, 26
; CHECK-NEXT: srli a5, a5, 31
; CHECK-NEXT: mv a3, a1
-; CHECK-NEXT: bnez a5, .LBB7_2
+; CHECK-NEXT: bnez a5, .LBB9_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a3, a0
-; CHECK-NEXT: .LBB7_2:
+; CHECK-NEXT: .LBB9_2:
; CHECK-NEXT: sll a4, a3, a2
-; CHECK-NEXT: bnez a5, .LBB7_4
+; CHECK-NEXT: bnez a5, .LBB9_4
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: mv a0, a1
-; CHECK-NEXT: .LBB7_4:
+; CHECK-NEXT: .LBB9_4:
; CHECK-NEXT: srli a1, a0, 1
; CHECK-NEXT: not a5, a2
; CHECK-NEXT: sll a2, a0, a2
@@ -192,15 +231,15 @@ define i64 @ror_i64(i64 %a, i64 %b) nounwind {
; CHECK: # %bb.0:
; CHECK-NEXT: andi a5, a2, 32
; CHECK-NEXT: mv a3, a0
-; CHECK-NEXT: beqz a5, .LBB9_2
+; CHECK-NEXT: beqz a5, .LBB11_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mv a3, a1
-; CHECK-NEXT: .LBB9_2:
+; CHECK-NEXT: .LBB11_2:
; CHECK-NEXT: srl a4, a3, a2
-; CHECK-NEXT: beqz a5, .LBB9_4
+; CHECK-NEXT: beqz a5, .LBB11_4
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: mv a1, a0
-; CHECK-NEXT: .LBB9_4:
+; CHECK-NEXT: .LBB11_4:
; CHECK-NEXT: slli a0, a1, 1
; CHECK-NEXT: not a5, a2
; CHECK-NEXT: srl a1, a1, a2
@@ -293,19 +332,32 @@ define i32 @not_shl_one_i32(i32 %x) {
}
define i64 @not_shl_one_i64(i64 %x) {
-; CHECK-LABEL: not_shl_one_i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: addi a1, a0, -32
-; CHECK-NEXT: li a2, 1
-; CHECK-NEXT: slti a1, a1, 0
-; CHECK-NEXT: sll a0, a2, a0
-; CHECK-NEXT: neg a2, a1
-; CHECK-NEXT: addi a1, a1, -1
-; CHECK-NEXT: and a2, a2, a0
-; CHECK-NEXT: and a1, a1, a0
-; CHECK-NEXT: not a0, a2
-; CHECK-NEXT: not a1, a1
-; CHECK-NEXT: ret
+; RV32I-LABEL: not_shl_one_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi a1, a0, -32
+; RV32I-NEXT: li a2, 1
+; RV32I-NEXT: slti a1, a1, 0
+; RV32I-NEXT: sll a0, a2, a0
+; RV32I-NEXT: neg a2, a1
+; RV32I-NEXT: addi a1, a1, -1
+; RV32I-NEXT: and a2, a2, a0
+; RV32I-NEXT: and a1, a1, a0
+; RV32I-NEXT: not a0, a2
+; RV32I-NEXT: not a1, a1
+; RV32I-NEXT: ret
+;
+; RV32ZBB-ZBKB-LABEL: not_shl_one_i64:
+; RV32ZBB-ZBKB: # %bb.0:
+; RV32ZBB-ZBKB-NEXT: li a1, 1
+; RV32ZBB-ZBKB-NEXT: addi a2, a0, -32
+; RV32ZBB-ZBKB-NEXT: sll a0, a1, a0
+; RV32ZBB-ZBKB-NEXT: slti a1, a2, 0
+; RV32ZBB-ZBKB-NEXT: addi a2, a1, -1
+; RV32ZBB-ZBKB-NEXT: andn a1, a0, a1
+; RV32ZBB-ZBKB-NEXT: and a2, a2, a0
+; RV32ZBB-ZBKB-NEXT: not a0, a1
+; RV32ZBB-ZBKB-NEXT: not a1, a2
+; RV32ZBB-ZBKB-NEXT: ret
%1 = shl i64 1, %x
%2 = xor i64 %1, -1
ret i64 %2
diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll
index bf077364c9c7a..b4ed47d9c4fbc 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll
@@ -22,6 +22,17 @@ define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {
ret i32 %and
}
+define signext i32 @andn_i32_from_sub(i32 signext %a, i32 signext %b) nounwind {
+; CHECK-LABEL: andn_i32_from_sub:
+; CHECK: # %bb.0:
+; CHECK-NEXT: negw a1, a1
+; CHECK-NEXT: and a0, a1, a0
+; CHECK-NEXT: ret
+ %neg = sub i32 0, %b
+ %and = and i32 %neg, %a
+ ret i32 %and
+}
+
define i64 @andn_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: andn_i64:
; RV64I: # %bb.0:
@@ -38,6 +49,22 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
ret i64 %and
}
+define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
+; RV64I-LABEL: andn_i64_from_sub:
+; RV64I: # %bb.0:
+; RV64I-NEXT: neg a1, a1
+; RV64I-NEXT: and a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBB-ZBKB-LABEL: andn_i64_from_sub:
+; RV64ZBB-ZBKB: # %bb.0:
+; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1
+; RV64ZBB-ZBKB-NEXT: ret
+ %neg = sub i64 0, %b
+ %and = and i64 %neg, %a
+ ret i64 %and
+}
+
define signext i32 @orn_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: orn_i32:
; RV64I: # %bb.0:
>From 4a6834991bbd00254bb1a7b7e6589eb0d9ad4a09 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Fri, 28 Feb 2025 16:21:53 +0100
Subject: [PATCH 2/2] It is -1 not 0
---
llvm/lib/Target/RISCV/RISCVInstrInfoZb.td | 2 +-
.../CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll | 320 ++++++------------
.../CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll | 14 +-
llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll | 53 +--
llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll | 21 +-
5 files changed, 152 insertions(+), 258 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index 92d126fb8bcf9..75b1f5593cf50 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -483,7 +483,7 @@ def invLogicImm : ComplexPattern<XLenVT, 1, "selectInvLogicImm", [], [], 0>;
let Predicates = [HasStdExtZbbOrZbkb] in {
def : Pat<(XLenVT (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
-def : Pat<(XLenVT (and GPR:$rs1, (sub 0, GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
+def : Pat<(XLenVT (and GPR:$rs1, (sub -1, GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
def : Pat<(XLenVT (or GPR:$rs1, (not GPR:$rs2))), (ORN GPR:$rs1, GPR:$rs2)>;
def : Pat<(XLenVT (xor GPR:$rs1, (not GPR:$rs2))), (XNOR GPR:$rs1, GPR:$rs2)>;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll
index 03a3e4b3ff742..385563864933b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll
@@ -25,15 +25,16 @@ define i32 @andn_i32(i32 %a, i32 %b) nounwind {
define i32 @andn_i32_from_sub(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: andn_i32_from_sub:
; RV32I: # %bb.0:
-; RV32I-NEXT: neg a1, a1
-; RV32I-NEXT: and a0, a1, a0
+; RV32I-NEXT: li a2, -1
+; RV32I-NEXT: sub a2, a2, a1
+; RV32I-NEXT: and a0, a2, a0
; RV32I-NEXT: ret
;
; RV32ZBB-ZBKB-LABEL: andn_i32_from_sub:
; RV32ZBB-ZBKB: # %bb.0:
; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1
; RV32ZBB-ZBKB-NEXT: ret
- %neg = sub i32 0, %b
+ %neg = sub i32 -1, %b
%and = and i32 %neg, %a
ret i32 %and
}
@@ -60,23 +61,25 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: andn_i64_from_sub:
; RV32I: # %bb.0:
-; RV32I-NEXT: neg a4, a2
-; RV32I-NEXT: snez a2, a2
-; RV32I-NEXT: neg a3, a3
-; RV32I-NEXT: sub a3, a3, a2
-; RV32I-NEXT: and a0, a4, a0
-; RV32I-NEXT: and a1, a3, a1
+; RV32I-NEXT: li a4, -1
+; RV32I-NEXT: sub a5, a4, a2
+; RV32I-NEXT: sltu a2, a4, a2
+; RV32I-NEXT: sub a4, a4, a3
+; RV32I-NEXT: sub a4, a4, a2
+; RV32I-NEXT: and a0, a5, a0
+; RV32I-NEXT: and a1, a4, a1
; RV32I-NEXT: ret
;
; RV32ZBB-ZBKB-LABEL: andn_i64_from_sub:
; RV32ZBB-ZBKB: # %bb.0:
-; RV32ZBB-ZBKB-NEXT: snez a4, a2
-; RV32ZBB-ZBKB-NEXT: neg a3, a3
-; RV32ZBB-ZBKB-NEXT: sub a3, a3, a4
+; RV32ZBB-ZBKB-NEXT: li a4, -1
+; RV32ZBB-ZBKB-NEXT: sltu a5, a4, a2
+; RV32ZBB-ZBKB-NEXT: sub a4, a4, a3
+; RV32ZBB-ZBKB-NEXT: sub a4, a4, a5
; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2
-; RV32ZBB-ZBKB-NEXT: and a1, a3, a1
+; RV32ZBB-ZBKB-NEXT: and a1, a4, a1
; RV32ZBB-ZBKB-NEXT: ret
- %neg = sub i64 0, %b
+ %neg = sub i64 -1, %b
%and = and i64 %neg, %a
ret i64 %and
}
@@ -176,102 +179,53 @@ define i32 @rol_i32(i32 %a, i32 %b) nounwind {
declare i64 @llvm.fshl.i64(i64, i64, i64)
define i64 @rol_i64(i64 %a, i64 %b) nounwind {
-; RV32I-LABEL: rol_i64:
-; RV32I: # %bb.0:
-; RV32I-NEXT: andi a6, a2, 63
-; RV32I-NEXT: li a4, 32
-; RV32I-NEXT: bltu a6, a4, .LBB9_2
-; RV32I-NEXT: # %bb.1:
-; RV32I-NEXT: li a3, 0
-; RV32I-NEXT: sll a7, a0, a6
-; RV32I-NEXT: j .LBB9_3
-; RV32I-NEXT: .LBB9_2:
-; RV32I-NEXT: sll a3, a0, a2
-; RV32I-NEXT: neg a5, a6
-; RV32I-NEXT: srl a5, a0, a5
-; RV32I-NEXT: sll a7, a1, a2
-; RV32I-NEXT: or a7, a5, a7
-; RV32I-NEXT: .LBB9_3:
-; RV32I-NEXT: neg a5, a2
-; RV32I-NEXT: mv a2, a1
-; RV32I-NEXT: beqz a6, .LBB9_5
-; RV32I-NEXT: # %bb.4:
-; RV32I-NEXT: mv a2, a7
-; RV32I-NEXT: .LBB9_5:
-; RV32I-NEXT: andi a6, a5, 63
-; RV32I-NEXT: bltu a6, a4, .LBB9_7
-; RV32I-NEXT: # %bb.6:
-; RV32I-NEXT: srl a7, a1, a6
-; RV32I-NEXT: bnez a6, .LBB9_8
-; RV32I-NEXT: j .LBB9_9
-; RV32I-NEXT: .LBB9_7:
-; RV32I-NEXT: srl a7, a0, a5
-; RV32I-NEXT: neg t0, a6
-; RV32I-NEXT: sll t0, a1, t0
-; RV32I-NEXT: or a7, a7, t0
-; RV32I-NEXT: beqz a6, .LBB9_9
-; RV32I-NEXT: .LBB9_8:
-; RV32I-NEXT: mv a0, a7
-; RV32I-NEXT: .LBB9_9:
-; RV32I-NEXT: bltu a6, a4, .LBB9_11
-; RV32I-NEXT: # %bb.10:
-; RV32I-NEXT: li a1, 0
-; RV32I-NEXT: j .LBB9_12
-; RV32I-NEXT: .LBB9_11:
-; RV32I-NEXT: srl a1, a1, a5
-; RV32I-NEXT: .LBB9_12:
-; RV32I-NEXT: or a0, a3, a0
-; RV32I-NEXT: or a1, a2, a1
-; RV32I-NEXT: ret
-;
-; RV32ZBB-ZBKB-LABEL: rol_i64:
-; RV32ZBB-ZBKB: # %bb.0:
-; RV32ZBB-ZBKB-NEXT: andi a6, a2, 63
-; RV32ZBB-ZBKB-NEXT: li a4, 32
-; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_2
-; RV32ZBB-ZBKB-NEXT: # %bb.1:
-; RV32ZBB-ZBKB-NEXT: li a3, 0
-; RV32ZBB-ZBKB-NEXT: sll a7, a0, a6
-; RV32ZBB-ZBKB-NEXT: j .LBB9_3
-; RV32ZBB-ZBKB-NEXT: .LBB9_2:
-; RV32ZBB-ZBKB-NEXT: sll a3, a0, a2
-; RV32ZBB-ZBKB-NEXT: neg a5, a6
-; RV32ZBB-ZBKB-NEXT: srl a5, a0, a5
-; RV32ZBB-ZBKB-NEXT: sll a7, a1, a2
-; RV32ZBB-ZBKB-NEXT: or a7, a5, a7
-; RV32ZBB-ZBKB-NEXT: .LBB9_3:
-; RV32ZBB-ZBKB-NEXT: li t0, 63
-; RV32ZBB-ZBKB-NEXT: mv a5, a1
-; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB9_5
-; RV32ZBB-ZBKB-NEXT: # %bb.4:
-; RV32ZBB-ZBKB-NEXT: mv a5, a7
-; RV32ZBB-ZBKB-NEXT: .LBB9_5:
-; RV32ZBB-ZBKB-NEXT: andn a6, t0, a2
-; RV32ZBB-ZBKB-NEXT: neg a2, a2
-; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_7
-; RV32ZBB-ZBKB-NEXT: # %bb.6:
-; RV32ZBB-ZBKB-NEXT: srl a7, a1, a6
-; RV32ZBB-ZBKB-NEXT: bnez a6, .LBB9_8
-; RV32ZBB-ZBKB-NEXT: j .LBB9_9
-; RV32ZBB-ZBKB-NEXT: .LBB9_7:
-; RV32ZBB-ZBKB-NEXT: srl a7, a0, a2
-; RV32ZBB-ZBKB-NEXT: neg t0, a6
-; RV32ZBB-ZBKB-NEXT: sll t0, a1, t0
-; RV32ZBB-ZBKB-NEXT: or a7, a7, t0
-; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB9_9
-; RV32ZBB-ZBKB-NEXT: .LBB9_8:
-; RV32ZBB-ZBKB-NEXT: mv a0, a7
-; RV32ZBB-ZBKB-NEXT: .LBB9_9:
-; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_11
-; RV32ZBB-ZBKB-NEXT: # %bb.10:
-; RV32ZBB-ZBKB-NEXT: li a1, 0
-; RV32ZBB-ZBKB-NEXT: j .LBB9_12
-; RV32ZBB-ZBKB-NEXT: .LBB9_11:
-; RV32ZBB-ZBKB-NEXT: srl a1, a1, a2
-; RV32ZBB-ZBKB-NEXT: .LBB9_12:
-; RV32ZBB-ZBKB-NEXT: or a0, a3, a0
-; RV32ZBB-ZBKB-NEXT: or a1, a5, a1
-; RV32ZBB-ZBKB-NEXT: ret
+; CHECK-LABEL: rol_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: andi a6, a2, 63
+; CHECK-NEXT: li a4, 32
+; CHECK-NEXT: bltu a6, a4, .LBB9_2
+; CHECK-NEXT: # %bb.1:
+; CHECK-NEXT: li a3, 0
+; CHECK-NEXT: sll a7, a0, a6
+; CHECK-NEXT: j .LBB9_3
+; CHECK-NEXT: .LBB9_2:
+; CHECK-NEXT: sll a3, a0, a2
+; CHECK-NEXT: neg a5, a6
+; CHECK-NEXT: srl a5, a0, a5
+; CHECK-NEXT: sll a7, a1, a2
+; CHECK-NEXT: or a7, a5, a7
+; CHECK-NEXT: .LBB9_3:
+; CHECK-NEXT: neg a5, a2
+; CHECK-NEXT: mv a2, a1
+; CHECK-NEXT: beqz a6, .LBB9_5
+; CHECK-NEXT: # %bb.4:
+; CHECK-NEXT: mv a2, a7
+; CHECK-NEXT: .LBB9_5:
+; CHECK-NEXT: andi a6, a5, 63
+; CHECK-NEXT: bltu a6, a4, .LBB9_7
+; CHECK-NEXT: # %bb.6:
+; CHECK-NEXT: srl a7, a1, a6
+; CHECK-NEXT: bnez a6, .LBB9_8
+; CHECK-NEXT: j .LBB9_9
+; CHECK-NEXT: .LBB9_7:
+; CHECK-NEXT: srl a7, a0, a5
+; CHECK-NEXT: neg t0, a6
+; CHECK-NEXT: sll t0, a1, t0
+; CHECK-NEXT: or a7, a7, t0
+; CHECK-NEXT: beqz a6, .LBB9_9
+; CHECK-NEXT: .LBB9_8:
+; CHECK-NEXT: mv a0, a7
+; CHECK-NEXT: .LBB9_9:
+; CHECK-NEXT: bltu a6, a4, .LBB9_11
+; CHECK-NEXT: # %bb.10:
+; CHECK-NEXT: li a1, 0
+; CHECK-NEXT: j .LBB9_12
+; CHECK-NEXT: .LBB9_11:
+; CHECK-NEXT: srl a1, a1, a5
+; CHECK-NEXT: .LBB9_12:
+; CHECK-NEXT: or a0, a3, a0
+; CHECK-NEXT: or a1, a2, a1
+; CHECK-NEXT: ret
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
ret i64 %or
}
@@ -301,104 +255,54 @@ define i32 @ror_i32(i32 %a, i32 %b) nounwind {
declare i64 @llvm.fshr.i64(i64, i64, i64)
define i64 @ror_i64(i64 %a, i64 %b) nounwind {
-; RV32I-LABEL: ror_i64:
-; RV32I: # %bb.0:
-; RV32I-NEXT: andi a5, a2, 63
-; RV32I-NEXT: li a4, 32
-; RV32I-NEXT: bltu a5, a4, .LBB11_2
-; RV32I-NEXT: # %bb.1:
-; RV32I-NEXT: srl a6, a1, a5
-; RV32I-NEXT: mv a3, a0
-; RV32I-NEXT: bnez a5, .LBB11_3
-; RV32I-NEXT: j .LBB11_4
-; RV32I-NEXT: .LBB11_2:
-; RV32I-NEXT: srl a3, a0, a2
-; RV32I-NEXT: neg a6, a5
-; RV32I-NEXT: sll a6, a1, a6
-; RV32I-NEXT: or a6, a3, a6
-; RV32I-NEXT: mv a3, a0
-; RV32I-NEXT: beqz a5, .LBB11_4
-; RV32I-NEXT: .LBB11_3:
-; RV32I-NEXT: mv a3, a6
-; RV32I-NEXT: .LBB11_4:
-; RV32I-NEXT: neg a6, a2
-; RV32I-NEXT: bltu a5, a4, .LBB11_7
-; RV32I-NEXT: # %bb.5:
-; RV32I-NEXT: li a2, 0
-; RV32I-NEXT: andi a5, a6, 63
-; RV32I-NEXT: bgeu a5, a4, .LBB11_8
-; RV32I-NEXT: .LBB11_6:
-; RV32I-NEXT: sll a4, a0, a6
-; RV32I-NEXT: neg a7, a5
-; RV32I-NEXT: srl a0, a0, a7
-; RV32I-NEXT: sll a6, a1, a6
-; RV32I-NEXT: or a0, a0, a6
-; RV32I-NEXT: bnez a5, .LBB11_9
-; RV32I-NEXT: j .LBB11_10
-; RV32I-NEXT: .LBB11_7:
-; RV32I-NEXT: srl a2, a1, a2
-; RV32I-NEXT: andi a5, a6, 63
-; RV32I-NEXT: bltu a5, a4, .LBB11_6
-; RV32I-NEXT: .LBB11_8:
-; RV32I-NEXT: li a4, 0
-; RV32I-NEXT: sll a0, a0, a5
-; RV32I-NEXT: beqz a5, .LBB11_10
-; RV32I-NEXT: .LBB11_9:
-; RV32I-NEXT: mv a1, a0
-; RV32I-NEXT: .LBB11_10:
-; RV32I-NEXT: or a0, a3, a4
-; RV32I-NEXT: or a1, a2, a1
-; RV32I-NEXT: ret
-;
-; RV32ZBB-ZBKB-LABEL: ror_i64:
-; RV32ZBB-ZBKB: # %bb.0:
-; RV32ZBB-ZBKB-NEXT: andi a4, a2, 63
-; RV32ZBB-ZBKB-NEXT: li a5, 32
-; RV32ZBB-ZBKB-NEXT: bltu a4, a5, .LBB11_2
-; RV32ZBB-ZBKB-NEXT: # %bb.1:
-; RV32ZBB-ZBKB-NEXT: srl a6, a1, a4
-; RV32ZBB-ZBKB-NEXT: mv a3, a0
-; RV32ZBB-ZBKB-NEXT: bnez a4, .LBB11_3
-; RV32ZBB-ZBKB-NEXT: j .LBB11_4
-; RV32ZBB-ZBKB-NEXT: .LBB11_2:
-; RV32ZBB-ZBKB-NEXT: srl a3, a0, a2
-; RV32ZBB-ZBKB-NEXT: neg a6, a4
-; RV32ZBB-ZBKB-NEXT: sll a6, a1, a6
-; RV32ZBB-ZBKB-NEXT: or a6, a3, a6
-; RV32ZBB-ZBKB-NEXT: mv a3, a0
-; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB11_4
-; RV32ZBB-ZBKB-NEXT: .LBB11_3:
-; RV32ZBB-ZBKB-NEXT: mv a3, a6
-; RV32ZBB-ZBKB-NEXT: .LBB11_4:
-; RV32ZBB-ZBKB-NEXT: li a6, 63
-; RV32ZBB-ZBKB-NEXT: bltu a4, a5, .LBB11_7
-; RV32ZBB-ZBKB-NEXT: # %bb.5:
-; RV32ZBB-ZBKB-NEXT: li a4, 0
-; RV32ZBB-ZBKB-NEXT: andn a6, a6, a2
-; RV32ZBB-ZBKB-NEXT: bgeu a6, a5, .LBB11_8
-; RV32ZBB-ZBKB-NEXT: .LBB11_6:
-; RV32ZBB-ZBKB-NEXT: neg a5, a2
-; RV32ZBB-ZBKB-NEXT: neg a7, a6
-; RV32ZBB-ZBKB-NEXT: sll a2, a0, a5
-; RV32ZBB-ZBKB-NEXT: srl a0, a0, a7
-; RV32ZBB-ZBKB-NEXT: sll a5, a1, a5
-; RV32ZBB-ZBKB-NEXT: or a0, a0, a5
-; RV32ZBB-ZBKB-NEXT: bnez a6, .LBB11_9
-; RV32ZBB-ZBKB-NEXT: j .LBB11_10
-; RV32ZBB-ZBKB-NEXT: .LBB11_7:
-; RV32ZBB-ZBKB-NEXT: srl a4, a1, a2
-; RV32ZBB-ZBKB-NEXT: andn a6, a6, a2
-; RV32ZBB-ZBKB-NEXT: bltu a6, a5, .LBB11_6
-; RV32ZBB-ZBKB-NEXT: .LBB11_8:
-; RV32ZBB-ZBKB-NEXT: li a2, 0
-; RV32ZBB-ZBKB-NEXT: sll a0, a0, a6
-; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB11_10
-; RV32ZBB-ZBKB-NEXT: .LBB11_9:
-; RV32ZBB-ZBKB-NEXT: mv a1, a0
-; RV32ZBB-ZBKB-NEXT: .LBB11_10:
-; RV32ZBB-ZBKB-NEXT: or a0, a3, a2
-; RV32ZBB-ZBKB-NEXT: or a1, a4, a1
-; RV32ZBB-ZBKB-NEXT: ret
+; CHECK-LABEL: ror_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: andi a5, a2, 63
+; CHECK-NEXT: li a4, 32
+; CHECK-NEXT: bltu a5, a4, .LBB11_2
+; CHECK-NEXT: # %bb.1:
+; CHECK-NEXT: srl a6, a1, a5
+; CHECK-NEXT: mv a3, a0
+; CHECK-NEXT: bnez a5, .LBB11_3
+; CHECK-NEXT: j .LBB11_4
+; CHECK-NEXT: .LBB11_2:
+; CHECK-NEXT: srl a3, a0, a2
+; CHECK-NEXT: neg a6, a5
+; CHECK-NEXT: sll a6, a1, a6
+; CHECK-NEXT: or a6, a3, a6
+; CHECK-NEXT: mv a3, a0
+; CHECK-NEXT: beqz a5, .LBB11_4
+; CHECK-NEXT: .LBB11_3:
+; CHECK-NEXT: mv a3, a6
+; CHECK-NEXT: .LBB11_4:
+; CHECK-NEXT: neg a6, a2
+; CHECK-NEXT: bltu a5, a4, .LBB11_7
+; CHECK-NEXT: # %bb.5:
+; CHECK-NEXT: li a2, 0
+; CHECK-NEXT: andi a5, a6, 63
+; CHECK-NEXT: bgeu a5, a4, .LBB11_8
+; CHECK-NEXT: .LBB11_6:
+; CHECK-NEXT: sll a4, a0, a6
+; CHECK-NEXT: neg a7, a5
+; CHECK-NEXT: srl a0, a0, a7
+; CHECK-NEXT: sll a6, a1, a6
+; CHECK-NEXT: or a0, a0, a6
+; CHECK-NEXT: bnez a5, .LBB11_9
+; CHECK-NEXT: j .LBB11_10
+; CHECK-NEXT: .LBB11_7:
+; CHECK-NEXT: srl a2, a1, a2
+; CHECK-NEXT: andi a5, a6, 63
+; CHECK-NEXT: bltu a5, a4, .LBB11_6
+; CHECK-NEXT: .LBB11_8:
+; CHECK-NEXT: li a4, 0
+; CHECK-NEXT: sll a0, a0, a5
+; CHECK-NEXT: beqz a5, .LBB11_10
+; CHECK-NEXT: .LBB11_9:
+; CHECK-NEXT: mv a1, a0
+; CHECK-NEXT: .LBB11_10:
+; CHECK-NEXT: or a0, a3, a4
+; CHECK-NEXT: or a1, a2, a1
+; CHECK-NEXT: ret
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
ret i64 %or
}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
index 842ef1b215cd1..239d17032c07a 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
@@ -9,10 +9,11 @@
define signext i32 @andn_i32_from_sub(i32 signext %a, i32 signext %b) nounwind {
; CHECK-LABEL: andn_i32_from_sub:
; CHECK: # %bb.0:
-; CHECK-NEXT: negw a1, a1
-; CHECK-NEXT: and a0, a1, a0
+; CHECK-NEXT: li a2, -1
+; CHECK-NEXT: subw a2, a2, a1
+; CHECK-NEXT: and a0, a2, a0
; CHECK-NEXT: ret
- %neg = sub i32 0, %b
+ %neg = sub i32 -1, %b
%and = and i32 %neg, %a
ret i32 %and
}
@@ -52,15 +53,16 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: andn_i64_from_sub:
; RV64I: # %bb.0:
-; RV64I-NEXT: neg a1, a1
-; RV64I-NEXT: and a0, a1, a0
+; RV64I-NEXT: li a2, -1
+; RV64I-NEXT: sub a2, a2, a1
+; RV64I-NEXT: and a0, a2, a0
; RV64I-NEXT: ret
;
; RV64ZBB-ZBKB-LABEL: andn_i64_from_sub:
; RV64ZBB-ZBKB: # %bb.0:
; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1
; RV64ZBB-ZBKB-NEXT: ret
- %neg = sub i64 0, %b
+ %neg = sub i64 -1, %b
%and = and i64 %neg, %a
ret i64 %and
}
diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll
index 045d0939d0764..4ea8b1b3f84f5 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll
@@ -25,7 +25,7 @@ define i32 @andn_i32(i32 %a, i32 %b) nounwind {
define i32 @andn_i32_from_sub(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: andn_i32_from_sub:
; RV32I: # %bb.0:
-; RV32I-NEXT: neg a1, a1
+; RV32I-NEXT: not a1, a1
; RV32I-NEXT: and a0, a1, a0
; RV32I-NEXT: ret
;
@@ -33,7 +33,7 @@ define i32 @andn_i32_from_sub(i32 %a, i32 %b) nounwind {
; RV32ZBB-ZBKB: # %bb.0:
; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1
; RV32ZBB-ZBKB-NEXT: ret
- %neg = sub i32 0, %b
+ %neg = sub i32 -1, %b
%and = and i32 %neg, %a
ret i32 %and
}
@@ -60,22 +60,18 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: andn_i64_from_sub:
; RV32I: # %bb.0:
-; RV32I-NEXT: snez a4, a2
-; RV32I-NEXT: neg a3, a3
-; RV32I-NEXT: neg a2, a2
-; RV32I-NEXT: sub a3, a3, a4
+; RV32I-NEXT: not a3, a3
+; RV32I-NEXT: not a2, a2
; RV32I-NEXT: and a0, a2, a0
; RV32I-NEXT: and a1, a3, a1
; RV32I-NEXT: ret
;
; RV32ZBB-ZBKB-LABEL: andn_i64_from_sub:
; RV32ZBB-ZBKB: # %bb.0:
-; RV32ZBB-ZBKB-NEXT: snez a4, a2
-; RV32ZBB-ZBKB-NEXT: add a3, a3, a4
; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2
; RV32ZBB-ZBKB-NEXT: andn a1, a1, a3
; RV32ZBB-ZBKB-NEXT: ret
- %neg = sub i64 0, %b
+ %neg = sub i64 -1, %b
%and = and i64 %neg, %a
ret i64 %and
}
@@ -332,32 +328,19 @@ define i32 @not_shl_one_i32(i32 %x) {
}
define i64 @not_shl_one_i64(i64 %x) {
-; RV32I-LABEL: not_shl_one_i64:
-; RV32I: # %bb.0:
-; RV32I-NEXT: addi a1, a0, -32
-; RV32I-NEXT: li a2, 1
-; RV32I-NEXT: slti a1, a1, 0
-; RV32I-NEXT: sll a0, a2, a0
-; RV32I-NEXT: neg a2, a1
-; RV32I-NEXT: addi a1, a1, -1
-; RV32I-NEXT: and a2, a2, a0
-; RV32I-NEXT: and a1, a1, a0
-; RV32I-NEXT: not a0, a2
-; RV32I-NEXT: not a1, a1
-; RV32I-NEXT: ret
-;
-; RV32ZBB-ZBKB-LABEL: not_shl_one_i64:
-; RV32ZBB-ZBKB: # %bb.0:
-; RV32ZBB-ZBKB-NEXT: li a1, 1
-; RV32ZBB-ZBKB-NEXT: addi a2, a0, -32
-; RV32ZBB-ZBKB-NEXT: sll a0, a1, a0
-; RV32ZBB-ZBKB-NEXT: slti a1, a2, 0
-; RV32ZBB-ZBKB-NEXT: addi a2, a1, -1
-; RV32ZBB-ZBKB-NEXT: andn a1, a0, a1
-; RV32ZBB-ZBKB-NEXT: and a2, a2, a0
-; RV32ZBB-ZBKB-NEXT: not a0, a1
-; RV32ZBB-ZBKB-NEXT: not a1, a2
-; RV32ZBB-ZBKB-NEXT: ret
+; CHECK-LABEL: not_shl_one_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: addi a1, a0, -32
+; CHECK-NEXT: li a2, 1
+; CHECK-NEXT: slti a1, a1, 0
+; CHECK-NEXT: sll a0, a2, a0
+; CHECK-NEXT: neg a2, a1
+; CHECK-NEXT: addi a1, a1, -1
+; CHECK-NEXT: and a2, a2, a0
+; CHECK-NEXT: and a1, a1, a0
+; CHECK-NEXT: not a0, a2
+; CHECK-NEXT: not a1, a1
+; CHECK-NEXT: ret
%1 = shl i64 1, %x
%2 = xor i64 %1, -1
ret i64 %2
diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll
index b4ed47d9c4fbc..30936c247b233 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll
@@ -23,12 +23,17 @@ define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {
}
define signext i32 @andn_i32_from_sub(i32 signext %a, i32 signext %b) nounwind {
-; CHECK-LABEL: andn_i32_from_sub:
-; CHECK: # %bb.0:
-; CHECK-NEXT: negw a1, a1
-; CHECK-NEXT: and a0, a1, a0
-; CHECK-NEXT: ret
- %neg = sub i32 0, %b
+; RV64I-LABEL: andn_i32_from_sub:
+; RV64I: # %bb.0:
+; RV64I-NEXT: not a1, a1
+; RV64I-NEXT: and a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBB-ZBKB-LABEL: andn_i32_from_sub:
+; RV64ZBB-ZBKB: # %bb.0:
+; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1
+; RV64ZBB-ZBKB-NEXT: ret
+ %neg = sub i32 -1, %b
%and = and i32 %neg, %a
ret i32 %and
}
@@ -52,7 +57,7 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: andn_i64_from_sub:
; RV64I: # %bb.0:
-; RV64I-NEXT: neg a1, a1
+; RV64I-NEXT: not a1, a1
; RV64I-NEXT: and a0, a1, a0
; RV64I-NEXT: ret
;
@@ -60,7 +65,7 @@ define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
; RV64ZBB-ZBKB: # %bb.0:
; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1
; RV64ZBB-ZBKB-NEXT: ret
- %neg = sub i64 0, %b
+ %neg = sub i64 -1, %b
%and = and i64 %neg, %a
ret i64 %and
}
More information about the llvm-commits
mailing list