gollvm: sync with trunk

Sync with trunk at e53d4869a0d, part 1.

This update required quite a few changes. Highlights:

- the LLVM LIRBuilder class now has even more paths that assume that
  you are inserting instructions into an existing basic block parented
  by an existing function, as opposed to generating them without a
  parent. This required converting over all of the builder uses in the
  bridge to use the BlockLIRBuilder, which works around these issues.
  After this change the BinstructionsLIRBuilder helper is no longer
  referenced, so it has been removed.

- convert to using llvm::MaybeAlign as opposed to raw unsigned values
  in places where alignment is set on variables, etc.

- adapt to changes in the LLVM value type class hierarchy (no more
  SequentialType, new sibling types for fixed and variable length
  vector types)

- adapt to some signature changes in LLVM instruction creation
  functions (typically to be more explicit about types)

This CL takes care of llvm-goc, gotools, and libgo, however a lot
of the unit tests need to be remastered (this will be in a follow
on CL).

Updates golang/go#38728.

Change-Id: I491fe30edb4fb3ee9d6e509ebd8b2777e0373b8f
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/232497
Reviewed-by: eric fang <eric.fang@arm.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/bridge/go-llvm-bfunction.cpp b/bridge/go-llvm-bfunction.cpp
index 2dc331b..68e0282 100644
--- a/bridge/go-llvm-bfunction.cpp
+++ b/bridge/go-llvm-bfunction.cpp
@@ -354,8 +354,8 @@
 {
   lazyAbiSetup();
   assert(paramInfo.disp() == ParmDirect);
-  BinstructionsLIRBuilder builder(function()->getContext(), spillInstructions);
   TypeManager *tm = abiOracle_->tm();
+  BlockLIRBuilder builder(function(), this);
 
   // Simple case: param arrived in single register.
   if (paramInfo.abiTypes().size() == 1) {
@@ -371,6 +371,7 @@
     }
     llvm::Instruction *si = builder.CreateStore(arg, sploc);
     paramVar->setInitializer(si);
+    spillInstructions->appendInstructions(builder.instructions());
     return 1;
   }
 
@@ -395,6 +396,7 @@
     stinst = builder.CreateStore(argChunk, fieldgep);
   }
   paramVar->setInitializer(stinst);
+  spillInstructions->appendInstructions(builder.instructions());
 
   // All done.
   return paramInfo.abiTypes().size();
@@ -508,10 +510,9 @@
     BlockLIRBuilder bbuilder(function(), inamegen);
     uint64_t sz = tm->typeSize(fcnType_->resultType());
     uint64_t algn = tm->typeAlignment(fcnType_->resultType());
-    bbuilder.CreateMemCpy(rtnValueMem_, algn, toRet->value(), algn, sz);
-    std::vector<llvm::Instruction*> instructions = bbuilder.instructions();
-    for (auto i : instructions)
-      retInstrs->appendInstruction(i);
+    llvm::MaybeAlign malgn(algn);
+    bbuilder.CreateMemCpy(rtnValueMem_, malgn, toRet->value(), malgn, sz);
+    retInstrs->appendInstructions(bbuilder.instructions());
     llvm::Value *rval = nullptr;
     return rval;
   }
@@ -529,11 +530,12 @@
                       returnInfo.computeABIStructType(tm) :
                       returnInfo.abiType());
   llvm::Type *ptst = llvm::PointerType::get(llrt, 0);
-  BinstructionsLIRBuilder builder(function()->getContext(), retInstrs);
+  BlockLIRBuilder builder(function(), inamegen);
   std::string castname(namegen("cast"));
   llvm::Value *bitcast = builder.CreateBitCast(toRet->value(), ptst, castname);
   std::string loadname(namegen("ld"));
   llvm::Instruction *ldinst = builder.CreateLoad(bitcast, loadname);
+  retInstrs->appendInstructions(builder.instructions());
   return ldinst;
 }
 
diff --git a/bridge/go-llvm-builtins.cpp b/bridge/go-llvm-builtins.cpp
index 6f0f0b2..779aba5 100644
--- a/bridge/go-llvm-builtins.cpp
+++ b/bridge/go-llvm-builtins.cpp
@@ -347,7 +347,7 @@
 }
 
 static llvm::Value *builtinExtractReturnAddrMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                                  BinstructionsLIRBuilder *builder,
