4141#include " libSPIRV/SPIRVDebug.h"
4242
4343#include " llvm/IR/IRBuilder.h"
44- #include " llvm/IR/InstVisitor.h"
4544#include " llvm/IR/IntrinsicInst.h"
4645#include " llvm/IR/Module.h"
4746#include " llvm/IR/PassManager.h"
4847#include " llvm/Pass.h"
48+ #include " llvm/Transforms/Utils/LowerMemIntrinsics.h"
4949
5050using namespace llvm ;
5151using namespace SPIRV ;
5252
5353namespace SPIRV {
5454
55- class SPIRVLowerMemmoveBase : public InstVisitor <SPIRVLowerMemmoveBase> {
55+ class SPIRVLowerMemmoveBase {
5656public:
57- SPIRVLowerMemmoveBase () : Context(nullptr ) {}
58- virtual ~SPIRVLowerMemmoveBase () {}
59- virtual void visitMemMoveInst (MemMoveInst &I) {
57+ SPIRVLowerMemmoveBase () : Context(nullptr ), Mod(nullptr ) {}
58+ void LowerMemMoveInst (MemMoveInst &I) {
6059 IRBuilder<> Builder (I.getParent ());
6160 Builder.SetInsertPoint (&I);
6261 auto *Dest = I.getRawDest ();
@@ -65,11 +64,6 @@ class SPIRVLowerMemmoveBase : public InstVisitor<SPIRVLowerMemmoveBase> {
6564 report_fatal_error (" llvm.memmove of PHI instruction result not supported" ,
6665 false );
6766 auto *SrcTy = Src->getType ();
68- if (!isa<ConstantInt>(I.getLength ()))
69- // ToDo: for non-constant length, could use a loop to copy a
70- // fixed length chunk at a time. For now simply fail
71- report_fatal_error (" llvm.memmove of non-constant length not supported" ,
72- false );
7367 auto *Length = cast<ConstantInt>(I.getLength ());
7468 auto *S = Src;
7569 // The source could be bit-cast or addrspacecast from another type,
@@ -111,13 +105,36 @@ class SPIRVLowerMemmoveBase : public InstVisitor<SPIRVLowerMemmoveBase> {
111105 I.dropAllReferences ();
112106 I.eraseFromParent ();
113107 }
108+ bool expandMemMoveIntrinsicUses (Function &F) {
109+ bool Changed = false ;
110+
111+ for (User *U : make_early_inc_range (F.users ())) {
112+ MemMoveInst *Inst = cast<MemMoveInst>(U);
113+ if (!isa<ConstantInt>(Inst->getLength ())) {
114+ expandMemMoveAsLoop (Inst);
115+ Inst->eraseFromParent ();
116+ } else {
117+ LowerMemMoveInst (*Inst);
118+ }
119+ Changed = true ;
120+ }
121+ return Changed;
122+ }
114123 bool runLowerMemmove (Module &M) {
115124 Context = &M.getContext ();
116125 Mod = &M;
117- visit (M);
126+ bool Changed = false ;
127+
128+ for (Function &F : M) {
129+ if (!F.isDeclaration ())
130+ continue ;
131+
132+ if (F.getIntrinsicID () == Intrinsic::memmove)
133+ Changed |= expandMemMoveIntrinsicUses (F);
134+ }
118135
119136 verifyRegularizationPass (M, " SPIRVLowerMemmove" );
120- return true ;
137+ return Changed ;
121138 }
122139
123140private:
0 commit comments