[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