+                                                  BlockLIRBuilder *builder,
                                                   Llvm_backend *be)
 {
   // __builtin_extract_return_addr(uintptr) uintptr
@@ -362,7 +362,7 @@
 }
 
 static llvm::Value *builtinUnreachableMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                            BinstructionsLIRBuilder *builder,
+                                            BlockLIRBuilder *builder,
                                             Llvm_backend *be)
 {
   llvm::UnreachableInst *unr = builder->CreateUnreachable();
@@ -370,7 +370,7 @@
 }
 
 static llvm::Value *builtinMemsetMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                       BinstructionsLIRBuilder *builder,
+                                       BlockLIRBuilder *builder,
                                        Llvm_backend *be)
 {
   // __builtin_memset takes int32 as its second argument, whereas
@@ -406,7 +406,7 @@
 }
 
 static llvm::Value *atomicLoadMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                    BinstructionsLIRBuilder *builder,
+                                    BlockLIRBuilder *builder,
                                     Llvm_backend *be, int sz)
 {
   assert(args.size() == 2);
@@ -424,21 +424,21 @@
 }
 
 static llvm::Value *atomicLoad4Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                     BinstructionsLIRBuilder *builder,
+                                     BlockLIRBuilder *builder,
                                      Llvm_backend *be)
 {
   return atomicLoadMaker(args, builder, be, 4);
 }
 
 static llvm::Value *atomicLoad8Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                     BinstructionsLIRBuilder *builder,
+                                     BlockLIRBuilder *builder,
                                      Llvm_backend *be)
 {
   return atomicLoadMaker(args, builder, be, 8);
 }
 
 static llvm::Value *atomicStoreMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                     BinstructionsLIRBuilder *builder,
+                                     BlockLIRBuilder *builder,
                                      Llvm_backend *be, int sz)
 {
   assert(args.size() == 3);
@@ -454,14 +454,14 @@
 }
 
 static llvm::Value *atomicStore4Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                      BinstructionsLIRBuilder *builder,
+                                      BlockLIRBuilder *builder,
                                       Llvm_backend *be)
 {
   return atomicStoreMaker(args, builder, be, 4);
 }
 
 static llvm::Value *atomicStore8Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                      BinstructionsLIRBuilder *builder,
+                                      BlockLIRBuilder *builder,
                                       Llvm_backend *be)
 {
   return atomicStoreMaker(args, builder, be, 8);
@@ -469,7 +469,7 @@
 
 static llvm::Value *atomicRMWMaker(llvm::AtomicRMWInst::BinOp op,
                                    llvm::SmallVectorImpl<llvm::Value*> &args,
-                                   BinstructionsLIRBuilder *builder,
+                                   BlockLIRBuilder *builder,
                                    Llvm_backend *be)
 {
   assert(args.size() == 3);
@@ -482,14 +482,14 @@
 }
 
 static llvm::Value *atomicXchgMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                    BinstructionsLIRBuilder *builder,
+                                    BlockLIRBuilder *builder,
                                     Llvm_backend *be)
 {
   return atomicRMWMaker(llvm::AtomicRMWInst::Xchg, args, builder, be);
 }
 
 static llvm::Value *atomicAddMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                   BinstructionsLIRBuilder *builder,
+                                   BlockLIRBuilder *builder,
                                    Llvm_backend *be)
 {
   // atomicrmw returns the old content. We need to do the add.
@@ -498,7 +498,7 @@
 }
 
 static llvm::Value *atomicAndMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                   BinstructionsLIRBuilder *builder,
+                                   BlockLIRBuilder *builder,
                                    Llvm_backend *be)
 {
   // atomicrmw returns the old content. We need to do the and.
@@ -507,7 +507,7 @@
 }
 
 static llvm::Value *atomicOrMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                  BinstructionsLIRBuilder *builder,
+                                  BlockLIRBuilder *builder,
                                   Llvm_backend *be)
 {
   // atomicrmw returns the old content. We need to do the or.
@@ -516,7 +516,7 @@
 }
 
 static llvm::Value *atomicCasMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                   BinstructionsLIRBuilder *builder,
