@@ -2750,59 +2750,27 @@ bool IRTranslator::translateCallBase(const CallBase &CB,
2750
2750
return Success;
2751
2751
}
2752
2752
2753
- bool IRTranslator::translateCall (const User &U, MachineIRBuilder &MIRBuilder) {
2754
- if (containsBF16Type (U))
2755
- return false ;
2756
-
2757
- const CallInst &CI = cast<CallInst>(U);
2758
- const Function *F = CI.getCalledFunction ();
2759
-
2760
- // FIXME: support Windows dllimport function calls and calls through
2761
- // weak symbols.
2762
- if (F && (F->hasDLLImportStorageClass () ||
2763
- (MF->getTarget ().getTargetTriple ().isOSWindows () &&
2764
- F->hasExternalWeakLinkage ())))
2765
- return false ;
2766
-
2767
- // FIXME: support control flow guard targets.
2768
- if (CI.countOperandBundlesOfType (LLVMContext::OB_cfguardtarget))
2769
- return false ;
2770
-
2771
- // FIXME: support statepoints and related.
2772
- if (isa<GCStatepointInst, GCRelocateInst, GCResultInst>(U))
2773
- return false ;
2774
-
2775
- if (CI.isInlineAsm ())
2776
- return translateInlineAsm (CI, MIRBuilder);
2777
-
2778
- diagnoseDontCall (CI);
2779
-
2780
- Intrinsic::ID ID = Intrinsic::not_intrinsic;
2781
- if (F && F->isIntrinsic ())
2782
- ID = F->getIntrinsicID ();
2783
-
2784
- if (!F || !F->isIntrinsic () || ID == Intrinsic::not_intrinsic)
2785
- return translateCallBase (CI, MIRBuilder);
2786
-
2787
- assert (ID != Intrinsic::not_intrinsic && " unknown intrinsic" );
2788
-
2789
- if (translateKnownIntrinsic (CI, ID, MIRBuilder))
2790
- return true ;
2791
-
2753
+ // / Translate a call or callbr to a target intrinsic.
2754
+ // / Depending on whether TLI->getTgtMemIntrinsic() is true, TgtMemIntrinsicInfo
2755
+ // / is a pointer to the correspondingly populated IntrinsicInfo object.
2756
+ // / Otherwise, this pointer is null.
2757
+ bool IRTranslator::translateTargetIntrinsic (
2758
+ const CallBase &CB, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder,
2759
+ TargetLowering::IntrinsicInfo *TgtMemIntrinsicInfo) {
2792
2760
ArrayRef<Register> ResultRegs;
2793
- if (!CI .getType ()->isVoidTy ())
2794
- ResultRegs = getOrCreateVRegs (CI );
2761
+ if (!CB .getType ()->isVoidTy ())
2762
+ ResultRegs = getOrCreateVRegs (CB );
2795
2763
2796
2764
// Ignore the callsite attributes. Backend code is most likely not expecting
2797
2765
// an intrinsic to sometimes have side effects and sometimes not.
2798
2766
MachineInstrBuilder MIB = MIRBuilder.buildIntrinsic (ID, ResultRegs);
2799
- if (isa<FPMathOperator>(CI ))
2800
- MIB->copyIRFlags (CI );
2767
+ if (isa<FPMathOperator>(CB ))
2768
+ MIB->copyIRFlags (CB );
2801
2769
2802
- for (const auto &Arg : enumerate(CI .args ())) {
2770
+ for (const auto &Arg : enumerate(CB .args ())) {
2803
2771
// If this is required to be an immediate, don't materialize it in a
2804
2772
// register.
2805
- if (CI .paramHasAttr (Arg.index (), Attribute::ImmArg)) {
2773
+ if (CB .paramHasAttr (Arg.index (), Attribute::ImmArg)) {
2806
2774
if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg.value ())) {
2807
2775
// imm arguments are more convenient than cimm (and realistically
2808
2776
// probably sufficient), so use them.
@@ -2831,29 +2799,31 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
2831
2799
}
2832
2800
2833
2801
// Add a MachineMemOperand if it is a target mem intrinsic.
2834
- TargetLowering::IntrinsicInfo Info;
2835
- // TODO: Add a GlobalISel version of getTgtMemIntrinsic.
2836
- if (TLI->getTgtMemIntrinsic (Info, CI, *MF, ID)) {
2837
- Align Alignment = Info.align .value_or (
2838
- DL->getABITypeAlign (Info.memVT .getTypeForEVT (F->getContext ())));
2839
- LLT MemTy = Info.memVT .isSimple ()
2840
- ? getLLTForMVT (Info.memVT .getSimpleVT ())
2841
- : LLT::scalar (Info.memVT .getStoreSizeInBits ());
2802
+ if (TgtMemIntrinsicInfo) {
2803
+ const Function *F = CB.getCalledFunction ();
2804
+
2805
+ Align Alignment = TgtMemIntrinsicInfo->align .value_or (DL->getABITypeAlign (
2806
+ TgtMemIntrinsicInfo->memVT .getTypeForEVT (F->getContext ())));
2807
+ LLT MemTy =
2808
+ TgtMemIntrinsicInfo->memVT .isSimple ()
2809
+ ? getLLTForMVT (TgtMemIntrinsicInfo->memVT .getSimpleVT ())
2810
+ : LLT::scalar (TgtMemIntrinsicInfo->memVT .getStoreSizeInBits ());
2842
2811
2843
2812
// TODO: We currently just fallback to address space 0 if getTgtMemIntrinsic
2844
2813
// didn't yield anything useful.
2845
2814
MachinePointerInfo MPI;
2846
- if (Info.ptrVal )
2847
- MPI = MachinePointerInfo (Info.ptrVal , Info.offset );
2848
- else if (Info.fallbackAddressSpace )
2849
- MPI = MachinePointerInfo (*Info.fallbackAddressSpace );
2815
+ if (TgtMemIntrinsicInfo->ptrVal )
2816
+ MPI = MachinePointerInfo (TgtMemIntrinsicInfo->ptrVal ,
2817
+ TgtMemIntrinsicInfo->offset );
2818
+ else if (TgtMemIntrinsicInfo->fallbackAddressSpace )
2819
+ MPI = MachinePointerInfo (*TgtMemIntrinsicInfo->fallbackAddressSpace );
2850
2820
MIB.addMemOperand (MF->getMachineMemOperand (
2851
- MPI, Info. flags , MemTy, Alignment, CI.getAAMetadata (),
2852
- /* Ranges=*/ nullptr , Info. ssid , Info. order , Info. failureOrder ));
2821
+ MPI, TgtMemIntrinsicInfo-> flags , MemTy, Alignment, CI.getAAMetadata (),
2822
+ /* Ranges=*/ nullptr , TgtMemIntrinsicInfo-> ssid , TgtMemIntrinsicInfo-> order , TgtMemIntrinsicInfo-> failureOrder ));
2853
2823
}
2854
2824
2855
- if (CI .isConvergent ()) {
2856
- if (auto Bundle = CI .getOperandBundle (LLVMContext::OB_convergencectrl)) {
2825
+ if (CB .isConvergent ()) {
2826
+ if (auto Bundle = CB .getOperandBundle (LLVMContext::OB_convergencectrl)) {
2857
2827
auto *Token = Bundle->Inputs [0 ].get ();
2858
2828
Register TokenReg = getOrCreateVReg (*Token);
2859
2829
MIB.addUse (TokenReg, RegState::Implicit);
@@ -2863,6 +2833,53 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
2863
2833
return true ;
2864
2834
}
2865
2835
2836
+ bool IRTranslator::translateCall (const User &U, MachineIRBuilder &MIRBuilder) {
2837
+ if (containsBF16Type (U))
2838
+ return false ;
2839
+
2840
+ const CallInst &CI = cast<CallInst>(U);
2841
+ const Function *F = CI.getCalledFunction ();
2842
+
2843
+ // FIXME: support Windows dllimport function calls and calls through
2844
+ // weak symbols.
2845
+ if (F && (F->hasDLLImportStorageClass () ||
2846
+ (MF->getTarget ().getTargetTriple ().isOSWindows () &&
2847
+ F->hasExternalWeakLinkage ())))
2848
+ return false ;
2849
+
2850
+ // FIXME: support control flow guard targets.
2851
+ if (CI.countOperandBundlesOfType (LLVMContext::OB_cfguardtarget))
2852
+ return false ;
2853
+
2854
+ // FIXME: support statepoints and related.
2855
+ if (isa<GCStatepointInst, GCRelocateInst, GCResultInst>(U))
2856
+ return false ;
2857
+
2858
+ if (CI.isInlineAsm ())
2859
+ return translateInlineAsm (CI, MIRBuilder);
2860
+
2861
+ diagnoseDontCall (CI);
2862
+
2863
+ Intrinsic::ID ID = Intrinsic::not_intrinsic;
2864
+ if (F && F->isIntrinsic ())
2865
+ ID = F->getIntrinsicID ();
2866
+
2867
+ if (!F || !F->isIntrinsic () || ID == Intrinsic::not_intrinsic)
2868
+ return translateCallBase (CI, MIRBuilder);
2869
+
2870
+ assert (ID != Intrinsic::not_intrinsic && " unknown intrinsic" );
2871
+
2872
+ if (translateKnownIntrinsic (CI, ID, MIRBuilder))
2873
+ return true ;
2874
+
2875
+ TargetLowering::IntrinsicInfo Info;
2876
+ // TODO: Add a GlobalISel version of getTgtMemIntrinsic.
2877
+ bool IsTgtMemIntrinsic = TLI->getTgtMemIntrinsic (Info, CI, *MF, ID);
2878
+
2879
+ return translateTargetIntrinsic (CI, ID, MIRBuilder,
2880
+ IsTgtMemIntrinsic ? &Info : nullptr );
2881
+ }
2882
+
2866
2883
bool IRTranslator::findUnwindDestinations (
2867
2884
const BasicBlock *EHPadBB,
2868
2885
BranchProbability Prob,
@@ -3006,15 +3023,16 @@ bool IRTranslator::translateInvoke(const User &U,
3006
3023
return true ;
3007
3024
}
3008
3025
3026
+ // / The intrinsics currently supported by callbr are implicit control flow
3027
+ // / intrinsics such as amdgcn.kill.
3009
3028
bool IRTranslator::translateCallBr (const User &U,
3010
3029
MachineIRBuilder &MIRBuilder) {
3030
+ if (containsBF16Type (U))
3031
+ return false ; // see translateCall
3032
+
3011
3033
const CallBrInst &I = cast<CallBrInst>(U);
3012
3034
MachineBasicBlock *CallBrMBB = &MIRBuilder.getMBB ();
3013
3035
3014
- // TODO: operand bundles (see SelDAG implementation of callbr)?
3015
- assert (!I.hasOperandBundles () &&
3016
- " Cannot lower callbrs with operand bundles yet" );
3017
-
3018
3036
if (I.isInlineAsm ()) {
3019
3037
// FIXME: inline asm not yet supported
3020
3038
if (!translateInlineAsm (I, MIRBuilder))
@@ -3024,15 +3042,7 @@ bool IRTranslator::translateCallBr(const User &U,
3024
3042
default :
3025
3043
report_fatal_error (" Unsupported intrinsic for callbr" );
3026
3044
case Intrinsic::amdgcn_kill:
3027
- if (I.getNumIndirectDests () != 1 )
3028
- report_fatal_error (
3029
- " amdgcn.kill supportes exactly one indirect destination" );
3030
- CallInst *CI =
3031
- CallInst::Create (I.getFunctionType (), I.getCalledFunction (),
3032
- SmallVector<Value *, 1 >(I.args ()));
3033
- bool Success = translateCall (*CI, MIRBuilder);
3034
- CI->deleteValue ();
3035
- if (!Success)
3045
+ if (!translateTargetIntrinsic (I, Intrinsic::amdgcn_kill, MIRBuilder))
3036
3046
return false ;
3037
3047
break ;
3038
3048
}
0 commit comments