[llvm] [ConstantFolding] Fold `bitinsert` and `bitextract` (PR #229115)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 11:51:58 PDT 2026


================
@@ -1729,6 +1734,86 @@ Constant *llvm::ConstantFoldIntegerCast(Constant *C, Type *DestTy,
   return ConstantFoldCastOperand(Instruction::ZExt, C, DestTy, DL);
 }
 
+Constant *llvm::ConstantFoldBitInsertOperands(Constant *Base, Constant *Val,
+                                              Constant *Offset,
+                                              const DataLayout &DL) {
+  // bitinsert C, C, undef -> poison
+  if (isa<UndefValue>(Offset))
+    return PoisonValue::get(Base->getType());
+
+  auto *COffset = dyn_cast<ConstantInt>(Offset);
+  if (!COffset)
+    return nullptr;
+
+  // bitinsert C, C, out_of_range -> poison
+  unsigned BaseBits = DL.getTypeSizeInBits(Base->getType());
+  unsigned Bits = DL.getTypeSizeInBits(Val->getType());
+  uint64_t Off = COffset->getZExtValue();
+  if (Off + Bits > BaseBits)
+    return PoisonValue::get(Base->getType());
+
+  // Overwriting every bit of the base is a bitcast of the value.
+  if (Bits == BaseBits)
+    return ConstantExpr::getBitCast(Val, Base->getType());
+
+  // bitinsert poison, poison, C -> poison
+  if (isa<PoisonValue>(Base) && isa<PoisonValue>(Val))
+    return Base;
+
+  // bitinsert undef, undef, C -> undef
+  if (isa<UndefValue>(Base) && !isa<PoisonValue>(Base) &&
+      isa<UndefValue>(Val) && !isa<PoisonValue>(Val))
+    return Base;
----------------
nikic wrote:

This could always return `UndefValue::get(Base->getType())`. Is the thought here that we want to preserve the fact that some bits are poison rather than refining them to undef?

https://github.com/llvm/llvm-project/pull/229115


More information about the llvm-commits mailing list