Fix cases where RSInvariant pass might miss marking some loads as invariant.

llvm-rs-cc and bcc can add numeric suffixes to structure type names; we need
to tolerate this when looking for the context structure by name.

Bug: 21815112
Change-Id: If5ef169245f8d43affdc43abb2298c7015568dd0
diff --git a/include/bcc/Renderscript/RSUtils.h b/include/bcc/Renderscript/RSUtils.h
index fa1fb1a..edc7fdf 100644
--- a/include/bcc/Renderscript/RSUtils.h
+++ b/include/bcc/Renderscript/RSUtils.h
@@ -20,9 +20,23 @@
 #include "rsDefines.h"
 
 #include <llvm/IR/Type.h>
+#include <llvm/IR/DerivedTypes.h>
 
 namespace {
 
+static inline llvm::StringRef getUnsuffixedStructName(const llvm::StructType *T) {
+  // Get just the object type name with no suffix.
+  size_t LastDot = T->getName().rfind('.');
+  if (LastDot == strlen("struct")) {
+    // If we get back to just the "struct" part, we know that we had a
+    // raw typename (i.e. struct.rs_element with no ".[0-9]+" suffix on it.
+    // In that case, we will want to create our slice such that it contains
+    // the entire name.
+    LastDot = T->getName().size();
+  }
+  return T->getStructName().slice(0, LastDot);
+}
+
 const char kAllocationTypeName[] = "struct.rs_allocation";
 const char kElementTypeName[]    = "struct.rs_element";
 const char kSamplerTypeName[]    = "struct.rs_sampler";
@@ -36,16 +50,7 @@
 // handling would be necessary.
 static inline enum RsDataType getRsDataTypeForType(const llvm::Type *T) {
   if (T->isStructTy()) {
-    // Get just the object type name with no suffix.
-    size_t LastDot = T->getStructName().rfind('.');
-    if (LastDot == strlen("struct")) {
-      // If we get back to just the "struct" part, we know that we had a
-      // raw typename (i.e. struct.rs_element with no ".[0-9]+" suffix on it.
-      // In that case, we will want to create our slice such that it contains
-      // the entire name.
-      LastDot = T->getStructName().size();
-    }
-    const llvm::StringRef StructName = T->getStructName().slice(0, LastDot);
+    const llvm::StringRef StructName = getUnsuffixedStructName(llvm::dyn_cast<const llvm::StructType>(T));
     if (StructName.equals(kAllocationTypeName)) {
       return RS_TYPE_ALLOCATION;
     } else if (StructName.equals(kElementTypeName)) {
diff --git a/lib/Renderscript/RSInvariant.cpp b/lib/Renderscript/RSInvariant.cpp
index a741a22..eb11d7e 100644
--- a/lib/Renderscript/RSInvariant.cpp
+++ b/lib/Renderscript/RSInvariant.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "bcc/Renderscript/RSTransforms.h"
+#include "bcc/Renderscript/RSUtils.h"
 
 #include <llvm/IR/Function.h>
 #include <llvm/IR/Instructions.h>
@@ -80,7 +81,7 @@
         const llvm::Type *ArgPtrDomainType =  ArgType->getPointerElementType();
         if (auto ArgPtrDomainStructType = llvm::dyn_cast<llvm::StructType>(ArgPtrDomainType)) {
           if (!ArgPtrDomainStructType->isLiteral()) {
-            const llvm::StringRef StructName = ArgPtrDomainStructType->getName();
+            const llvm::StringRef StructName = getUnsuffixedStructName(ArgPtrDomainStructType);
             if (StructName.equals("struct.rs_kernel_context_t") || StructName.equals("RsExpandKernelDriverInfoPfx")) {
               Changed |= markInvariantUserLoads(&Arg);
             }