+                                   BlockLIRBuilder *builder,
                                    Llvm_backend *be)
 {
   assert(args.size() == 6);
diff --git a/bridge/go-llvm-builtins.h b/bridge/go-llvm-builtins.h
index fe36da1..2904c01 100644
--- a/bridge/go-llvm-builtins.h
+++ b/bridge/go-llvm-builtins.h
@@ -26,7 +26,7 @@
 typedef std::vector<Btype*> BuiltinEntryTypeVec;
 
 typedef llvm::Value *(*BuiltinExprMaker)(llvm::SmallVectorImpl<llvm::Value*> &args,
-                                         BinstructionsLIRBuilder *builder,
+                                         BlockLIRBuilder *builder,
                                          Llvm_backend *be);
 
 // An entry in a table of interesting builtin functions. A given entry
diff --git a/bridge/go-llvm-irbuilders.h b/bridge/go-llvm-irbuilders.h
index c855d97..537eb1d 100644
--- a/bridge/go-llvm-irbuilders.h
+++ b/bridge/go-llvm-irbuilders.h
@@ -54,39 +54,7 @@
   }
 };
 
-// Similar to the above, but adds to a Binstructions object.
-
-class BinstructionsInserter : public llvm::IRBuilderDefaultInserter {
- public:
-  BinstructionsInserter() : insns_(nullptr) { }
-  void setDest(Binstructions *insns) { assert(!insns_); insns_ = insns; }
-
-  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
-                    llvm::BasicBlock *BB,
-                    llvm::BasicBlock::iterator InsertPt) const {
-    assert(insns_);
-    insns_->appendInstruction(I);
-    I->setName(Name);
-  }
-
- private:
-    mutable Binstructions *insns_;
-};
-
-// Builder that appends to a specified Binstructions object
-
-class BinstructionsLIRBuilder :
-    public llvm::IRBuilder<llvm::ConstantFolder, BinstructionsInserter> {
-  typedef llvm::IRBuilder<llvm::ConstantFolder,
-                          BinstructionsInserter> IRBuilderB;
- public:
-  BinstructionsLIRBuilder(llvm::LLVMContext &context, Binstructions *insns) :
-      IRBuilderB(context, llvm::ConstantFolder()) {
-    getInserter().setDest(insns);
-  }
-};
-
-// Some of the methods in the LLVM IRBuilder class (ex: CreateMemCpy)
+// Many of the methods in the LLVM IRBuilder class (ex: CreateMemCpy)
 // assume that you are appending to an existing basic block (which is
 // typically not what we want to do in many cases in the bridge code).
 // Furthermore it is required that the block in question be already
diff --git a/bridge/go-llvm-materialize.cpp b/bridge/go-llvm-materialize.cpp
index 27a826f..da3c09d 100644
--- a/bridge/go-llvm-materialize.cpp
+++ b/bridge/go-llvm-materialize.cpp
@@ -1099,8 +1099,7 @@
 
 struct GenCallState {
   CABIOracle oracle;
-  Binstructions instructions;
-  BinstructionsLIRBuilder builder;
+  BlockLIRBuilder builder;
   std::vector<Bexpression *> resolvedArgs;
   llvm::SmallVector<llvm::Value *, 16> llargs;
   llvm::Value *chainVal;
@@ -1111,10 +1110,11 @@
   GenCallState(llvm::LLVMContext &context,
                Bfunction *callerFunc,
                BFunctionType *calleeFcnTyp,
-               TypeManager *tm)
+               TypeManager *tm,
+               NameGen *namegen,
+               llvm::Function *dummyFcn)
       : oracle(calleeFcnTyp, tm),
-        instructions(),
-        builder(context, &instructions),
+        builder(dummyFcn, namegen),
         chainVal(nullptr),
         sretTemp(nullptr),
         calleeFcnType(calleeFcnTyp),
@@ -1169,7 +1169,7 @@
     if (paramInfo.attr() == AttrNest)
       continue;
 
-    BinstructionsLIRBuilder &builder = state.builder;
+    BlockLIRBuilder &builder = state.builder;
 
     // For arguments not passed by value, no call to resolveVarContext
     // (we want var address, not var value).
