@@ -3490,8 +3490,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
34903490
34913491 // Update successor info.
34923492 addSuccessorWithProb(CallBrMBB, Return, BranchProbability::getOne());
3493- for (unsigned i = 0 , e = I.getNumIndirectDests (); i < e; ++i) {
3494- BasicBlock *Dest = I.getIndirectDest (i);
3493+ for (BasicBlock *Dest : I.getIndirectDests()) {
34953494 MachineBasicBlock *Target = FuncInfo.getMBB(Dest);
34963495 Target->setIsInlineAsmBrIndirectTarget();
34973496 // If we introduce a type of asm goto statement that is permitted to use an
@@ -5304,18 +5303,26 @@ void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
53045303 DAG.setRoot(OutChain);
53055304}
53065305
5307- // / visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
5308- // / node .
5309- void SelectionDAGBuilder::visitTargetIntrinsic ( const CallInst &I,
5310- unsigned Intrinsic) {
5311- // Ignore the callsite's attributes. A specific call site may be marked with
5312- // readnone, but the lowering code will expect the chain based on the
5313- // definition.
5306+ /// Check if this intrinsic call depends on the chain (1st return value)
5307+ /// and if it only *loads* memory .
5308+ /// Ignore the callsite's attributes. A specific call site may be marked with
5309+ /// readnone, but the lowering code will expect the chain based on the
5310+ /// definition.
5311+ std::pair<bool, bool>
5312+ SelectionDAGBuilder::getTargetIntrinsicCallProperties(const CallBase &I) {
53145313 const Function *F = I.getCalledFunction();
53155314 bool HasChain = !F->doesNotAccessMemory();
53165315 bool OnlyLoad =
53175316 HasChain && F->onlyReadsMemory() && F->willReturn() && F->doesNotThrow();
53185317
5318+ return {HasChain, OnlyLoad};
5319+ }
5320+
5321+ SmallVector<SDValue, 8> SelectionDAGBuilder::getTargetIntrinsicOperands(
5322+ const CallBase &I, bool HasChain, bool OnlyLoad,
5323+ TargetLowering::IntrinsicInfo *TgtMemIntrinsicInfo) {
5324+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5325+
53195326 // Build the operand list.
53205327 SmallVector<SDValue, 8> Ops;
53215328 if (HasChain) { // If this intrinsic has side-effects, chainify it.
@@ -5327,17 +5334,10 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
53275334 }
53285335 }
53295336
5330- // Info is set by getTgtMemIntrinsic
5331- TargetLowering::IntrinsicInfo Info;
5332- const TargetLowering &TLI = DAG.getTargetLoweringInfo ();
5333- bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic (Info, I,
5334- DAG.getMachineFunction (),
5335- Intrinsic);
5336-
53375337 // Add the intrinsic ID as an integer operand if it's not a target intrinsic.
5338- if (!IsTgtIntrinsic || Info. opc == ISD::INTRINSIC_VOID ||
5339- Info. opc == ISD::INTRINSIC_W_CHAIN)
5340- Ops.push_back (DAG.getTargetConstant (Intrinsic , getCurSDLoc (),
5338+ if (!TgtMemIntrinsicInfo || TgtMemIntrinsicInfo-> opc == ISD::INTRINSIC_VOID ||
5339+ TgtMemIntrinsicInfo-> opc == ISD::INTRINSIC_W_CHAIN)
5340+ Ops.push_back(DAG.getTargetConstant(I.getIntrinsicID() , getCurSDLoc(),
53415341 TLI.getPointerTy(DAG.getDataLayout())));
53425342
53435343 // Add all operands of the call to the operand list.
@@ -5360,13 +5360,88 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
53605360 }
53615361 }
53625362
5363+ if (auto Bundle = I.getOperandBundle(LLVMContext::OB_convergencectrl)) {
5364+ auto *Token = Bundle->Inputs[0].get();
5365+ SDValue ConvControlToken = getValue(Token);
5366+ assert(Ops.back().getValueType() != MVT::Glue &&
5367+ "Did not expected another glue node here.");
5368+ ConvControlToken =
5369+ DAG.getNode(ISD::CONVERGENCECTRL_GLUE, {}, MVT::Glue, ConvControlToken);
5370+ Ops.push_back(ConvControlToken);
5371+ }
5372+
5373+ return Ops;
5374+ }
5375+
5376+ SDVTList SelectionDAGBuilder::getTargetIntrinsicVTList(const CallBase &I,
5377+ bool HasChain) {
5378+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5379+
53635380 SmallVector<EVT, 4> ValueVTs;
53645381 ComputeValueVTs(TLI, DAG.getDataLayout(), I.getType(), ValueVTs);
53655382
53665383 if (HasChain)
53675384 ValueVTs.push_back(MVT::Other);
53685385
5369- SDVTList VTs = DAG.getVTList (ValueVTs);
5386+ return DAG.getVTList(ValueVTs);
5387+ }
5388+
5389+ /// Get an INTRINSIC node for a target intrinsic which does not touch touch
5390+ /// memory.
5391+ SDValue SelectionDAGBuilder::getTargetNonMemIntrinsicNode(
5392+ const CallBase &I, bool HasChain, SmallVector<SDValue, 8> &Ops,
5393+ SDVTList &VTs) {
5394+ if (!HasChain)
5395+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurSDLoc(), VTs, Ops);
5396+ if (!I.getType()->isVoidTy())
5397+ return DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurSDLoc(), VTs, Ops);
5398+ return DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops);
5399+ }
5400+
5401+ /// Set root, convert return type if necessaey and check alignment.
5402+ SDValue SelectionDAGBuilder::handleTargetIntrinsicRet(const CallBase &I,
5403+ bool HasChain,
5404+ bool OnlyLoad,
5405+ SDValue Result) {
5406+ if (HasChain) {
5407+ SDValue Chain = Result.getValue(Result.getNode()->getNumValues() - 1);
5408+ if (OnlyLoad)
5409+ PendingLoads.push_back(Chain);
5410+ else
5411+ DAG.setRoot(Chain);
5412+ }
5413+
5414+ if (I.getType()->isVoidTy())
5415+ return Result;
5416+
5417+ if (!isa<VectorType>(I.getType()))
5418+ Result = lowerRangeToAssertZExt(DAG, I, Result);
5419+
5420+ MaybeAlign Alignment = I.getRetAlign();
5421+
5422+ // Insert `assertalign` node if there's an alignment.
5423+ if (InsertAssertAlign && Alignment) {
5424+ Result = DAG.getAssertAlign(getCurSDLoc(), Result, Alignment.valueOrOne());
5425+ }
5426+
5427+ return Result;
5428+ }
5429+
5430+ /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
5431+ /// node.
5432+ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
5433+ unsigned Intrinsic) {
5434+ auto [HasChain, OnlyLoad] = getTargetIntrinsicCallProperties(I);
5435+
5436+ // Info is set by getTgtMemIntrinsic
5437+ TargetLowering::IntrinsicInfo Info;
5438+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5439+ bool IsTgtMemIntrinsic =
5440+ TLI.getTgtMemIntrinsic(Info, I, DAG.getMachineFunction(), Intrinsic);
5441+
5442+ SmallVector<SDValue, 8> Ops = getTargetIntrinsicOperands(
5443+ I, HasChain, OnlyLoad, IsTgtMemIntrinsic ? &Info : nullptr);
5444+ SDVTList VTs = getTargetIntrinsicVTList(I, HasChain);
53705445
53715446 // Propagate fast-math-flags from IR to node(s).
53725447 SDNodeFlags Flags;
@@ -5377,19 +5452,9 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
53775452 // Create the node.
53785453 SDValue Result;
53795454
5380- if (auto Bundle = I.getOperandBundle (LLVMContext::OB_convergencectrl)) {
5381- auto *Token = Bundle->Inputs [0 ].get ();
5382- SDValue ConvControlToken = getValue (Token);
5383- assert (Ops.back ().getValueType () != MVT::Glue &&
5384- " Did not expected another glue node here." );
5385- ConvControlToken =
5386- DAG.getNode (ISD::CONVERGENCECTRL_GLUE, {}, MVT::Glue, ConvControlToken);
5387- Ops.push_back (ConvControlToken);
5388- }
5389-
53905455 // In some cases, custom collection of operands from CallInst I may be needed.
53915456 TLI.CollectTargetIntrinsicOperands(I, Ops, DAG);
5392- if (IsTgtIntrinsic ) {
5457+ if (IsTgtMemIntrinsic ) {
53935458 // This is target intrinsic that touches memory
53945459 //
53955460 // TODO: We currently just fallback to address space 0 if getTgtMemIntrinsic
@@ -5409,34 +5474,11 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
54095474 Info.ssid, Info.order, Info.failureOrder);
54105475 Result =
54115476 DAG.getMemIntrinsicNode(Info.opc, getCurSDLoc(), VTs, Ops, MemVT, MMO);
5412- } else if (!HasChain) {
5413- Result = DAG.getNode (ISD::INTRINSIC_WO_CHAIN, getCurSDLoc (), VTs, Ops);
5414- } else if (!I.getType ()->isVoidTy ()) {
5415- Result = DAG.getNode (ISD::INTRINSIC_W_CHAIN, getCurSDLoc (), VTs, Ops);
54165477 } else {
5417- Result = DAG. getNode (ISD::INTRINSIC_VOID, getCurSDLoc (), VTs, Ops );
5478+ Result = getTargetNonMemIntrinsicNode(I, HasChain, Ops, VTs );
54185479 }
54195480
5420- if (HasChain) {
5421- SDValue Chain = Result.getValue (Result.getNode ()->getNumValues ()-1 );
5422- if (OnlyLoad)
5423- PendingLoads.push_back (Chain);
5424- else
5425- DAG.setRoot (Chain);
5426- }
5427-
5428- if (!I.getType ()->isVoidTy ()) {
5429- if (!isa<VectorType>(I.getType ()))
5430- Result = lowerRangeToAssertZExt (DAG, I, Result);
5431-
5432- MaybeAlign Alignment = I.getRetAlign ();
5433-
5434- // Insert `assertalign` node if there's an alignment.
5435- if (InsertAssertAlign && Alignment) {
5436- Result =
5437- DAG.getAssertAlign (getCurSDLoc (), Result, Alignment.valueOrOne ());
5438- }
5439- }
5481+ Result = handleTargetIntrinsicRet(I, HasChain, OnlyLoad, Result);
54405482
54415483 setValue(&I, Result);
54425484}
0 commit comments