[llvm-branch-commits] [llvm] [llubi] Add support for `bitinsert` and `bitextract` (PR #230827)
Pedro Lobo via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Oct 10 11:35:11 PDT 2026
https://github.com/pedroclobo created https://github.com/llvm/llvm-project/pull/230827
Add support for `bitinsert` and `bitextract`.
>From a3da945a2322c9a0403bd04cb9de159767892849 Mon Sep 17 00:00:00 2001
From: Pedro Lobo <pedro.lobo at tecnico.ulisboa.pt>
Date: Sat, 10 Oct 2026 17:47:27 +0100
Subject: [PATCH] [llubi] Add support for `bitinsert` and `bitextract`
---
.../tools/llubi/bitinsert_bitextract_be.ll | 78 +++++++++++++++++++
.../tools/llubi/bitinsert_bitextract_le.ll | 78 +++++++++++++++++++
llvm/tools/llubi/lib/Context.cpp | 19 +++++
llvm/tools/llubi/lib/Context.h | 7 ++
llvm/tools/llubi/lib/Interpreter.cpp | 29 +++++++
5 files changed, 211 insertions(+)
create mode 100644 llvm/test/tools/llubi/bitinsert_bitextract_be.ll
create mode 100644 llvm/test/tools/llubi/bitinsert_bitextract_le.ll
diff --git a/llvm/test/tools/llubi/bitinsert_bitextract_be.ll b/llvm/test/tools/llubi/bitinsert_bitextract_be.ll
new file mode 100644
index 0000000000000..8b867e2c026a8
--- /dev/null
+++ b/llvm/test/tools/llubi/bitinsert_bitextract_be.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
+; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
+
+define void @main() {
+entry:
+ %bitextract_aligned = bitextract i8, b32 u0x12345678, i32 8
+ %bitextract_unaligned = bitextract i8, b32 u0x12345678, i32 4
+ %bitextract_i3 = bitextract i3, b32 u0x12345678, i32 6
+ %bitextract_float = bitextract float, b64 u0x3F80000000000000, i32 32
+ %bitextract_b12 = bitextract b12, b32 u0x12345678, i32 10
+ %bitextract_oob = bitextract i8, b32 u0x12345678, i32 25
+ %bitextract_oob_wrap = bitextract i8, b32 u0x12345678, i32 -1
+ %bitextract_poison_offset = bitextract i8, b32 u0x12345678, i32 poison
+ %bitextract_poison_src = bitextract i8, b32 poison, i32 0
+
+ %bitinsert_aligned = bitinsert b32 u0x12345678, i8 0, i32 8
+ %bitinsert_unaligned = bitinsert b32 u0x12345678, i8 -1, i32 4
+ %bitinsert_float = bitinsert b64 0, float 1.0, i32 32
+ %bitinsert_b8 = bitinsert b32 0, b8 -1, i32 12
+ %bitinsert_b12 = bitinsert b12 0, i4 -1, i32 8
+ %bitinsert_oob = bitinsert b32 u0x12345678, i8 0, i32 25
+ %bitinsert_poison_offset = bitinsert b32 u0x12345678, i8 0, i32 poison
+ %bitinsert_poison = bitinsert b32 0, i16 poison, i32 4
+
+ %bitextract_poison_overlap = bitextract i8, b32 %bitinsert_poison, i32 16
+ %bitextract_poison_disjoint = bitextract i8, b32 %bitinsert_poison, i32 20
+ %bitextract_poison_overlap_b8 = bitextract b8, b32 %bitinsert_poison, i32 16
+
+ %ptr = alloca i32
+ %bitinsert_ptr = bitinsert b128 0, ptr %ptr, i32 32
+ %bitextract_ptr = bitextract ptr, b128 %bitinsert_ptr, i32 32
+ %bitextract_ptr_shifted = bitextract ptr, b128 %bitinsert_ptr, i32 31
+ %bitextract_ptr_addr = bitextract i64, b128 %bitinsert_ptr, i32 32
+ %bitinsert_ptr_clobber = bitinsert b128 %bitinsert_ptr, i8 0, i32 40
+ %bitextract_ptr_clobbered = bitextract ptr, b128 %bitinsert_ptr_clobber, i32 32
+ %bitinsert_ptr_unaligned = bitinsert b128 0, ptr %ptr, i32 3
+ %bitextract_ptr_unaligned = bitextract ptr, b128 %bitinsert_ptr_unaligned, i32 3
+ %bitextract_ptr_bytes = bitextract b64, b128 %bitinsert_ptr, i32 32
+ %bitinsert_ptr_bytes = bitinsert b128 0, b64 %bitextract_ptr_bytes, i32 5
+ %bitextract_ptr_via_bytes = bitextract ptr, b128 %bitinsert_ptr_bytes, i32 5
+ ret void
+}
+; CHECK: Entering function: main
+; CHECK-NEXT: %bitextract_aligned = bitextract i8, b32 305419896, i32 8 => i8 86
+; CHECK-NEXT: %bitextract_unaligned = bitextract i8, b32 305419896, i32 4 => i8 103
+; CHECK-NEXT: %bitextract_i3 = bitextract i3, b32 305419896, i32 6 => i3 1
+; CHECK-NEXT: %bitextract_float = bitextract float, b64 4575657221408423936, i32 32 => float 1.000000e+00
+; CHECK-NEXT: %bitextract_b12 = bitextract b12, b32 305419896, i32 10 => b12 1101 0x15
+; CHECK-NEXT: %bitextract_oob = bitextract i8, b32 305419896, i32 25 => poison
+; CHECK-NEXT: %bitextract_oob_wrap = bitextract i8, b32 305419896, i32 -1 => poison
+; CHECK-NEXT: %bitextract_poison_offset = bitextract i8, b32 305419896, i32 poison => poison
+; CHECK-NEXT: %bitextract_poison_src = bitextract i8, b32 poison, i32 0 => poison
+; CHECK-NEXT: %bitinsert_aligned = bitinsert b32 305419896, i8 0, i32 8 => b32 0x12 0x34 0x00 0x78
+; CHECK-NEXT: %bitinsert_unaligned = bitinsert b32 305419896, i8 -1, i32 4 => b32 0x12 0x34 0x5F 0xF8
+; CHECK-NEXT: %bitinsert_float = bitinsert b64 0, float 1.000000e+00, i32 32 => b64 0x3F 0x80 0x00 0x00 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitinsert_b8 = bitinsert b32 0, b8 -1, i32 12 => b32 0x00 0x0F 0xF0 0x00
+; CHECK-NEXT: %bitinsert_b12 = bitinsert b12 0, i4 -1, i32 8 => b12 1111 0x00
+; CHECK-NEXT: %bitinsert_oob = bitinsert b32 305419896, i8 0, i32 25 => b32 0x!! 0x!! 0x!! 0x!!
+; CHECK-NEXT: %bitinsert_poison_offset = bitinsert b32 305419896, i8 0, i32 poison => b32 0x!! 0x!! 0x!! 0x!!
+; CHECK-NEXT: %bitinsert_poison = bitinsert b32 0, i16 poison, i32 4 => b32 0x00 0000!!!! 0x!! !!!!0000
+; CHECK-NEXT: %bitextract_poison_overlap = bitextract i8, b32 %bitinsert_poison, i32 16 => poison
+; CHECK-NEXT: %bitextract_poison_disjoint = bitextract i8, b32 %bitinsert_poison, i32 20 => i8 0
+; CHECK-NEXT: %bitextract_poison_overlap_b8 = bitextract b8, b32 %bitinsert_poison, i32 16 => b8 0000!!!!
+; CHECK-NEXT: %ptr = alloca i32, align 4 => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitinsert_ptr = bitinsert b128 0, ptr %ptr, i32 32 => b128 0x00 0x00 0x00 0x00 00000000(00101000) 00000000(11101000) 00000000(00110111) 00000000(11000101) 00000000(11001011) 00000000(01000001) 00000000(11011100) 00001000(00111110) 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitextract_ptr = bitextract ptr, b128 %bitinsert_ptr, i32 32 => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitextract_ptr_shifted = bitextract ptr, b128 %bitinsert_ptr, i32 31 => ptr 0x10 [nullary]
+; CHECK-NEXT: %bitextract_ptr_addr = bitextract i64, b128 %bitinsert_ptr, i32 32 => i64 8
+; CHECK-NEXT: %bitinsert_ptr_clobber = bitinsert b128 %bitinsert_ptr, i8 0, i32 40 => b128 0x00 0x00 0x00 0x00 00000000(00101000) 00000000(11101000) 00000000(00110111) 00000000(11000101) 00000000(11001011) 00000000(01000001) 0x00 00001000(00111110) 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitextract_ptr_clobbered = bitextract ptr, b128 %bitinsert_ptr_clobber, i32 32 => ptr 0x8 [nullary]
+; CHECK-NEXT: %bitinsert_ptr_unaligned = bitinsert b128 0, ptr %ptr, i32 3 => b128 0x00 0x00 0x00 0x00 0x00 0x00 0x00 00000000(!!!!!001) 00000000(01000111) 00000000(01000001) 00000000(10111110) 00000000(00101110) 00000000(01011010) 00000000(00001110) 00000000(11100001) 01000000(11110!!!)
+; CHECK-NEXT: %bitextract_ptr_unaligned = bitextract ptr, b128 %bitinsert_ptr_unaligned, i32 3 => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitextract_ptr_bytes = bitextract b64, b128 %bitinsert_ptr, i32 32 => b64 ptr 0x8 [ptr]
+; CHECK-NEXT: %bitinsert_ptr_bytes = bitinsert b128 0, b64 %bitextract_ptr_bytes, i32 5 => b128 0x00 0x00 0x00 0x00 0x00 0x00 0x00 00000000(!!!00101) 00000000(00011101) 00000000(00000110) 00000000(11111000) 00000000(10111001) 00000000(01101000) 00000000(00111011) 00000001(10000111) 00000000(110!!!!!)
+; CHECK-NEXT: %bitextract_ptr_via_bytes = bitextract ptr, b128 %bitinsert_ptr_bytes, i32 5 => ptr 0x8 [ptr]
+; CHECK-NEXT: ret void
+; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/bitinsert_bitextract_le.ll b/llvm/test/tools/llubi/bitinsert_bitextract_le.ll
new file mode 100644
index 0000000000000..4561aebb931df
--- /dev/null
+++ b/llvm/test/tools/llubi/bitinsert_bitextract_le.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
+; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
+
+define void @main() {
+entry:
+ %bitextract_aligned = bitextract i8, b32 u0x12345678, i32 8
+ %bitextract_unaligned = bitextract i8, b32 u0x12345678, i32 4
+ %bitextract_i3 = bitextract i3, b32 u0x12345678, i32 6
+ %bitextract_float = bitextract float, b64 u0x3F80000000000000, i32 32
+ %bitextract_b12 = bitextract b12, b32 u0x12345678, i32 10
+ %bitextract_oob = bitextract i8, b32 u0x12345678, i32 25
+ %bitextract_oob_wrap = bitextract i8, b32 u0x12345678, i32 -1
+ %bitextract_poison_offset = bitextract i8, b32 u0x12345678, i32 poison
+ %bitextract_poison_src = bitextract i8, b32 poison, i32 0
+
+ %bitinsert_aligned = bitinsert b32 u0x12345678, i8 0, i32 8
+ %bitinsert_unaligned = bitinsert b32 u0x12345678, i8 -1, i32 4
+ %bitinsert_float = bitinsert b64 0, float 1.0, i32 32
+ %bitinsert_b8 = bitinsert b32 0, b8 -1, i32 12
+ %bitinsert_b12 = bitinsert b12 0, i4 -1, i32 8
+ %bitinsert_oob = bitinsert b32 u0x12345678, i8 0, i32 25
+ %bitinsert_poison_offset = bitinsert b32 u0x12345678, i8 0, i32 poison
+ %bitinsert_poison = bitinsert b32 0, i16 poison, i32 4
+
+ %bitextract_poison_overlap = bitextract i8, b32 %bitinsert_poison, i32 16
+ %bitextract_poison_disjoint = bitextract i8, b32 %bitinsert_poison, i32 20
+ %bitextract_poison_overlap_b8 = bitextract b8, b32 %bitinsert_poison, i32 16
+
+ %ptr = alloca i32
+ %bitinsert_ptr = bitinsert b128 0, ptr %ptr, i32 32
+ %bitextract_ptr = bitextract ptr, b128 %bitinsert_ptr, i32 32
+ %bitextract_ptr_shifted = bitextract ptr, b128 %bitinsert_ptr, i32 31
+ %bitextract_ptr_addr = bitextract i64, b128 %bitinsert_ptr, i32 32
+ %bitinsert_ptr_clobber = bitinsert b128 %bitinsert_ptr, i8 0, i32 40
+ %bitextract_ptr_clobbered = bitextract ptr, b128 %bitinsert_ptr_clobber, i32 32
+ %bitinsert_ptr_unaligned = bitinsert b128 0, ptr %ptr, i32 3
+ %bitextract_ptr_unaligned = bitextract ptr, b128 %bitinsert_ptr_unaligned, i32 3
+ %bitextract_ptr_bytes = bitextract b64, b128 %bitinsert_ptr, i32 32
+ %bitinsert_ptr_bytes = bitinsert b128 0, b64 %bitextract_ptr_bytes, i32 5
+ %bitextract_ptr_via_bytes = bitextract ptr, b128 %bitinsert_ptr_bytes, i32 5
+ ret void
+}
+; CHECK: Entering function: main
+; CHECK-NEXT: %bitextract_aligned = bitextract i8, b32 305419896, i32 8 => i8 86
+; CHECK-NEXT: %bitextract_unaligned = bitextract i8, b32 305419896, i32 4 => i8 103
+; CHECK-NEXT: %bitextract_i3 = bitextract i3, b32 305419896, i32 6 => i3 1
+; CHECK-NEXT: %bitextract_float = bitextract float, b64 4575657221408423936, i32 32 => float 1.000000e+00
+; CHECK-NEXT: %bitextract_b12 = bitextract b12, b32 305419896, i32 10 => b12 0x15 1101
+; CHECK-NEXT: %bitextract_oob = bitextract i8, b32 305419896, i32 25 => poison
+; CHECK-NEXT: %bitextract_oob_wrap = bitextract i8, b32 305419896, i32 -1 => poison
+; CHECK-NEXT: %bitextract_poison_offset = bitextract i8, b32 305419896, i32 poison => poison
+; CHECK-NEXT: %bitextract_poison_src = bitextract i8, b32 poison, i32 0 => poison
+; CHECK-NEXT: %bitinsert_aligned = bitinsert b32 305419896, i8 0, i32 8 => b32 0x78 0x00 0x34 0x12
+; CHECK-NEXT: %bitinsert_unaligned = bitinsert b32 305419896, i8 -1, i32 4 => b32 0xF8 0x5F 0x34 0x12
+; CHECK-NEXT: %bitinsert_float = bitinsert b64 0, float 1.000000e+00, i32 32 => b64 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x3F
+; CHECK-NEXT: %bitinsert_b8 = bitinsert b32 0, b8 -1, i32 12 => b32 0x00 0xF0 0x0F 0x00
+; CHECK-NEXT: %bitinsert_b12 = bitinsert b12 0, i4 -1, i32 8 => b12 0x00 1111
+; CHECK-NEXT: %bitinsert_oob = bitinsert b32 305419896, i8 0, i32 25 => b32 0x!! 0x!! 0x!! 0x!!
+; CHECK-NEXT: %bitinsert_poison_offset = bitinsert b32 305419896, i8 0, i32 poison => b32 0x!! 0x!! 0x!! 0x!!
+; CHECK-NEXT: %bitinsert_poison = bitinsert b32 0, i16 poison, i32 4 => b32 !!!!0000 0x!! 0000!!!! 0x00
+; CHECK-NEXT: %bitextract_poison_overlap = bitextract i8, b32 %bitinsert_poison, i32 16 => poison
+; CHECK-NEXT: %bitextract_poison_disjoint = bitextract i8, b32 %bitinsert_poison, i32 20 => i8 0
+; CHECK-NEXT: %bitextract_poison_overlap_b8 = bitextract b8, b32 %bitinsert_poison, i32 16 => b8 0000!!!!
+; CHECK-NEXT: %ptr = alloca i32, align 4 => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitinsert_ptr = bitinsert b128 0, ptr %ptr, i32 32 => b128 0x00 0x00 0x00 0x00 00001000(00111110) 00000000(11011100) 00000000(01000001) 00000000(11001011) 00000000(11000101) 00000000(00110111) 00000000(11101000) 00000000(00101000) 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitextract_ptr = bitextract ptr, b128 %bitinsert_ptr, i32 32 => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitextract_ptr_shifted = bitextract ptr, b128 %bitinsert_ptr, i32 31 => ptr 0x10 [nullary]
+; CHECK-NEXT: %bitextract_ptr_addr = bitextract i64, b128 %bitinsert_ptr, i32 32 => i64 8
+; CHECK-NEXT: %bitinsert_ptr_clobber = bitinsert b128 %bitinsert_ptr, i8 0, i32 40 => b128 0x00 0x00 0x00 0x00 00001000(00111110) 0x00 00000000(01000001) 00000000(11001011) 00000000(11000101) 00000000(00110111) 00000000(11101000) 00000000(00101000) 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitextract_ptr_clobbered = bitextract ptr, b128 %bitinsert_ptr_clobber, i32 32 => ptr 0x8 [nullary]
+; CHECK-NEXT: %bitinsert_ptr_unaligned = bitinsert b128 0, ptr %ptr, i32 3 => b128 01000000(11110!!!) 00000000(11100001) 00000000(00001110) 00000000(01011010) 00000000(00101110) 00000000(10111110) 00000000(01000001) 00000000(01000111) 00000000(!!!!!001) 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitextract_ptr_unaligned = bitextract ptr, b128 %bitinsert_ptr_unaligned, i32 3 => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitextract_ptr_bytes = bitextract b64, b128 %bitinsert_ptr, i32 32 => b64 ptr 0x8 [ptr]
+; CHECK-NEXT: %bitinsert_ptr_bytes = bitinsert b128 0, b64 %bitextract_ptr_bytes, i32 5 => b128 00000000(110!!!!!) 00000001(10000111) 00000000(00111011) 00000000(01101000) 00000000(10111001) 00000000(11111000) 00000000(00000110) 00000000(00011101) 00000000(!!!00101) 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+; CHECK-NEXT: %bitextract_ptr_via_bytes = bitextract ptr, b128 %bitinsert_ptr_bytes, i32 5 => ptr 0x8 [ptr]
+; CHECK-NEXT: ret void
+; CHECK-NEXT: Exiting function: main
diff --git a/llvm/tools/llubi/lib/Context.cpp b/llvm/tools/llubi/lib/Context.cpp
index d9e9bb668c93c..da38a01a0a408 100644
--- a/llvm/tools/llubi/lib/Context.cpp
+++ b/llvm/tools/llubi/lib/Context.cpp
@@ -829,6 +829,25 @@ void Context::toBytes(const AnyValue &Val, Type *Ty,
llvm_unreachable("Unsupported first class type.");
}
+AnyValue Context::extractBits(const ByteValue &Src, uint32_t OffsetInBits,
+ Type *Ty) {
+ assert(OffsetInBits + DL.getTypeSizeInBits(Ty).getFixedValue() <=
+ Src.getBitWidth() &&
+ "Bit range out of bounds");
+ return fromBytes(ConstBytesView(Src.bytes(), DL), Ty, OffsetInBits,
+ /*CheckPaddingBits=*/false,
+ /*ContainsUndefinedBits=*/nullptr);
+}
+
+void Context::insertBits(ByteValue &Base, uint32_t OffsetInBits,
+ const AnyValue &Val, Type *Ty) {
+ assert(OffsetInBits + DL.getTypeSizeInBits(Ty).getFixedValue() <=
+ Base.getBitWidth() &&
+ "Bit range out of bounds");
+ toBytes(Val, Ty, OffsetInBits, MutableBytesView(Base.mutableBytes(), DL),
+ /*PaddingBits=*/false);
+}
+
AnyValue Context::load(MemoryObject &MO, uint64_t Offset, Type *ValTy,
bool *ContainsUndefinedBits) {
return fromBytes(
diff --git a/llvm/tools/llubi/lib/Context.h b/llvm/tools/llubi/lib/Context.h
index 571be140cc83f..5d1a41e66bb3e 100644
--- a/llvm/tools/llubi/lib/Context.h
+++ b/llvm/tools/llubi/lib/Context.h
@@ -420,6 +420,13 @@ class Context {
bool *ContainsUndefinedBits = nullptr);
/// Convert a value to byte sequence. Padding bits are set to zero.
void toBytes(const AnyValue &Val, Type *Ty, MutableArrayRef<Byte> Bytes);
+ /// Read the bits [OffsetInBits, OffsetInBits + bitwidth(Ty)) of \p Src as a
+ /// value of type \p Ty. The bit range must be within \p Src.
+ AnyValue extractBits(const ByteValue &Src, uint32_t OffsetInBits, Type *Ty);
+ /// Overwrite the bits [OffsetInBits, OffsetInBits + bitwidth(Ty)) of \p Base
+ /// with \p Val. The bit range must be within \p Base.
+ void insertBits(ByteValue &Base, uint32_t OffsetInBits, const AnyValue &Val,
+ Type *Ty);
/// Direct memory load without checks.
AnyValue load(MemoryObject &MO, uint64_t Offset, Type *ValTy,
bool *ContainsUndefinedBits = nullptr);
diff --git a/llvm/tools/llubi/lib/Interpreter.cpp b/llvm/tools/llubi/lib/Interpreter.cpp
index 1154804b10d23..e7ef61ce86036 100644
--- a/llvm/tools/llubi/lib/Interpreter.cpp
+++ b/llvm/tools/llubi/lib/Interpreter.cpp
@@ -2899,6 +2899,35 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
setResult(BCI, Ctx.fromBytes(Bytes, BCI.getType()));
}
+ void visitBitInsertInst(BitInsertInst &BII) {
+ ByteValue Res = getValue(BII.getOperand(0)).asByte();
+ auto &Val = getValue(BII.getOperand(1));
+ auto &Offset = getValue(BII.getOperand(2));
+ Type *ValTy = BII.getOperand(1)->getType();
+ uint64_t NumBits = DL.getTypeSizeInBits(ValTy).getFixedValue();
+ uint64_t OffsetInBits =
+ Offset.isPoison() ? 0 : Offset.asInteger().getZExtValue();
+ if (Offset.isPoison() || OffsetInBits + NumBits > Res.getBitWidth()) {
+ setResult(BII, AnyValue::getPoisonValue(Ctx, BII.getType()));
+ return;
+ }
+ Ctx.insertBits(Res, OffsetInBits, Val, ValTy);
+ setResult(BII, std::move(Res));
+ }
+
+ void visitBitExtractInst(BitExtractInst &BEI) {
+ auto &Src = getValue(BEI.getOperand(0)).asByte();
+ auto &Offset = getValue(BEI.getOperand(1));
+ uint64_t NumBits = DL.getTypeSizeInBits(BEI.getType()).getFixedValue();
+ uint64_t OffsetInBits =
+ Offset.isPoison() ? 0 : Offset.asInteger().getZExtValue();
+ if (Offset.isPoison() || OffsetInBits + NumBits > Src.getBitWidth()) {
+ setResult(BEI, AnyValue::getPoisonValue(Ctx, BEI.getType()));
+ return;
+ }
+ setResult(BEI, Ctx.extractBits(Src, OffsetInBits, BEI.getType()));
+ }
+
void visitFreezeInst(FreezeInst &FI) {
AnyValue Val = getValue(FI.getOperand(0));
Ctx.freeze(Val, FI.getType());
More information about the llvm-branch-commits
mailing list