@@ -39,11 +39,13 @@ class OpLowerer {
39
39
DXILOpBuilder OpBuilder;
40
40
DXILResourceMap &DRM;
41
41
DXILResourceTypeMap &DRTM;
42
+ const ModuleMetadataInfo &MMDI;
42
43
SmallVector<CallInst *> CleanupCasts;
43
44
44
45
public:
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) {}
47
49
48
50
// / Replace every call to \c F using \c ReplaceCall, and then erase \c F. If
49
51
// / there is an error replacing a call, we emit a diagnostic and return true.
@@ -745,6 +747,37 @@ class OpLowerer {
745
747
});
746
748
}
747
749
750
+ [[nodiscard]] bool lowerLifetimeIntrinsic (Function &F) {
751
+ IRBuilder<> &IRB = OpBuilder.getIRB ();
752
+ return replaceFunction (F, [&](CallInst *CI) -> Error {
753
+ IRB.SetInsertPoint (CI);
754
+ Value *Ptr = CI->getArgOperand (1 );
755
+ assert (Ptr->getType ()->isPointerTy () &&
756
+ " Expected operand of lifetime intrinsic to be a pointer" );
757
+
758
+ auto ZeroOrUndef = [&](Type *Ty) {
759
+ return MMDI.ValidatorVersion < VersionTuple (1 , 6 )
760
+ ? Constant::getNullValue (Ty)
761
+ : UndefValue::get (Ty);
762
+ };
763
+
764
+ Value *Val = nullptr ;
765
+ if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
766
+ if (GV->hasInitializer () || GV->isExternallyInitialized ())
767
+ return Error::success ();
768
+ Val = ZeroOrUndef (GV->getValueType ());
769
+ } else if (auto *AI = dyn_cast<AllocaInst>(Ptr))
770
+ Val = ZeroOrUndef (AI->getAllocatedType ());
771
+
772
+ assert (Val && " Expected operand of lifetime intrinsic to be a global "
773
+ " variable or alloca instruction" );
774
+ IRB.CreateStore (Val, Ptr, false );
775
+
776
+ CI->eraseFromParent ();
777
+ return Error::success ();
778
+ });
779
+ }
780
+
748
781
[[nodiscard]] bool lowerIsFPClass (Function &F) {
749
782
IRBuilder<> &IRB = OpBuilder.getIRB ();
750
783
Type *RetTy = IRB.getInt1Ty ();
@@ -803,8 +836,6 @@ class OpLowerer {
803
836
case Intrinsic::dx_resource_casthandle:
804
837
// NOTE: llvm.dbg.value is supported as is in DXIL.
805
838
case Intrinsic::dbg_value:
806
- case Intrinsic::lifetime_start:
807
- case Intrinsic::lifetime_end:
808
839
case Intrinsic::not_intrinsic:
809
840
if (F.use_empty ())
810
841
F.eraseFromParent ();
@@ -855,6 +886,17 @@ class OpLowerer {
855
886
case Intrinsic::ctpop:
856
887
HasErrors |= lowerCtpopToCountBits (F);
857
888
break ;
889
+ case Intrinsic::lifetime_start:
890
+ case Intrinsic::lifetime_end:
891
+ if (F.use_empty ())
892
+ F.eraseFromParent ();
893
+ else {
894
+ if (MMDI.DXILVersion < VersionTuple (1 , 6 ))
895
+ HasErrors |= lowerLifetimeIntrinsic (F);
896
+ else
897
+ continue ;
898
+ }
899
+ break ;
858
900
case Intrinsic::is_fpclass:
859
901
HasErrors |= lowerIsFPClass (F);
860
902
break ;
@@ -872,8 +914,9 @@ class OpLowerer {
872
914
PreservedAnalyses DXILOpLowering::run (Module &M, ModuleAnalysisManager &MAM) {
873
915
DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
874
916
DXILResourceTypeMap &DRTM = MAM.getResult <DXILResourceTypeAnalysis>(M);
917
+ const ModuleMetadataInfo MMDI = MAM.getResult <DXILMetadataAnalysis>(M);
875
918
876
- bool MadeChanges = OpLowerer (M, DRM, DRTM).lowerIntrinsics ();
919
+ bool MadeChanges = OpLowerer (M, DRM, DRTM, MMDI ).lowerIntrinsics ();
877
920
if (!MadeChanges)
878
921
return PreservedAnalyses::all ();
879
922
PreservedAnalyses PA;
@@ -891,8 +934,10 @@ class DXILOpLoweringLegacy : public ModulePass {
891
934
getAnalysis<DXILResourceWrapperPass>().getResourceMap ();
892
935
DXILResourceTypeMap &DRTM =
893
936
getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap ();
937
+ const ModuleMetadataInfo MMDI =
938
+ getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata ();
894
939
895
- return OpLowerer (M, DRM, DRTM).lowerIntrinsics ();
940
+ return OpLowerer (M, DRM, DRTM, MMDI ).lowerIntrinsics ();
896
941
}
897
942
StringRef getPassName () const override { return " DXIL Op Lowering" ; }
898
943
DXILOpLoweringLegacy () : ModulePass(ID) {}
@@ -901,6 +946,7 @@ class DXILOpLoweringLegacy : public ModulePass {
901
946
void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
902
947
AU.addRequired <DXILResourceTypeWrapperPass>();
903
948
AU.addRequired <DXILResourceWrapperPass>();
949
+ AU.addRequired <DXILMetadataAnalysisWrapperPass>();
904
950
AU.addPreserved <DXILResourceWrapperPass>();
905
951
AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
906
952
AU.addPreserved <ShaderFlagsAnalysisWrapper>();
0 commit comments