[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