@@ -1199,17 +1199,14 @@
       // be copied to the space allocated by the caller on the stack, and pass
       // the address of the copied version to the callee.
       if (paramInfo.attr() == AttrDoCopy) {
-        BlockLIRBuilder bbuilder(state.callerFcn->function(), this);
         TypeManager *tm = state.oracle.tm();
         Btype *bty = fnarg->btype();
         uint64_t sz = tm->typeSize(bty);
         uint64_t algn = tm->typeAlignment(bty);
+        llvm::MaybeAlign malgn(algn);
         std::string tname(namegen("doCopy.addr"));
         llvm::Value *tmpV = state.callerFcn->createTemporary(bty, tname);
-        bbuilder.CreateMemCpy(tmpV, algn, val, algn, sz);
-        std::vector<llvm::Instruction *> instructions = bbuilder.instructions();
-        for (auto i : instructions)
-          state.instructions.appendInstruction(i);
+        builder.CreateMemCpy(tmpV, malgn, val, malgn, sz);
         val = tmpV;
       }
       state.llargs.push_back(val);
@@ -1356,7 +1353,6 @@
 {
   const CABIParamInfo &returnInfo = state.oracle.returnInfo();
 
-
   if (needSretTemp(returnInfo, state.calleeFcnType)) {
     assert(state.sretTemp);
     assert(callExpr->value() == state.sretTemp);
@@ -1367,16 +1363,17 @@
       // the expected abstract result type of the function. Cast the
       // sret storage location to a pointer to the abi type and store
       // the ABI return value into it.
-      BinstructionsLIRBuilder builder(context_, callExpr);
       llvm::Type *rt = (returnInfo.abiTypes().size() == 1 ?
                         returnInfo.abiType()  :
                         returnInfo.computeABIStructType(typeManager()));
       llvm::Type *ptrt = llvm::PointerType::get(rt, 0);
       std::string castname(namegen("cast"));
-      llvm::Value *bitcast = builder.CreateBitCast(state.sretTemp,
-                                                   ptrt, castname);
+      llvm::Value *bitcast =
+          state.builder.CreateBitCast(state.sretTemp,
+                                      ptrt, castname);
       std::string stname(namegen("st"));
-      builder.CreateStore(callInst, bitcast);
+      state.builder.CreateStore(callInst, bitcast);
+      callExpr->appendInstructions(state.builder.instructions());
     }
   }
 }
@@ -1385,7 +1382,7 @@
 // This is not done as a builtin because, unlike other builtins,
 // we need the FE to tell us the result type.
 static llvm::Value *makeGetg(Btype *resType,
-                             BinstructionsLIRBuilder *builder,
+                             BlockLIRBuilder *builder,
                              Llvm_backend *be)
 {
   llvm::GlobalValue* g = be->module().getGlobalVariable("runtime.g");
@@ -1473,7 +1470,9 @@
   }
 
   // State object to help with marshalling of call arguments, etc.
-  GenCallState state(context_, caller, calleeFcnTyp, typeManager());
+  llvm::Function *dummyFcn = errorFunction_->function();
+  GenCallState state(context_, caller, calleeFcnTyp, typeManager(),
+                     nameTags(), dummyFcn);
 
   // Static chain expression if applicable
   if (chain_expr->btype() != void_type()) {
@@ -1515,10 +1514,14 @@
     callValue = (state.sretTemp ? state.sretTemp : call);
   }
 
+  Binstructions callInstructions;
+  std::vector<llvm::Instruction *> binstructions = state.builder.instructions();
+  for (auto i : binstructions)
+    callInstructions.appendInstruction(i);
+
   Bexpression *rval =
       nbuilder_.mkCall(rbtype, callValue, caller, fn_expr, chain_expr,
-                       state.resolvedArgs, state.instructions, location);
-  state.instructions.clear();
+                       state.resolvedArgs, callInstructions, location);
 
   if (call)
     genCallEpilog(state, call, rval);
