leonardchan updated this revision to Diff 461686.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134300/new/

https://reviews.llvm.org/D134300

Files:
  llvm/lib/Transforms/Utils/FunctionComparator.cpp
  llvm/test/Transforms/MergeFunc/dso_local_equivalent_merged.ll
  llvm/test/Transforms/MergeFunc/dso_local_equivalent_unmerged.ll

Index: llvm/test/Transforms/MergeFunc/dso_local_equivalent_unmerged.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/MergeFunc/dso_local_equivalent_unmerged.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+;; Check the cases involving dso_local_equivalent where we do not expect functions to be merged.
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+
+@x = constant { i32 ()*, i32 ()* } { i32 ()* @a, i32 ()* @b }
+; CHECK: { i32 ()* @a, i32 ()* @b }
+
+@x2 = constant { i32 ()*, i32 ()* } { i32 ()* @c, i32 ()* @d }
+; CHECK: { i32 ()* @c, i32 ()* @d }
+
+;; func1 and func2 are different functions.
+declare i32 @func1()
+define i32 @func2() {
+; CHECK-LABEL: @func2(
+; CHECK-NEXT:    ret i32 0
+;
+  ret i32 0
+}
+
+define internal i32 @a() unnamed_addr {
+; CHECK-LABEL: @a(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 dso_local_equivalent @func1()
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %1 = call i32 dso_local_equivalent @func1()
+  ret i32 %1
+}
+
+define internal i32 @b() unnamed_addr {
+; CHECK-LABEL: @b(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 dso_local_equivalent @func2()
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %1 = call i32 dso_local_equivalent @func2()
+  ret i32 %1
+}
+
+;; func3 and func4 have the same body and signature but do not have merged
+;; callers because they are different functions.
+define i32 @func3() {
+; CHECK-LABEL: @func3(
+; CHECK-NEXT:    ret i32 0
+;
+  ret i32 0
+}
+define i32 @func4() {
+; CHECK-LABEL: @func4(
+; CHECK-NEXT:    ret i32 0
+;
+  ret i32 0
+}
+
+define internal i32 @c() unnamed_addr {
+; CHECK-LABEL: @c(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 dso_local_equivalent @func3()
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %1 = call i32 dso_local_equivalent @func3()
+  ret i32 %1
+}
+
+define internal i32 @d() unnamed_addr {
+; CHECK-LABEL: @d(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 dso_local_equivalent @func4()
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %1 = call i32 dso_local_equivalent @func4()
+  ret i32 %1
+}
Index: llvm/test/Transforms/MergeFunc/dso_local_equivalent_merged.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/MergeFunc/dso_local_equivalent_merged.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+;; Check the cases involving dso_local_equivalent where we do expect functions to be merged.
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+
+; CHECK-NOT: @b
+
+@x = constant { i32 ()*, i32 ()* } { i32 ()* @a, i32 ()* @b }
+; CHECK: { i32 ()* @a, i32 ()* @a }
+
+define i32 @func() {
+; CHECK-LABEL: @func(
+; CHECK-NEXT:    ret i32 0
+;
+  ret i32 0
+}
+
+define internal i32 @a() unnamed_addr {
+; CHECK-LABEL: @a(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 dso_local_equivalent @func()
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %1 = call i32 dso_local_equivalent @func()
+  ret i32 %1
+}
+
+define internal i32 @b() unnamed_addr {
+  %1 = call i32 dso_local_equivalent @func()
+  ret i32 %1
+}
Index: llvm/lib/Transforms/Utils/FunctionComparator.cpp
===================================================================
--- llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -402,6 +402,15 @@
       return cmpValues(LBA->getBasicBlock(), RBA->getBasicBlock());
     }
   }
+  case Value::DSOLocalEquivalentVal: {
+    // dso_local_equivalent is functionally equivalent to whatever it points to.
+    // This means the behavior of the IR should be the exact same as if the
+    // function was referenced directly rather than through a
+    // dso_local_equivalent.
+    const auto *LEquiv = cast<DSOLocalEquivalent>(L);
+    const auto *REquiv = cast<DSOLocalEquivalent>(R);
+    return cmpGlobalValues(LEquiv->getGlobalValue(), REquiv->getGlobalValue());
+  }
   default: // Unknown constant, abort.
     LLVM_DEBUG(dbgs() << "Looking at valueID " << L->getValueID() << "\n");
     llvm_unreachable("Constant ValueID not recognized.");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to