summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2018-05-10 15:05:47 +0000
committerwhitequark <whitequark@whitequark.org>2018-05-10 15:05:47 +0000
commit68403564dfbcaacec89e025cc049947e6975979a (patch)
treec15ce2a53363944580189fdd1660cb26cba4e760
parentec9b6be26fbd2444eb935fe2752fd45ef46f3b11 (diff)
downloadbcm5719-llvm-68403564dfbcaacec89e025cc049947e6975979a.tar.gz
bcm5719-llvm-68403564dfbcaacec89e025cc049947e6975979a.zip
[PR37339] Fix assertion in FunctionComparator::cmpInlineAsm
Fixes bug https://bugs.llvm.org/show_bug.cgi?id=37339. InlineAsm is only uniqued if the FunctionTypes are exactly the same, while cmpTypes() for example considers all pointer types in the default address space to be the same. For this reason the end of cmpInlineAsm() can be reached. This patch replaces the unreachable assertion with a check that the function types are not identical. Differential Revision: https://reviews.llvm.org/D46495 Reviewers: jfb llvm-svn: 331990
-rw-r--r--llvm/lib/Transforms/Utils/FunctionComparator.cpp2
-rw-r--r--llvm/test/Transforms/MergeFunc/inline-asm.ll53
2 files changed, 54 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
index bddcbd86e91..75539428b68 100644
--- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -710,7 +710,7 @@ int FunctionComparator::cmpInlineAsm(const InlineAsm *L,
return Res;
if (int Res = cmpNumbers(L->getDialect(), R->getDialect()))
return Res;
- llvm_unreachable("InlineAsm blocks were not uniqued.");
+ assert(L->getFunctionType() != R->getFunctionType());
return 0;
}
diff --git a/llvm/test/Transforms/MergeFunc/inline-asm.ll b/llvm/test/Transforms/MergeFunc/inline-asm.ll
new file mode 100644
index 00000000000..370d3c56f06
--- /dev/null
+++ b/llvm/test/Transforms/MergeFunc/inline-asm.ll
@@ -0,0 +1,53 @@
+; RUN: opt -mergefunc -S < %s | FileCheck %s
+
+; CHECK-LABEL: @int_ptr_arg_different
+; CHECK-NEXT: call void asm
+
+; CHECK-LABEL: @int_ptr_arg_same
+; CHECK-NEXT: %2 = bitcast i32* %0 to float*
+; CHECK-NEXT: tail call void @float_ptr_arg_same(float* %2)
+
+; CHECK-LABEL: @int_ptr_null
+; CHECK-NEXT: tail call void @float_ptr_null()
+
+; Used to satisfy minimum size limit
+declare void @stuff()
+
+; Can be merged
+define void @float_ptr_null() {
+ call void asm "nop", "r"(float* null)
+ call void @stuff()
+ ret void
+}
+
+define void @int_ptr_null() {
+ call void asm "nop", "r"(i32* null)
+ call void @stuff()
+ ret void
+}
+
+; Can be merged (uses same argument differing by pointer type)
+define void @float_ptr_arg_same(float*) {
+ call void asm "nop", "r"(float* %0)
+ call void @stuff()
+ ret void
+}
+
+define void @int_ptr_arg_same(i32*) {
+ call void asm "nop", "r"(i32* %0)
+ call void @stuff()
+ ret void
+}
+
+; Can not be merged (uses different arguments)
+define void @float_ptr_arg_different(float*, float*) {
+ call void asm "nop", "r"(float* %0)
+ call void @stuff()
+ ret void
+}
+
+define void @int_ptr_arg_different(i32*, i32*) {
+ call void asm "nop", "r"(i32* %1)
+ call void @stuff()
+ ret void
+}
OpenPOWER on IntegriCloud