diff --git a/bridge/go-llvm-typemanager.cpp b/bridge/go-llvm-typemanager.cpp
index 513e34f..2f5199d 100644
--- a/bridge/go-llvm-typemanager.cpp
+++ b/bridge/go-llvm-typemanager.cpp
@@ -1384,7 +1384,7 @@
 
 bool TypeManager::isLlvmCompositeType(llvm::Type *t)
 {
-  return llvm::isa<llvm::StructType>(t) || llvm::isa<llvm::SequentialType>(t);
+  return llvm::isa<llvm::StructType>(t) || llvm::isa<llvm::ArrayType>(t) || llvm::isa<llvm::VectorType>(t);
 }
 
 llvm::Type *TypeManager::getLlvmTypeAtIndex(llvm::Type *t, unsigned i)
@@ -1392,10 +1392,12 @@
   if (llvm::isa<llvm::StructType>(t)) {
     llvm::StructType *st = llvm::cast<llvm::StructType>(t);
     return st->getTypeAtIndex(i);
+  } else if (llvm::isa<llvm::ArrayType>(t)) {
+    llvm::ArrayType *at = llvm::cast<llvm::ArrayType>(t);
+    return at->getElementType();
   } else {
-    assert(llvm::isa<llvm::SequentialType>(t));
-    llvm::SequentialType *st = llvm::cast<llvm::SequentialType>(t);
-    return st->getElementType();
+    assert(llvm::isa<llvm::VectorType>(t));
+    return t->getScalarType();
   }
 }
 
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index bd00cdc..4bd0dce 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -612,7 +612,8 @@
     std::string ldname(tag);
     ldname += ".ld";
     ldname = namegen(ldname);
-    llvm::Instruction *loadInst = new llvm::LoadInst(spaceVal, ldname);
+    llvm::Type *vt = spaceVal->getType()->getPointerElementType();
+    llvm::Instruction *loadInst = new llvm::LoadInst(vt, spaceVal, ldname);
     rval = nbuilder_.mkDeref(loadResultType, loadInst, space, loc);
     rval->appendInstruction(loadInst);
   } else {
@@ -886,9 +887,11 @@
 
   // alignment of src expr
   unsigned algn = typeAlignment(srcType);
+  llvm::MaybeAlign malgn(algn);
 
   // Q: should we be using memmove here instead?
-  llvm::CallInst *call = builder->CreateMemCpy(dstLoc, algn, srcVal, algn, sz);
+  llvm::CallInst *call =
+      builder->CreateMemCpy(dstLoc, malgn, srcVal, malgn, sz);
 
   return call;
 }
@@ -2094,7 +2097,7 @@
           glob->setComdat(module().getOrInsertComdat(gname));
         }
         if (alignment)
-          glob->setAlignment(alignment);
+          glob->setAlignment(llvm::MaybeAlign(alignment));
         if (initializer)
           glob->setInitializer(initializer);
       }
@@ -2138,7 +2141,7 @@
                                   threadlocal, addressSpace_);
 
   if (alignment)
