IR: compare type attributes deeply when looking into functions.

FunctionComparator attempts to produce a stable comparison of two Function
instances by looking at all available properties. Since ByVal attributes now
contain a Type pointer, they are not trivially ordered and FunctionComparator
should use its own Type comparison logic to sort them.

llvm-svn: 364523
This commit is contained in:
Tim Northover 2019-06-27 11:44:45 +00:00
parent cfe9d0fb2b
commit 22c96a966b
2 changed files with 50 additions and 0 deletions

View File

@ -113,6 +113,19 @@ int FunctionComparator::cmpAttrs(const AttributeList L,
for (; LI != LE && RI != RE; ++LI, ++RI) {
Attribute LA = *LI;
Attribute RA = *RI;
if (LA.isTypeAttribute() && RA.isTypeAttribute()) {
if (LA.getKindAsEnum() != RA.getKindAsEnum())
return cmpNumbers(LA.getKindAsEnum(), RA.getKindAsEnum());
Type *TyL = LA.getValueAsType();
Type *TyR = RA.getValueAsType();
if (TyL && TyR)
return cmpTypes(TyL, TyR);
// Two pointers, at least one null, so the comparison result is
// independent of the value of a real pointer.
return cmpNumbers((uint64_t)TyL, (uint64_t)TyR);
}
if (LA < RA)
return -1;
if (RA < LA)

View File

@ -0,0 +1,37 @@
; RUN: opt -S -mergefunc %s | FileCheck %s
@i = global i32 0
@f = global float 0.0
define internal void @foo() {
; CHECK: define internal void @foo()
call void @callee_i32(i32* byval(i32) @i)
ret void
}
define internal void @bar() {
; CHECK: define internal void @bar()
call void @callee_float(float* byval(float) @f)
ret void
}
define internal void @baz() {
; CHECK-NOT: define{{.*}}@bar
call void @callee_float(float* byval(float) @f)
ret void
}
define void @user() {
; CHECK-LABEL: define void @user
; CHECK: call void @foo()
; CHECK: call void @bar()
; CHECK: call void @bar()
call void @foo()
call void @bar()
call void @baz()
ret void
}
declare void @callee_i32(i32* byval(i32))
declare void @callee_float(float* byval(float))