[OpaquePtr] Return opaque pointer from opaque pointer GEP

For a GEP on an opaque pointer, also return an opaque pointer (or
vector of opaque pointer) result.

This requires explicitly enumerating the GEP source element type,
because it is now no longer implicitly enumerated as part of either
the source or result pointer types.

Differential Revision: https://reviews.llvm.org/D104652
This commit is contained in:
Nikita Popov 2021-06-21 17:43:06 +02:00
parent 0a2d4f3f24
commit 9f779195d3
3 changed files with 30 additions and 8 deletions

View File

@ -1098,8 +1098,12 @@ public:
/// instruction, which may be a vector of pointers.
static Type *getGEPReturnType(Type *ElTy, Value *Ptr,
ArrayRef<Value *> IdxList) {
Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)),
Ptr->getType()->getPointerAddressSpace());
PointerType *OrigPtrTy = cast<PointerType>(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<VectorType>(Ptr->getType())) {
ElementCount EltCount = PtrVTy->getElementCount();

View File

@ -463,6 +463,8 @@ ValueEnumerator::ValueEnumerator(const Module &M,
}
if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I))
EnumerateType(SVI->getShuffleMaskForBitcode()->getType());
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I))
EnumerateType(GEP->getSourceElementType());
EnumerateType(I.getType());
if (const auto *Call = dyn_cast<CallBase>(&I))
EnumerateAttributes(Call->getAttributes());

View File

@ -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> <i32 1, i32 2>
; CHECK: ret <2 x ptr> %res
define <2 x ptr> @gep_vec1(ptr %a) {
%res = getelementptr i8, ptr %a, <2 x i32> <i32 1, i32 2>
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)