-    glob->setAlignment(alignment);
+    glob->setAlignment(llvm::MaybeAlign(alignment));
   if (inComdat == MV_InComdat) {
     assert(! gname.empty());
     glob->setComdat(module().getOrInsertComdat(gname));
@@ -3064,9 +3067,13 @@
   // target, operands, etc) to the CallInst 'call', but uses a
   // possibly-excepting call with landing pad.
   llvm::SmallVector<llvm::Value *, 8> args(call->arg_begin(), call->arg_end());
+  llvm::Value *callop = call->getCalledOperand();
+  llvm::PointerType *pft =
+      llvm::cast<llvm::PointerType>(callop->getType());
+  llvm::FunctionType *fty =
+      llvm::cast<llvm::FunctionType>(pft->getElementType());
   llvm::InvokeInst *invcall =
-      llvm::InvokeInst::Create(call->getCalledValue(),
-                               contbb, padbb, args,
+      llvm::InvokeInst::Create(fty, callop, contbb, padbb, args,
                                call->getName());
 
   // Rewrite uses of the original call's return value to be the new call's
diff --git a/bridge/go-llvm.h b/bridge/go-llvm.h
index 5cc83a5..ff77d3b 100644
--- a/bridge/go-llvm.h
+++ b/bridge/go-llvm.h
@@ -62,7 +62,6 @@
 class BuiltinEntry;
 class BuiltinTable;
 class BlockLIRBuilder;
-class BinstructionsLIRBuilder;
 struct GenCallState;
 
 #include "llvm/IR/GlobalValue.h"
diff --git a/bridge/go-sha1.cpp b/bridge/go-sha1.cpp
index 0fa9279..54925d5 100644
--- a/bridge/go-sha1.cpp
+++ b/bridge/go-sha1.cpp
@@ -11,6 +11,7 @@
 
 #include "go-sha1.h"
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/SHA1.h"
 
 class Llvm_Sha1_Helper : public Go_sha1_helper
diff --git a/passes/GoStatepoints.cpp b/passes/GoStatepoints.cpp
index a6801ba..55cb185 100644
--- a/passes/GoStatepoints.cpp
+++ b/passes/GoStatepoints.cpp
@@ -1257,7 +1257,8 @@
 
 // Create new attribute set containing only attributes which can be transferred
 // from original call to the safepoint.
-static AttributeList legalizeCallAttributes(AttributeList AL) {
+static AttributeList legalizeCallAttributes(LLVMContext &Ctx,
+                                            AttributeList AL) {
   if (AL.isEmpty())
     return AL;
 
@@ -1270,7 +1271,6 @@
       FnAttrs.remove(A);
   }
 
-  LLVMContext &Ctx = AL.getContext();
   AttributeList Ret = AttributeList::get(Ctx, AttributeList::FunctionIndex,
                                          AttributeSet::get(Ctx, FnAttrs));
 
@@ -1456,7 +1456,7 @@
   if (SD.StatepointID)
     StatepointID = *SD.StatepointID;
 
-  Value *CallTarget = Call->getCalledValue();
+  Value *CallTarget = Call->getCalledOperand();
   if (Function *F = dyn_cast<Function>(CallTarget)) {
     if (F->getIntrinsicID() == Intrinsic::experimental_deoptimize) {
       // Calls to llvm.experimental.deoptimize are lowered to calls to the
@@ -1508,7 +1508,8 @@
     // function attributes.  In case if we can handle this set of attributes -
     // set up function attrs directly on statepoint and return attrs later for
     // gc_result intrinsic.
-    Invoke->setAttributes(legalizeCallAttributes(ToReplace->getAttributes()));
+    Invoke->setAttributes(
+        legalizeCallAttributes(Invoke->getContext(), ToReplace->getAttributes()));
 
     Token = Invoke;
 
@@ -2967,7 +2968,8 @@
           Value *GEP = Builder.CreateConstInBoundsGEP2_32(
               TD->getType()->getPointerElementType(), TD, 0, 0);
           Value *Siz = Builder.CreateLoad(GEP);
-          Builder.CreateMemMove(Dst, 0, Src, 0, Siz);
+          llvm::MaybeAlign malgn(0);
+          Builder.CreateMemMove(Dst, malgn, Src, malgn, Siz);
           ToDel.insert(CI);
         }
       }
diff --git a/passes/Util.cpp b/passes/Util.cpp
index 560e838..483163c 100644
--- a/passes/Util.cpp
+++ b/passes/Util.cpp
@@ -31,8 +31,9 @@
     return true;
   case Type::ArrayTyID:
     return hasPointer(T->getArrayElementType());
-  case Type::VectorTyID:
-    return hasPointer(T->getVectorElementType());
+  case Type::FixedVectorTyID:
+  case Type::ScalableVectorTyID:
+    return hasPointer(T->getScalarType());
   case Type::StructTyID: {
     for (unsigned i = 0, e = T->getStructNumElements(); i < e; ++i)
       if (hasPointer(T->getStructElementType(i)))
@@ -66,9 +67,11 @@
     }
     break;
   }
-  case Type::VectorTyID: {
-    Type *ET = T->getVectorElementType();
-    for (unsigned i = 0, n = T->getVectorNumElements(); i < n; ++i) {
+  case Type::FixedVectorTyID:
+  case Type::ScalableVectorTyID: {
+    auto *VT = llvm::cast<llvm::VectorType>(T);
+    Type *ET = T->getScalarType();
+    for (unsigned i = 0, n = VT->getNumElements(); i < n; ++i) {
       Value *ivals[2] = { ConstantInt::get(Int32Ty, 0),
                           ConstantInt::get(Int32Ty, i) };
       ArrayRef<Value*> Idx = makeArrayRef(ivals, 2);