diff --git a/lib/Transforms/Utils/FunctionComparator.cpp b/lib/Transforms/Utils/FunctionComparator.cpp index dfab9369c7b..f25c4e5d6e9 100644 --- a/lib/Transforms/Utils/FunctionComparator.cpp +++ b/lib/Transforms/Utils/FunctionComparator.cpp @@ -124,12 +124,17 @@ int FunctionComparator::cmpAttrs(const AttributeList L, Type *TyL = LA.getValueAsType(); Type *TyR = RA.getValueAsType(); - if (TyL && TyR) - return cmpTypes(TyL, TyR); + if (TyL && TyR) { + if (int Res = cmpTypes(TyL, TyR)) + return Res; + continue; + } // 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 (int Res = cmpNumbers((uint64_t)TyL, (uint64_t)TyR)) + return Res; + continue; } if (LA < RA) return -1; diff --git a/test/Transforms/MergeFunc/mismatching-attr-crash.ll b/test/Transforms/MergeFunc/mismatching-attr-crash.ll new file mode 100644 index 00000000000..e3f81c5776f --- /dev/null +++ b/test/Transforms/MergeFunc/mismatching-attr-crash.ll @@ -0,0 +1,21 @@ +; RUN: opt -S -mergefunc %s | FileCheck %s + +; CHECK-LABEL: define void @foo +; CHECK: call void %bc +define void @foo(i8* byval %a0, i8* swiftself %a4) { +entry: + %bc = bitcast i8* %a0 to void (i8*, i8*)* + call void %bc(i8* byval %a0, i8* swiftself %a4) + ret void +} + +; CHECK-LABEL: define void @bar +; CHECK: call void %bc +define void @bar(i8* byval(i8) %a0, i8** swifterror %a4) { +entry: + %bc = bitcast i8* %a0 to void (i8*, i8**)* + call void %bc(i8* byval(i8) %a0, i8** swifterror %a4) + ret void +} + +