From b60818ba1433d5e36707134d0b627f4fc3fd69d9 Mon Sep 17 00:00:00 2001
From: Arina Neshlyaeva <arina.neshlyaeva@intel.com>
Date: Thu, 15 Sep 2022 15:01:43 -0700
Subject: [PATCH] Avoid using getPointerElementType in easy cases

---
 src/ctx.cpp    | 11 ++++++++---
 src/expr.cpp   |  2 +-
 src/module.cpp | 27 ++++++++++++---------------
 3 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/src/ctx.cpp b/src/ctx.cpp
index 23a628b16..9480f8567 100644
--- a/src/ctx.cpp
+++ b/src/ctx.cpp
@@ -1476,11 +1476,12 @@ static llvm::Value *lGetStringAsValue(llvm::BasicBlock *bblock, const char *s) {
     llvm::Constant *sConstant = llvm::ConstantDataArray::getString(*g->ctx, s, true);
     std::string var_name = "_";
     var_name = var_name + s;
-    llvm::Value *sPtr = new llvm::GlobalVariable(*m->module, sConstant->getType(), true /* const */,
-                                                 llvm::GlobalValue::InternalLinkage, sConstant, var_name.c_str());
+    llvm::GlobalVariable *sPtr =
+        new llvm::GlobalVariable(*m->module, sConstant->getType(), true /* const */, llvm::GlobalValue::InternalLinkage,
+                                 sConstant, var_name.c_str());
     llvm::Value *indices[2] = {LLVMInt32(0), LLVMInt32(0)};
     llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
-    return llvm::GetElementPtrInst::Create(PTYPE(sPtr), sPtr, arrayRef, "sptr", bblock);
+    return llvm::GetElementPtrInst::Create(sPtr->getValueType(), sPtr, arrayRef, "sptr", bblock);
 }
 
 void FunctionEmitContext::AddInstrumentationPoint(const char *note) {
@@ -2634,7 +2635,11 @@ llvm::Value *FunctionEmitContext::AddrSpaceCastInst(llvm::Value *val, AddressSpa
     if (pt->getAddressSpace() == (unsigned)as) {
         return val;
     }
+#if ISPC_LLVM_VERSION >= ISPC_LLVM_13_0
+    llvm::PointerType *newType = llvm::PointerType::getWithSamePointeeType(pt, (unsigned)as);
+#else
     llvm::PointerType *newType = llvm::PointerType::get(pt->getPointerElementType(), (unsigned)as);
+#endif
     llvm::AddrSpaceCastInst *inst;
     if (atEntryBlock) {
         inst = new llvm::AddrSpaceCastInst(val, newType, val->getName() + "__cast", allocaBlock->getTerminator());
diff --git a/src/expr.cpp b/src/expr.cpp
index e46ddf1de..2e5d44a7c 100644
--- a/src/expr.cpp
+++ b/src/expr.cpp
@@ -7728,7 +7728,7 @@ llvm::Value *AllocaExpr::GetValue(FunctionEmitContext *ctx) const {
     llvm::Value *llvmValue = expr->GetValue(ctx);
     if (llvmValue == NULL)
         return NULL;
-    llvm::Value *resultPtr = ctx->AllocaInst((LLVMTypes::VoidPointerType)->PTR_ELT_TYPE(), llvmValue, "allocaExpr", 16,
+    llvm::Value *resultPtr = ctx->AllocaInst(LLVMTypes::Int8Type, llvmValue, "allocaExpr", 16,
                                              false)
                                  ->getPointer(); // 16 byte stack alignment.
     return resultPtr;
diff --git a/src/module.cpp b/src/module.cpp
index 0c36d465c..562913f6a 100644
--- a/src/module.cpp
+++ b/src/module.cpp
@@ -2651,10 +2651,7 @@ static void lCreateDispatchFunction(llvm::Module *module, llvm::Function *setISA
 
     // Now we can load the system's ISA enumerant
 #if ISPC_LLVM_VERSION >= ISPC_LLVM_11_0
-    llvm::PointerType *ptr_type = llvm::dyn_cast<llvm::PointerType>(systemBestISAPtr->getType());
-    Assert(ptr_type);
-    llvm::Value *systemISA =
-        new llvm::LoadInst(ptr_type->getPointerElementType(), systemBestISAPtr, "system_isa", bblock);
+    llvm::Value *systemISA = new llvm::LoadInst(LLVMTypes::Int32Type, systemBestISAPtr, "system_isa", bblock);
 #else
     llvm::Value *systemISA = new llvm::LoadInst(systemBestISAPtr, "system_isa", bblock);
 #endif
@@ -2774,23 +2771,23 @@ static void lEmitDispatchModule(llvm::Module *module, std::map<std::string, Func
     optPM.run(*module);
 }
 
-// Determines if two types are compatible
+// Determines if two types are compatible.
+// Here we check layout compatibility. We don't care about pointer types.
 static bool lCompatibleTypes(llvm::Type *Ty1, llvm::Type *Ty2) {
     while (Ty1->getTypeID() == Ty2->getTypeID())
         switch (Ty1->getTypeID()) {
-        case llvm::ArrayType::ArrayTyID:
+        case llvm::Type::ArrayTyID:
             if (Ty1->getArrayNumElements() != Ty2->getArrayNumElements())
                 return false;
             Ty1 = Ty1->getArrayElementType();
             Ty2 = Ty2->getArrayElementType();
             break;
-
-        case llvm::ArrayType::PointerTyID:
-            Ty1 = Ty1->getPointerElementType();
-            Ty2 = Ty2->getPointerElementType();
-            break;
-
-        case llvm::ArrayType::StructTyID: {
+        case llvm::Type::PointerTyID:
+            // Uniform pointers are compatible.
+            // Varying pointers are represented as <N x i32>/<N x i64>, it'll
+            // be checked in default statement.
+            return true;
+        case llvm::Type::StructTyID: {
             llvm::StructType *STy1 = llvm::dyn_cast<llvm::StructType>(Ty1);
             llvm::StructType *STy2 = llvm::dyn_cast<llvm::StructType>(Ty2);
             return STy1 && STy2 && STy1->isLayoutIdentical(STy2);
@@ -2815,7 +2812,7 @@ static void lExtractOrCheckGlobals(llvm::Module *msrc, llvm::Module *mdst, bool
         llvm::GlobalVariable *gv = &*iter;
         // Is it a global definition?
         if (gv->getLinkage() == llvm::GlobalValue::ExternalLinkage && gv->hasInitializer()) {
-            llvm::Type *type = gv->getType()->PTR_ELT_TYPE();
+            llvm::Type *type = gv->getValueType();
             Symbol *sym = m->symbolTable->LookupVariable(gv->getName().str().c_str());
             Assert(sym != NULL);
 
@@ -2827,7 +2824,7 @@ static void lExtractOrCheckGlobals(llvm::Module *msrc, llvm::Module *mdst, bool
                 // It is possible that the types may not match: for
                 // example, this happens with varying globals if we
                 // compile to different vector widths
-                if (!lCompatibleTypes(exist->getType(), gv->getType())) {
+                if (!lCompatibleTypes(exist->getValueType(), gv->getValueType())) {
                     Warning(sym->pos,
                             "Mismatch in size/layout of global "
                             "variable \"%s\" with different targets. "
