@@ -3489,8 +3489,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
34893489
34903490 // Update successor info.
34913491 addSuccessorWithProb(CallBrMBB, Return, BranchProbability::getOne());
3492- for (unsigned i = 0, e = I.getNumIndirectDests(); i < e; ++i) {
3493- BasicBlock *Dest = I.getIndirectDest(i);
3492+ for (BasicBlock *Dest : I.getIndirectDests()) {
34943493 MachineBasicBlock *Target = FuncInfo.getMBB(Dest);
34953494 Target->setIsInlineAsmBrIndirectTarget();
34963495 // If we introduce a type of asm goto statement that is permitted to use an
@@ -5312,18 +5311,26 @@ void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
53125311 DAG.setRoot(OutChain);
53135312}
53145313
5315- /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
5316- /// node .
5317- void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
5318- unsigned Intrinsic) {
5319- // Ignore the callsite's attributes. A specific call site may be marked with
5320- // readnone, but the lowering code will expect the chain based on the
5321- // definition.
5314+ /// Check if this intrinsic call depends on the chain (1st return value)
5315+ /// and if it only *loads* memory .
5316+ /// Ignore the callsite's attributes. A specific call site may be marked with
5317+ /// readnone, but the lowering code will expect the chain based on the
5318+ /// definition.
5319+ std::pair<bool, bool>
5320+ SelectionDAGBuilder::getTargetIntrinsicCallProperties(const CallBase &I) {
53225321 const Function *F = I.getCalledFunction();
53235322 bool HasChain = !F->doesNotAccessMemory();
53245323 bool OnlyLoad =
53255324 HasChain && F->onlyReadsMemory() && F->willReturn() && F->doesNotThrow();
53265325
5326+ return {HasChain, OnlyLoad};
5327+ }
5328+
5329+ SmallVector<SDValue, 8> SelectionDAGBuilder::getTargetIntrinsicOperands(
5330+ const CallBase &I, bool HasChain, bool OnlyLoad,
5331+ TargetLowering::IntrinsicInfo *TgtMemIntrinsicInfo) {
5332+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5333+
53275334 // Build the operand list.
53285335 SmallVector<SDValue, 8> Ops;
53295336 if (HasChain) { // If this intrinsic has side-effects, chainify it.
@@ -5335,17 +5342,10 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
53355342 }
53365343 }
53375344
5338- // Info is set by getTgtMemIntrinsic
5339- TargetLowering::IntrinsicInfo Info;
5340- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5341- bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic(Info, I,
5342- DAG.getMachineFunction(),
5343- Intrinsic);
5344-
53455345 // Add the intrinsic ID as an integer operand if it's not a target intrinsic.
5346- if (!IsTgtIntrinsic || Info. opc == ISD::INTRINSIC_VOID ||
5347- Info. opc == ISD::INTRINSIC_W_CHAIN)
5348- Ops.push_back(DAG.getTargetConstant(Intrinsic , getCurSDLoc(),
5346+ if (!TgtMemIntrinsicInfo || TgtMemIntrinsicInfo-> opc == ISD::INTRINSIC_VOID ||
5347+ TgtMemIntrinsicInfo-> opc == ISD::INTRINSIC_W_CHAIN)
5348+ Ops.push_back(DAG.getTargetConstant(I.getIntrinsicID() , getCurSDLoc(),
53495349 TLI.getPointerTy(DAG.getDataLayout())));
53505350
53515351 // Add all operands of the call to the operand list.
@@ -5368,13 +5368,88 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
53685368 }
53695369 }
53705370
5371+ if (auto Bundle = I.getOperandBundle(LLVMContext::OB_convergencectrl)) {
5372+ auto *Token = Bundle->Inputs[0].get();
5373+ SDValue ConvControlToken = getValue(Token);
5374+ assert(Ops.back().getValueType() != MVT::Glue &&
5375+ "Did not expected another glue node here.");
5376+ ConvControlToken =
5377+ DAG.getNode(ISD::CONVERGENCECTRL_GLUE, {}, MVT::Glue, ConvControlToken);
5378+ Ops.push_back(ConvControlToken);
5379+ }
5380+
5381+ return Ops;
5382+ }
5383+
5384+ SDVTList SelectionDAGBuilder::getTargetIntrinsicVTList(const CallBase &I,
5385+ bool HasChain) {
5386+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5387+
53715388 SmallVector<EVT, 4> ValueVTs;
53725389 ComputeValueVTs(TLI, DAG.getDataLayout(), I.getType(), ValueVTs);
53735390
53745391 if (HasChain)
53755392 ValueVTs.push_back(MVT::Other);
53765393
5377- SDVTList VTs = DAG.getVTList(ValueVTs);
5394+ return DAG.getVTList(ValueVTs);
5395+ }
5396+
5397+ /// Get an INTRINSIC node for a target intrinsic which does not touch touch
5398+ /// memory.
5399+ SDValue SelectionDAGBuilder::getTargetNonMemIntrinsicNode(
5400+ const CallBase &I, bool HasChain, SmallVector<SDValue, 8> &Ops,
5401+ SDVTList &VTs) {
5402+ if (!HasChain)
5403+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurSDLoc(), VTs, Ops);
5404+ if (!I.getType()->isVoidTy())
5405+ return DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurSDLoc(), VTs, Ops);
5406+ return DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops);
5407+ }
5408+
5409+ /// Set root, convert return type if necessaey and check alignment.
5410+ SDValue SelectionDAGBuilder::handleTargetIntrinsicRet(const CallBase &I,
5411+ bool HasChain,
5412+ bool OnlyLoad,
5413+ SDValue Result) {
5414+ if (HasChain) {
5415+ SDValue Chain = Result.getValue(Result.getNode()->getNumValues() - 1);
5416+ if (OnlyLoad)
5417+ PendingLoads.push_back(Chain);
5418+ else
5419+ DAG.setRoot(Chain);
5420+ }
5421+
5422+ if (I.getType()->isVoidTy())
5423+ return Result;
5424+
5425+ if (!isa<VectorType>(I.getType()))
5426+ Result = lowerRangeToAssertZExt(DAG, I, Result);
5427+
5428+ MaybeAlign Alignment = I.getRetAlign();
5429+
5430+ // Insert `assertalign` node if there's an alignment.
5431+ if (InsertAssertAlign && Alignment) {
5432+ Result = DAG.getAssertAlign(getCurSDLoc(), Result, Alignment.valueOrOne());
5433+ }
5434+
5435+ return Result;
5436+ }
5437+
5438+ /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
5439+ /// node.
5440+ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
5441+ unsigned Intrinsic) {
5442+ auto [HasChain, OnlyLoad] = getTargetIntrinsicCallProperties(I);
5443+
5444+ // Info is set by getTgtMemIntrinsic
5445+ TargetLowering::IntrinsicInfo Info;
5446+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5447+ bool IsTgtMemIntrinsic =
5448+ TLI.getTgtMemIntrinsic(Info, I, DAG.getMachineFunction(), Intrinsic);
5449+
5450+ SmallVector<SDValue, 8> Ops = getTargetIntrinsicOperands(
5451+ I, HasChain, OnlyLoad, IsTgtMemIntrinsic ? &Info : nullptr);
5452+ SDVTList VTs = getTargetIntrinsicVTList(I, HasChain);
53785453
53795454 // Propagate fast-math-flags from IR to node(s).
53805455 SDNodeFlags Flags;
@@ -5385,19 +5460,9 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
53855460 // Create the node.
53865461 SDValue Result;
53875462
5388- if (auto Bundle = I.getOperandBundle(LLVMContext::OB_convergencectrl)) {
5389- auto *Token = Bundle->Inputs[0].get();
5390- SDValue ConvControlToken = getValue(Token);
5391- assert(Ops.back().getValueType() != MVT::Glue &&
5392- "Did not expected another glue node here.");
5393- ConvControlToken =
5394- DAG.getNode(ISD::CONVERGENCECTRL_GLUE, {}, MVT::Glue, ConvControlToken);
5395- Ops.push_back(ConvControlToken);
5396- }
5397-
53985463 // In some cases, custom collection of operands from CallInst I may be needed.
53995464 TLI.CollectTargetIntrinsicOperands(I, Ops, DAG);
5400- if (IsTgtIntrinsic ) {
5465+ if (IsTgtMemIntrinsic ) {
54015466 // This is target intrinsic that touches memory
54025467 //
54035468 // TODO: We currently just fallback to address space 0 if getTgtMemIntrinsic
@@ -5417,34 +5482,11 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
54175482 Info.ssid, Info.order, Info.failureOrder);
54185483 Result =
54195484 DAG.getMemIntrinsicNode(Info.opc, getCurSDLoc(), VTs, Ops, MemVT, MMO);
5420- } else if (!HasChain) {
5421- Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurSDLoc(), VTs, Ops);
5422- } else if (!I.getType()->isVoidTy()) {
5423- Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurSDLoc(), VTs, Ops);
54245485 } else {
5425- Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops );
5486+ Result = getTargetNonMemIntrinsicNode(I, HasChain, Ops, VTs );
54265487 }
54275488
5428- if (HasChain) {
5429- SDValue Chain = Result.getValue(Result.getNode()->getNumValues()-1);
5430- if (OnlyLoad)
5431- PendingLoads.push_back(Chain);
5432- else
5433- DAG.setRoot(Chain);
5434- }
5435-
5436- if (!I.getType()->isVoidTy()) {
5437- if (!isa<VectorType>(I.getType()))
5438- Result = lowerRangeToAssertZExt(DAG, I, Result);
5439-
5440- MaybeAlign Alignment = I.getRetAlign();
5441-
5442- // Insert `assertalign` node if there's an alignment.
5443- if (InsertAssertAlign && Alignment) {
5444- Result =
5445- DAG.getAssertAlign(getCurSDLoc(), Result, Alignment.valueOrOne());
5446- }
5447- }
5489+ Result = handleTargetIntrinsicRet(I, HasChain, OnlyLoad, Result);
54485490
54495491 setValue(&I, Result);
54505492}
0 commit comments