[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:55 PDT 2026


================
@@ -4202,6 +4202,67 @@ void SelectionDAGBuilder::visitInsertElement(const User &I) {
                            InVec, InVal, InIdx));
 }
 
+void SelectionDAGBuilder::visitBitInsert(const User &I) {
+  SDValue Base = getValue(I.getOperand(0));
+  SDValue Val = getValue(I.getOperand(1));
+  SDValue Offset = getValue(I.getOperand(2));
+  EVT BaseVT = Base.getValueType();
+  EVT ValVT = Val.getValueType();
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  SDLoc dl = getCurSDLoc();
+
+  SDValue LegalOffset = DAG.getZExtOrTrunc(Offset, dl, BaseVT);
+
+  // Legalize rotate amount to the target's shift amount type.
+  EVT ShiftAmtTy = TLI.getShiftAmountTy(BaseVT, DAG.getDataLayout());
+  SDValue LegalRotateAmount = DAG.getZExtOrTrunc(LegalOffset, dl, ShiftAmtTy);
+
+  SDValue RotatedBase =
+      DAG.getNode(ISD::ROTR, dl, BaseVT, Base, LegalRotateAmount);
+
+  unsigned BaseBitWidth = BaseVT.getScalarSizeInBits();
+  unsigned ValBitWidth = ValVT.getScalarSizeInBits();
+  APInt ClearMask =
+      APInt::getHighBitsSet(BaseBitWidth, BaseBitWidth - ValBitWidth);
+  SDValue ClearedBase = DAG.getNode(ISD::AND, dl, BaseVT, RotatedBase,
+                                    DAG.getConstant(ClearMask, dl, BaseVT));
+
+  SDValue ExtVal = DAG.getZExtOrTrunc(Val, dl, BaseVT);
+  SDValue Inserted = DAG.getNode(ISD::OR, dl, BaseVT, ClearedBase, ExtVal);
+
+  SDValue Result =
+      DAG.getNode(ISD::ROTL, dl, BaseVT, Inserted, LegalRotateAmount);
+  setValue(&I, Result);
+}
+
+void SelectionDAGBuilder::visitBitExtract(const User &I) {
+  SDValue Src = getValue(I.getOperand(0));
+  SDValue Offset = getValue(I.getOperand(1));
+  EVT SrcVT = Src.getValueType();
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  EVT ResultVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
+  SDLoc dl = getCurSDLoc();
+
+  // The verifier guarantees the result type is not wider than the source
+  // type, so reject any widening case here. getZExtOrTrunc handles the
+  // equal-width and narrower cases.
+  if (ResultVT.getSizeInBits() > SrcVT.getSizeInBits())
+    llvm_unreachable(
+        "bitextract result wider than source should be rejected by verifier");
+
+  // Convert offset to SrcVT
+  SDValue LegalOffset = DAG.getZExtOrTrunc(Offset, dl, SrcVT);
+
+  // Legalize rotate amount to the target's shift amount type
----------------
aengelke wrote:

comment outdated

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


More information about the llvm-commits mailing list