@@ -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.
@@ -316,8 +318,7 @@ class OpLowerer {
316
318
// / model and taking into account binding information from
317
319
// / DXILResourceAnalysis.
318
320
bool lowerHandleFromBinding (Function &F) {
319
- const Triple &TT = M.getTargetTriple ();
320
- if (TT.getDXILVersion () < VersionTuple (1 , 6 ))
321
+ if (MMDI.DXILVersion < VersionTuple (1 , 6 ))
321
322
return lowerToCreateHandle (F);
322
323
return lowerToBindAndAnnotateHandle (F);
323
324
}
@@ -486,8 +487,6 @@ class OpLowerer {
486
487
}
487
488
488
489
[[nodiscard]] bool lowerRawBufferLoad (Function &F) {
489
- const Triple &TT = M.getTargetTriple ();
490
- VersionTuple DXILVersion = TT.getDXILVersion ();
491
490
const DataLayout &DL = F.getDataLayout ();
492
491
IRBuilder<> &IRB = OpBuilder.getIRB ();
493
492
Type *Int8Ty = IRB.getInt8Ty ();
@@ -511,7 +510,7 @@ class OpLowerer {
511
510
ConstantInt::get (Int32Ty, DL.getPrefTypeAlign (ScalarTy).value ());
512
511
513
512
Expected<CallInst *> OpCall =
514
- DXILVersion >= VersionTuple (1 , 2 )
513
+ MMDI. DXILVersion >= VersionTuple (1 , 2 )
515
514
? OpBuilder.tryCreateOp (OpCode::RawBufferLoad,
516
515
{Handle, Index0, Index1, Mask, Align},
517
516
CI->getName (), NewRetTy)
@@ -586,8 +585,6 @@ class OpLowerer {
586
585
}
587
586
588
587
[[nodiscard]] bool lowerBufferStore (Function &F, bool IsRaw) {
589
- const Triple &TT = M.getTargetTriple ();
590
- VersionTuple DXILVersion = TT.getDXILVersion ();
591
588
const DataLayout &DL = F.getDataLayout ();
592
589
IRBuilder<> &IRB = OpBuilder.getIRB ();
593
590
Type *Int8Ty = IRB.getInt8Ty ();
@@ -654,7 +651,7 @@ class OpLowerer {
654
651
SmallVector<Value *, 9 > Args{
655
652
Handle, Index0, Index1, DataElements[0 ],
656
653
DataElements[1 ], DataElements[2 ], DataElements[3 ], Mask};
657
- if (IsRaw && DXILVersion >= VersionTuple (1 , 2 )) {
654
+ if (IsRaw && MMDI. DXILVersion >= VersionTuple (1 , 2 )) {
658
655
Op = OpCode::RawBufferStore;
659
656
// RawBufferStore requires the alignment
660
657
Args.push_back (
@@ -745,6 +742,37 @@ class OpLowerer {
745
742
});
746
743
}
747
744
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
+
748
776
[[nodiscard]] bool lowerIsFPClass (Function &F) {
749
777
IRBuilder<> &IRB = OpBuilder.getIRB ();
750
778
Type *RetTy = IRB.getInt1Ty ();
@@ -803,8 +831,6 @@ class OpLowerer {
803
831
case Intrinsic::dx_resource_casthandle:
804
832
// NOTE: llvm.dbg.value is supported as is in DXIL.
805
833
case Intrinsic::dbg_value:
806
- case Intrinsic::lifetime_start:
807
- case Intrinsic::lifetime_end:
808
834
case Intrinsic::not_intrinsic:
809
835
if (F.use_empty ())
810
836
F.eraseFromParent ();
@@ -855,6 +881,17 @@ class OpLowerer {
855
881
case Intrinsic::ctpop:
856
882
HasErrors |= lowerCtpopToCountBits (F);
857
883
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 ;
858
895
case Intrinsic::is_fpclass:
859
896
HasErrors |= lowerIsFPClass (F);
860
897
break ;
@@ -872,8 +909,9 @@ class OpLowerer {
872
909
PreservedAnalyses DXILOpLowering::run (Module &M, ModuleAnalysisManager &MAM) {
873
910
DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
874
911
DXILResourceTypeMap &DRTM = MAM.getResult <DXILResourceTypeAnalysis>(M);
912
+ const ModuleMetadataInfo MMDI = MAM.getResult <DXILMetadataAnalysis>(M);
875
913
876
- bool MadeChanges = OpLowerer (M, DRM, DRTM).lowerIntrinsics ();
914
+ const bool MadeChanges = OpLowerer (M, DRM, DRTM, MMDI ).lowerIntrinsics ();
877
915
if (!MadeChanges)
878
916
return PreservedAnalyses::all ();
879
917
PreservedAnalyses PA;
@@ -891,8 +929,10 @@ class DXILOpLoweringLegacy : public ModulePass {
891
929
getAnalysis<DXILResourceWrapperPass>().getResourceMap ();
892
930
DXILResourceTypeMap &DRTM =
893
931
getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap ();
932
+ const ModuleMetadataInfo MMDI =
933
+ getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata ();
894
934
895
- return OpLowerer (M, DRM, DRTM).lowerIntrinsics ();
935
+ return OpLowerer (M, DRM, DRTM, MMDI ).lowerIntrinsics ();
896
936
}
897
937
StringRef getPassName () const override { return " DXIL Op Lowering" ; }
898
938
DXILOpLoweringLegacy () : ModulePass(ID) {}
@@ -901,6 +941,7 @@ class DXILOpLoweringLegacy : public ModulePass {
901
941
void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
902
942
AU.addRequired <DXILResourceTypeWrapperPass>();
903
943
AU.addRequired <DXILResourceWrapperPass>();
944
+ AU.addRequired <DXILMetadataAnalysisWrapperPass>();
904
945
AU.addPreserved <DXILResourceWrapperPass>();
905
946
AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
906
947
AU.addPreserved <ShaderFlagsAnalysisWrapper>();
0 commit comments