leonardchan created this revision.
leonardchan added a reviewer: phosek.
leonardchan added a project: LLVM.
Herald added subscribers: abrachet, hiraditya.
Herald added a project: All.
leonardchan requested review of this revision.
Herald added subscribers: cfe-commits, pcwang-thead.
Herald added a project: clang.

This addresses https://github.com/llvm/llvm-project/issues/51066.

Prior to this, dso_local_equivalent would lead to an llvm_unreachable in a 
switch in the FunctionComparator. This adds a conservative case in that switch 
that just compares the underlying functions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134300

Files:
  clang/test/CodeGenCXX/pr51066.cpp
  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,45 @@
+;; Check the cases involving dso_local_equivalent where we do not expect functions to be merged.
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+
+;; func1 and func2 are different functions.
+declare i32 @func1()
+define i32 @func2() {
+  ret i32 0
+}
+
+; CHECK-LABEL: @call1
+; CHECK: call i32 dso_local_equivalent @func1()
+define i32 @call1() {
+  %1 = call i32 dso_local_equivalent @func1()
+  ret i32 %1
+}
+
+; CHECK-LABEL: @call2
+; CHECK: call i32 dso_local_equivalent @func2()
+define i32 @call2() {
+  %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() {
+  ret i32 0
+}
+define i32 @func4() {
+  ret i32 0
+}
+
+; CHECK-LABEL: @call3
+; CHECK: call i32 dso_local_equivalent @func3()
+define i32 @call3() {
+  %1 = call i32 dso_local_equivalent @func3()
+  ret i32 %1
+}
+
+; CHECK-LABEL: @call4
+; CHECK: call i32 dso_local_equivalent @func4()
+define i32 @call4() {
+  %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,18 @@
+;; Check the cases involving dso_local_equivalent where we do expect functions to be merged.
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+
+declare i32 @func()
+
+; CHECK-LABEL: @call1
+; CHECK: call i32 dso_local_equivalent @func()
+define i32 @call1() {
+  %1 = call i32 dso_local_equivalent @func()
+  ret i32 %1
+}
+
+; CHECK-LABEL: @call2
+; CHECK: call i32 dso_local_equivalent @func()
+define i32 @call2() {
+  %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.");
Index: clang/test/CodeGenCXX/pr51066.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/pr51066.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-fuchsia -emit-obj -massembler-fatal-warnings --mrelax-relocations -disable-free -disable-llvm-verifier -discard-value-names -main-file-name zircon_platform_buffer.cc -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fno-rounding-math -mconstructor-aliases -target-cpu x86-64-v2 -mllvm -x86-branches-within-32B-boundaries -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb -mllvm -crash-diagnostics-dir=clang-crashreports -ffunction-sections -fdata-sections -fcoverage-compilation-dir=. -sys-header-deps -D TOOLCHAIN_VERSION=dO8igrHyLDfgq8txd8Qx0mI9oJqFLswAMLcIBKLF6TYC -D _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D NDEBUG=1 -D _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D MAGMA_DEBUG_INTERNAL_USE_ONLY=0 -D MAGMA_ENABLE_TRACING -O3 -Wall -Wextra -Wnewline-eof -Wconversion -Wimplicit-fallthrough -Wno-unused-parameter -Wno-sign-conversion -Wno-c99-designator -Werror -Wno-error=deprecated-declarations -Wthread-safety -Wno-deprecated-copy -Wno-suggest-override -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=. -ferror-limit 19 -fvisibility=hidden -fvisibility-inlines-hidden -fsanitize=safe-stack -stack-protector 2 -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-legacy-pass-manager -fcolor-diagnostics -vectorize-loops -vectorize-slp -debug-info-kind=constructor -fmerge-functions -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ %s -o /dev/null
+// PR51066 - Just ensure this doesn't crash.
+
+class a {
+ public:
+  virtual int f();
+  virtual int g();
+  static a* x();
+  static a* y();
+};
+class b : public a {
+ public:
+  int f() override;
+};
+class c {
+ public:
+  static int z();
+};
+int c::z() { return a::x()->g(); }
+a* a::x() { return y(); }
+a* a::y() { return new b(); }
+int b::f() { return 0; }
+int s() { return a::x()->f(); }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to