diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index a133267ffe9c..5b334493eb41 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1098,8 +1098,12 @@ public: /// instruction, which may be a vector of pointers. static Type *getGEPReturnType(Type *ElTy, Value *Ptr, ArrayRef IdxList) { - Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)), - Ptr->getType()->getPointerAddressSpace()); + PointerType *OrigPtrTy = cast(Ptr->getType()->getScalarType()); + unsigned AddrSpace = OrigPtrTy->getAddressSpace(); + Type *ResultElemTy = checkGEPType(getIndexedType(ElTy, IdxList)); + Type *PtrTy = OrigPtrTy->isOpaque() + ? PointerType::get(OrigPtrTy->getContext(), AddrSpace) + : PointerType::get(ResultElemTy, AddrSpace); // Vector GEP if (auto *PtrVTy = dyn_cast(Ptr->getType())) { ElementCount EltCount = PtrVTy->getElementCount(); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 80c230da6a4b..abfdcd67524e 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -463,6 +463,8 @@ ValueEnumerator::ValueEnumerator(const Module &M, } if (auto *SVI = dyn_cast(&I)) EnumerateType(SVI->getShuffleMaskForBitcode()->getType()); + if (auto *GEP = dyn_cast(&I)) + EnumerateType(GEP->getSourceElementType()); EnumerateType(I.getType()); if (const auto *Call = dyn_cast(&I)) EnumerateAttributes(Call->getAttributes()); diff --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll index b3b35631188e..3a71da2f3537 100644 --- a/llvm/test/Assembler/opaque-ptr.ll +++ b/llvm/test/Assembler/opaque-ptr.ll @@ -41,12 +41,28 @@ define void @store(ptr %a, i32 %i) { ret void } -; CHECK: define void @gep(ptr %a) -; CHECK: %b = getelementptr i8, ptr %a, i32 2 -; CHECK: ret void -define void @gep(ptr %a) { - %b = getelementptr i8, ptr %a, i32 2 - ret void +; CHECK: define ptr @gep(ptr %a) +; CHECK: %res = getelementptr i8, ptr %a, i32 2 +; CHECK: ret ptr %res +define ptr @gep(ptr %a) { + %res = getelementptr i8, ptr %a, i32 2 + ret ptr %res +} + +; CHECK: define <2 x ptr> @gep_vec1(ptr %a) +; CHECK: %res = getelementptr i8, ptr %a, <2 x i32> +; CHECK: ret <2 x ptr> %res +define <2 x ptr> @gep_vec1(ptr %a) { + %res = getelementptr i8, ptr %a, <2 x i32> + ret <2 x ptr> %res +} + +; CHECK: define <2 x ptr> @gep_vec2(<2 x ptr> %a) +; CHECK: %res = getelementptr i8, <2 x ptr> %a, i32 2 +; CHECK: ret <2 x ptr> %res +define <2 x ptr> @gep_vec2(<2 x ptr> %a) { + %res = getelementptr i8, <2 x ptr> %a, i32 2 + ret <2 x ptr> %res } ; CHECK: define void @cmpxchg(ptr %p, i32 %a, i32 %b)