[llvm] [RISCV] Improve instruction selection for most significant bit extraction (PR #151687)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 1 04:00:32 PDT 2025
================
@@ -3507,3 +3507,77 @@ define void @bit_64_1_nz_branch_i64(i64 %0) {
5:
ret void
}
+
+define i32 @bittest_31_andeq0_i64(i64 %x) {
+; RV32-LABEL: bittest_31_andeq0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: xori a0, a0, 1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_31_andeq0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: xori a0, a0, 1
+; RV64-NEXT: ret
+ %and = and i64 %x, 2147483648
+ %cmp = icmp eq i64 %and, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bittest_63_andeq0_i64(i64 %x) {
+; RV32-LABEL: bittest_63_andeq0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a1, a1, 31
+; RV32-NEXT: xori a0, a1, 1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_63_andeq0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srli a0, a0, 63
+; RV64-NEXT: xori a0, a0, 1
+; RV64-NEXT: ret
+ %and = and i64 %x, 9223372036854775808
+ %cmp = icmp eq i64 %and, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bittest_31_slt0_i32(i32 %x, i1 %y) {
+; RV32-LABEL: bittest_31_slt0_i32:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: and a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_31_slt0_i32:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: and a0, a0, a1
+; RV64-NEXT: ret
+ %cmp = icmp slt i32 %x, 0
+ %and = and i1 %cmp, %y
+ %ext = zext i1 %and to i32
+ ret i32 %ext
+}
+
+define i32 @bittest_63_slt0_i64(i32 %x, i1 %y) {
+; RV32-LABEL: bittest_63_slt0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srai a0, a0, 31
----------------
pfusik wrote:
Future optimization opportunity: this `srai` was and still is redundant.
https://github.com/llvm/llvm-project/pull/151687
More information about the llvm-commits
mailing list