diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3333,6 +3333,9 @@
       if (!Func->hasParamAttribute(i, Kind))
         continue;
 
+      if (Func->getParamAttribute(i, Kind).getValueAsType())
+        continue;
+
       Func->removeParamAttr(i, Kind);
 
       Type *PTy = cast<FunctionType>(FTy)->getParamType(i);
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -1046,6 +1046,10 @@
       AttributeGroups.push_back(Pair);
       Entry = AttributeGroups.size();
     }
+    for (Attribute Attr : AS) {
+      if (Attr.isTypeAttribute())
+        EnumerateType(Attr.getValueAsType());
+    }
   }
 }
 
diff --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -134,3 +134,8 @@
     cleanup
   ret void
 }
+
+; CHECK: define void @byval(ptr byval({ i32, i32 }) %0)
+define void @byval(ptr byval({ i32, i32 }) %0) {
+  ret void
+}