[IR] Support ifuncs in opaque pointer mode

Relax the type assertion for opaque pointers, and enumerate the
value type in TypeFinder and ValueEnumerator.
This commit is contained in:
Nikita Popov 2022-01-27 12:46:47 +01:00
parent 659bf6d08c
commit 97916673d4
6 changed files with 36 additions and 19 deletions

View File

@ -985,17 +985,18 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, LocTy NameLoc,
return error(AliaseeLoc, "An alias or ifunc must have pointer type");
unsigned AddrSpace = PTy->getAddressSpace();
if (IsAlias && !PTy->isOpaqueOrPointeeTypeMatches(Ty)) {
return error(
ExplicitTypeLoc,
typeComparisonErrorMessage(
"explicit pointee type doesn't match operand's pointee type", Ty,
PTy->getNonOpaquePointerElementType()));
}
if (!IsAlias && !PTy->getPointerElementType()->isFunctionTy()) {
return error(ExplicitTypeLoc,
"explicit pointee type should be a function type");
if (IsAlias) {
if (!PTy->isOpaqueOrPointeeTypeMatches(Ty))
return error(
ExplicitTypeLoc,
typeComparisonErrorMessage(
"explicit pointee type doesn't match operand's pointee type", Ty,
PTy->getNonOpaquePointerElementType()));
} else {
if (!PTy->isOpaque() &&
!PTy->getNonOpaquePointerElementType()->isFunctionTy())
return error(ExplicitTypeLoc,
"explicit pointee type should be a function type");
}
GlobalValue *GVal = nullptr;

View File

@ -386,8 +386,10 @@ ValueEnumerator::ValueEnumerator(const Module &M,
}
// Enumerate the ifuncs.
for (const GlobalIFunc &GIF : M.ifuncs())
for (const GlobalIFunc &GIF : M.ifuncs()) {
EnumerateValue(&GIF);
EnumerateType(GIF.getValueType());
}
// Remember what is the cutoff between globalvalue's and other constants.
unsigned FirstConstant = Values.size();

View File

@ -48,6 +48,10 @@ void TypeFinder::run(const Module &M, bool onlyNamed) {
incorporateValue(Aliasee);
}
// Get types from ifuncs.
for (const auto &GI : M.ifuncs())
incorporateType(GI.getValueType());
// Get types from functions.
SmallVector<std::pair<unsigned, MDNode *>, 4> MDForInst;
for (const Function &FI : M) {

View File

@ -1,12 +1,13 @@
; RUN: opt -S -opaque-pointers < %s | opt -S -opaque-pointers | FileCheck %s
; CHECK: %T1 = type { i8 }
; CHECK: %T2 = type { i8 }
; CHECK: %T3 = type { i8 }
; CHECK: %T4 = type { i8 }
; CHECK: %T5 = type { i8 }
; CHECK: %T6 = type { i8 }
; CHECK: %T7 = type { i8 }
; CHECK-DAG: %T1 = type { i8 }
; CHECK-DAG: %T2 = type { i8 }
; CHECK-DAG: %T3 = type { i8 }
; CHECK-DAG: %T4 = type { i8 }
; CHECK-DAG: %T5 = type { i8 }
; CHECK-DAG: %T6 = type { i8 }
; CHECK-DAG: %T7 = type { i8 }
; CHECK-DAG: %T8 = type { i8 }
%T1 = type { i8 }
%T2 = type { i8 }
@ -15,9 +16,12 @@
%T5 = type { i8 }
%T6 = type { i8 }
%T7 = type { i8 }
%T8 = type { i8 }
@g = external global %T1
@g.ifunc = ifunc %T8 (), ptr @f
define %T2 @f(ptr %p) {
alloca %T3
getelementptr %T4, ptr %p, i64 1

View File

@ -11,6 +11,9 @@
@fptr2 = external global ptr () addrspace(1)*
@fptr3 = external global ptr () addrspace(1)* addrspace(2)*
; CHECK: @ifunc = ifunc void (), ptr @f
@ifunc = ifunc void (), ptr @f
; CHECK: define ptr @f(ptr %a) {
; CHECK: %b = bitcast ptr %a to ptr
; CHECK: ret ptr %b

View File

@ -19,6 +19,9 @@
; CHECK: @ga2 = alias i19, ptr @g2
@ga2 = alias i19, i19* bitcast (i18* @g2 to i19*)
; CHECK: @gi = ifunc i20 (), ptr @f
@gi = ifunc i20 (), i20 ()* ()* bitcast (void (i32*)* @f to i20 ()* ()*)
define void @f(i32* %p) {
; CHECK-LABEL: define {{[^@]+}}@f
; CHECK-SAME: (ptr [[P:%.*]]) {