[llvm-branch-commits] [llvm] [InstSimplify] Simplify `bitinsert` and `bitextract` (PR #229125)

Yingwei Zheng via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Oct 6 11:53:02 PDT 2026


================
@@ -5616,6 +5616,89 @@ Value *llvm::simplifyExtractElementInst(Value *Vec, Value *Idx,
   return ::simplifyExtractElementInst(Vec, Idx, Q, RecursionLimit);
 }
 
+/// Return true if accessing the bit range of type Ty at Offset in a value of
+/// type SrcTy is poison.
+static bool isPoisonBitRange(Value *Offset, Type *Ty, Type *SrcTy,
+                             const SimplifyQuery &Q) {
+  // A poison offset makes the result poison. An undef offset can be chosen to
+  // be out of range, which also makes the result poison.
+  if (isa<PoisonValue>(Offset) || Q.isUndefValue(Offset))
+    return true;
+
+  // Accessing bits past the end of the value is poison.
+  const APInt *Off;
+  return match(Offset, m_APInt(Off)) &&
+         Off->getZExtValue() + Q.DL.getTypeSizeInBits(Ty).getFixedValue() >
+             Q.DL.getTypeSizeInBits(SrcTy).getFixedValue();
+}
+
+/// Given operands for a BitInsertInst, see if we can fold the result.
+/// If not, this returns null.
+static Value *simplifyBitInsertInst(Value *Base, Value *Val, Value *Offset,
+                                    const SimplifyQuery &Q, unsigned) {
+  auto *CBase = dyn_cast<Constant>(Base);
+  auto *CVal = dyn_cast<Constant>(Val);
+  auto *COffset = dyn_cast<Constant>(Offset);
+  if (CBase && CVal && COffset)
+    if (Constant *C = ConstantFoldBitInsertOperands(CBase, CVal, COffset, Q.DL))
+      return C;
+
+  // bitinsert x, y, poison/undef/out_of_range -> poison
+  if (isPoisonBitRange(Offset, Val->getType(), Base->getType(), Q))
+    return PoisonValue::get(Base->getType());
+
+  // bitinsert x, (bN y), n -> y, since any n != 0 is poison
+  if (Val->getType() == Base->getType())
+    return Val;
+
+  // bitinsert x, (bitextract bM, x, n), n -> x
+  // Only fold byte extracts, which keep every bit as is. Other extracts can
----------------
dtcxzyw wrote:

For other types, returning x is still a valid refinement.


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


More information about the llvm-branch-commits mailing list