@@ -39,11 +39,13 @@ class OpLowerer {
3939 DXILOpBuilder OpBuilder;
4040 DXILResourceMap &DRM;
4141 DXILResourceTypeMap &DRTM;
42+ const ModuleMetadataInfo &MMDI;
4243 SmallVector<CallInst *> CleanupCasts;
4344
4445public:
45- OpLowerer (Module &M, DXILResourceMap &DRM, DXILResourceTypeMap &DRTM)
46- : M(M), OpBuilder(M), DRM(DRM), DRTM(DRTM) {}
46+ OpLowerer (Module &M, DXILResourceMap &DRM, DXILResourceTypeMap &DRTM,
47+ const ModuleMetadataInfo &MMDI)
48+ : M(M), OpBuilder(M), DRM(DRM), DRTM(DRTM), MMDI(MMDI) {}
4749
4850 // / Replace every call to \c F using \c ReplaceCall, and then erase \c F. If
4951 // / there is an error replacing a call, we emit a diagnostic and return true.
@@ -316,8 +318,7 @@ class OpLowerer {
316318 // / model and taking into account binding information from
317319 // / DXILResourceAnalysis.
318320 bool lowerHandleFromBinding (Function &F) {
319- const Triple &TT = M.getTargetTriple ();
320- if (TT.getDXILVersion () < VersionTuple (1 , 6 ))
321+ if (MMDI.DXILVersion < VersionTuple (1 , 6 ))
321322 return lowerToCreateHandle (F);
322323 return lowerToBindAndAnnotateHandle (F);
323324 }
@@ -486,8 +487,6 @@ class OpLowerer {
486487 }
487488
488489 [[nodiscard]] bool lowerRawBufferLoad (Function &F) {
489- const Triple &TT = M.getTargetTriple ();
490- VersionTuple DXILVersion = TT.getDXILVersion ();
491490 const DataLayout &DL = F.getDataLayout ();
492491 IRBuilder<> &IRB = OpBuilder.getIRB ();
493492 Type *Int8Ty = IRB.getInt8Ty ();
@@ -511,7 +510,7 @@ class OpLowerer {
511510 ConstantInt::get (Int32Ty, DL.getPrefTypeAlign (ScalarTy).value ());
512511
513512 Expected<CallInst *> OpCall =
514- DXILVersion >= VersionTuple (1 , 2 )
513+ MMDI. DXILVersion >= VersionTuple (1 , 2 )
515514 ? OpBuilder.tryCreateOp (OpCode::RawBufferLoad,
516515 {Handle, Index0, Index1, Mask, Align},
517516 CI->getName (), NewRetTy)
@@ -586,8 +585,6 @@ class OpLowerer {
586585 }
587586
588587 [[nodiscard]] bool lowerBufferStore (Function &F, bool IsRaw) {
589- const Triple &TT = M.getTargetTriple ();
590- VersionTuple DXILVersion = TT.getDXILVersion ();
591588 const DataLayout &DL = F.getDataLayout ();
592589 IRBuilder<> &IRB = OpBuilder.getIRB ();
593590 Type *Int8Ty = IRB.getInt8Ty ();
@@ -654,7 +651,7 @@ class OpLowerer {
654651 SmallVector<Value *, 9 > Args{
655652 Handle, Index0, Index1, DataElements[0 ],
656653 DataElements[1 ], DataElements[2 ], DataElements[3 ], Mask};
657- if (IsRaw && DXILVersion >= VersionTuple (1 , 2 )) {
654+ if (IsRaw && MMDI. DXILVersion >= VersionTuple (1 , 2 )) {
658655 Op = OpCode::RawBufferStore;
659656 // RawBufferStore requires the alignment
660657 Args.push_back (
@@ -745,6 +742,37 @@ class OpLowerer {
745742 });
746743 }
747744
745+ [[nodiscard]] bool lowerLifetimeIntrinsic (Function &F) {
746+ IRBuilder<> &IRB = OpBuilder.getIRB ();
747+ return replaceFunction (F, [&](CallInst *CI) -> Error {
748+ IRB.SetInsertPoint (CI);
749+ Value *Ptr = CI->getArgOperand (1 );
750+ assert (Ptr->getType ()->isPointerTy () &&
751+ " Expected operand of lifetime intrinsic to be a pointer" );
752+
753+ auto ZeroOrUndef = [&](Type *Ty) {
754+ return MMDI.ValidatorVersion < VersionTuple (1 , 6 )
755+ ? Constant::getNullValue (Ty)
756+ : UndefValue::get (Ty);
757+ };
758+
759+ Value *Val = nullptr ;
760+ if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
761+ if (GV->hasInitializer () || GV->isExternallyInitialized ())
762+ return Error::success ();
763+ Val = ZeroOrUndef (GV->getValueType ());
764+ } else if (auto *AI = dyn_cast<AllocaInst>(Ptr))
765+ Val = ZeroOrUndef (AI->getAllocatedType ());
766+
767+ assert (Val && " Expected operand of lifetime intrinsic to be a global "
768+ " variable or alloca instruction" );
769+ IRB.CreateStore (Val, Ptr, false );
770+
771+ CI->eraseFromParent ();
772+ return Error::success ();
773+ });
774+ }
775+
748776 [[nodiscard]] bool lowerIsFPClass (Function &F) {
749777 IRBuilder<> &IRB = OpBuilder.getIRB ();
750778 Type *RetTy = IRB.getInt1Ty ();
@@ -803,8 +831,6 @@ class OpLowerer {
803831 case Intrinsic::dx_resource_casthandle:
804832 // NOTE: llvm.dbg.value is supported as is in DXIL.
805833 case Intrinsic::dbg_value:
806- case Intrinsic::lifetime_start:
807- case Intrinsic::lifetime_end:
808834 case Intrinsic::not_intrinsic:
809835 if (F.use_empty ())
810836 F.eraseFromParent ();
@@ -855,6 +881,17 @@ class OpLowerer {
855881 case Intrinsic::ctpop:
856882 HasErrors |= lowerCtpopToCountBits (F);
857883 break ;
884+ case Intrinsic::lifetime_start:
885+ case Intrinsic::lifetime_end:
886+ if (F.use_empty ())
887+ F.eraseFromParent ();
888+ else {
889+ if (MMDI.DXILVersion < VersionTuple (1 , 6 ))
890+ HasErrors |= lowerLifetimeIntrinsic (F);
891+ else
892+ continue ;
893+ }
894+ break ;
858895 case Intrinsic::is_fpclass:
859896 HasErrors |= lowerIsFPClass (F);
860897 break ;
@@ -872,8 +909,9 @@ class OpLowerer {
872909PreservedAnalyses DXILOpLowering::run (Module &M, ModuleAnalysisManager &MAM) {
873910 DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
874911 DXILResourceTypeMap &DRTM = MAM.getResult <DXILResourceTypeAnalysis>(M);
912+ const ModuleMetadataInfo MMDI = MAM.getResult <DXILMetadataAnalysis>(M);
875913
876- bool MadeChanges = OpLowerer (M, DRM, DRTM).lowerIntrinsics ();
914+ const bool MadeChanges = OpLowerer (M, DRM, DRTM, MMDI ).lowerIntrinsics ();
877915 if (!MadeChanges)
878916 return PreservedAnalyses::all ();
879917 PreservedAnalyses PA;
@@ -891,8 +929,10 @@ class DXILOpLoweringLegacy : public ModulePass {
891929 getAnalysis<DXILResourceWrapperPass>().getResourceMap ();
892930 DXILResourceTypeMap &DRTM =
893931 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap ();
932+ const ModuleMetadataInfo MMDI =
933+ getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata ();
894934
895- return OpLowerer (M, DRM, DRTM).lowerIntrinsics ();
935+ return OpLowerer (M, DRM, DRTM, MMDI ).lowerIntrinsics ();
896936 }
897937 StringRef getPassName () const override { return " DXIL Op Lowering" ; }
898938 DXILOpLoweringLegacy () : ModulePass(ID) {}
@@ -901,6 +941,7 @@ class DXILOpLoweringLegacy : public ModulePass {
901941 void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
902942 AU.addRequired <DXILResourceTypeWrapperPass>();
903943 AU.addRequired <DXILResourceWrapperPass>();
944+ AU.addRequired <DXILMetadataAnalysisWrapperPass>();
904945 AU.addPreserved <DXILResourceWrapperPass>();
905946 AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
906947 AU.addPreserved <ShaderFlagsAnalysisWrapper>();
0 commit comments