[llvm] [IR] Implementation and lowering of bitinsert and bitextract (PR #200605)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 03:42:54 PDT 2026
================
@@ -0,0 +1,158 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefix=RV32
+; RUN: llc -mtriple=riscv32 -mattr=+zbb < %s | FileCheck %s --check-prefix=RV32ZBB
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefix=RV64
+; RUN: llc -mtriple=riscv64 -mattr=+zbb < %s | FileCheck %s --check-prefix=RV64ZBB
+
+define i16 @test_bitextract_var(b32 %src, i32 %off) {
+; RV32-LABEL: test_bitextract_var:
+; RV32: # %bb.0:
+; RV32-NEXT: srl a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV32ZBB-LABEL: test_bitextract_var:
+; RV32ZBB: # %bb.0:
+; RV32ZBB-NEXT: srl a0, a0, a1
+; RV32ZBB-NEXT: ret
+;
+; RV64-LABEL: test_bitextract_var:
+; RV64: # %bb.0:
+; RV64-NEXT: srlw a0, a0, a1
+; RV64-NEXT: ret
+;
+; RV64ZBB-LABEL: test_bitextract_var:
+; RV64ZBB: # %bb.0:
+; RV64ZBB-NEXT: srlw a0, a0, a1
+; RV64ZBB-NEXT: ret
+
+
+
+ %result = bitextract i16, b32 %src, i32 %off
+ ret i16 %result
+}
+
+define i16 @test_bitextract_const(b32 %src) {
+; RV32-LABEL: test_bitextract_const:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 8
+; RV32-NEXT: ret
+;
+; RV32ZBB-LABEL: test_bitextract_const:
+; RV32ZBB: # %bb.0:
+; RV32ZBB-NEXT: srli a0, a0, 8
+; RV32ZBB-NEXT: ret
+;
+; RV64-LABEL: test_bitextract_const:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 8
+; RV64-NEXT: ret
+;
+; RV64ZBB-LABEL: test_bitextract_const:
+; RV64ZBB: # %bb.0:
+; RV64ZBB-NEXT: srliw a0, a0, 8
+; RV64ZBB-NEXT: ret
+
+
+
+ %result = bitextract i16, b32 %src, i32 8
+ ret i16 %result
+}
+
+define i8 @test_bitextract_narrow(b64 %src) {
+; RV32-LABEL: test_bitextract_narrow:
+; RV32: # %bb.0:
+; RV32-NEXT: ret
+;
+; RV32ZBB-LABEL: test_bitextract_narrow:
+; RV32ZBB: # %bb.0:
+; RV32ZBB-NEXT: ret
+;
+; RV64-LABEL: test_bitextract_narrow:
+; RV64: # %bb.0:
+; RV64-NEXT: ret
+;
+; RV64ZBB-LABEL: test_bitextract_narrow:
+; RV64ZBB: # %bb.0:
+; RV64ZBB-NEXT: ret
+
+
+
+ %result = bitextract i8, b64 %src, i32 0
+ ret i8 %result
+}
+
+define b32 @test_bitinsert_var(b32 %base, i16 %val, i32 %off) {
+; RV32-LABEL: test_bitinsert_var:
+; RV32: # %bb.0:
+; RV32-NEXT: neg a3, a2
+; RV32-NEXT: srl a4, a0, a2
+; RV32-NEXT: sll a0, a0, a3
+; RV32-NEXT: or a0, a4, a0
+; RV32-NEXT: lui a4, 1048560
+; RV32-NEXT: slli a1, a1, 16
+; RV32-NEXT: and a0, a0, a4
+; RV32-NEXT: srli a1, a1, 16
+; RV32-NEXT: or a0, a0, a1
+; RV32-NEXT: srl a1, a0, a3
+; RV32-NEXT: sll a0, a0, a2
+; RV32-NEXT: or a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV32ZBB-LABEL: test_bitinsert_var:
+; RV32ZBB: # %bb.0:
+; RV32ZBB-NEXT: lui a3, 1048560
+; RV32ZBB-NEXT: ror a0, a0, a2
+; RV32ZBB-NEXT: and a0, a0, a3
+; RV32ZBB-NEXT: zext.h a1, a1
+; RV32ZBB-NEXT: or a0, a0, a1
+; RV32ZBB-NEXT: rol a0, a0, a2
+; RV32ZBB-NEXT: ret
+;
+; RV64-LABEL: test_bitinsert_var:
+; RV64: # %bb.0:
+; RV64-NEXT: neg a3, a2
+; RV64-NEXT: srlw a4, a0, a2
+; RV64-NEXT: sllw a0, a0, a3
+; RV64-NEXT: or a0, a4, a0
+; RV64-NEXT: lui a4, 1048560
+; RV64-NEXT: slli a1, a1, 48
+; RV64-NEXT: and a0, a0, a4
+; RV64-NEXT: srli a1, a1, 48
+; RV64-NEXT: or a0, a0, a1
+; RV64-NEXT: srlw a1, a0, a3
+; RV64-NEXT: sllw a0, a0, a2
+; RV64-NEXT: or a0, a0, a1
+; RV64-NEXT: ret
+;
+; RV64ZBB-LABEL: test_bitinsert_var:
+; RV64ZBB: # %bb.0:
+; RV64ZBB-NEXT: lui a3, 1048560
+; RV64ZBB-NEXT: rorw a0, a0, a2
+; RV64ZBB-NEXT: and a0, a0, a3
+; RV64ZBB-NEXT: zext.h a1, a1
+; RV64ZBB-NEXT: or a0, a0, a1
+; RV64ZBB-NEXT: rolw a0, a0, a2
+; RV64ZBB-NEXT: ret
+; RV32 srl a3, a0, a2
+; RV32 neg a4, a2
+; RV32 sll a0, a0, a4
+; RV32 or a0, a3, a0
+; RV32 lui a3, 1048560
+; RV32 slli a1, a1, 16
+; RV32 srli a1, a1, 16
+; RV32 and a0, a0, a3
+; RV32 or a0, a0, a1
+; RV32 srl a1, a0, a4
+; RV32 sll a0, a0, a2
+; RV32 or a0, a0, a1
+; RV32 ret
+
+
+
+
+
+
+
+ %result = bitinsert b32 %base, i16 %val, i32 %off
----------------
aengelke wrote:
Remove extra newlines. I'd expect substantially more test coverage, including at least:
- More base sizes (insert into/extract from e.g. b1, b37, b87, b128, b231).
- More insert types (b1, b8, b21, b123 (and/or integer), vectors of various sizes, floating-point values, pointers, also in different address spaces (and also on more interesting targets like AMDGPU)).
- More constant offset tests for common cases (e.g. insert i8 at offset 8).
- More ISAs, at least AArch64, ARM, PowerPC.
- Where supported, but SDAG and GISel codegen tests in a single file so that codegen differences can be spotted more easily.
https://github.com/llvm/llvm-project/pull/200605
More information about the llvm-commits
mailing list