[llvm] 049993e - [FunctionComparator] Differentiate instructions passing different MDStrings (#69543)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 19 14:00:00 PDT 2023


Author: Nuri Amari
Date: 2023-10-19T13:59:57-07:00
New Revision: 049993eae6bef539ac4bca7ddeede78282e496d9

URL: https://github.com/llvm/llvm-project/commit/049993eae6bef539ac4bca7ddeede78282e496d9
DIFF: https://github.com/llvm/llvm-project/commit/049993eae6bef539ac4bca7ddeede78282e496d9.diff

LOG: [FunctionComparator] Differentiate instructions passing different MDStrings (#69543)

Prior to this patch, differing metadata operands to two otherwise
identical instructions was not enough to consider the instructions
different in the eyes of the function comparator. This breaks LLVM
virtual function elimination, among other features.

In this patch, we handle the case where two associated operands are
MDStrings of different value. This patch does not differentiate more
complex metadata operands.

---------

Co-authored-by: Nuri Amari <nuriamari at fb.com>

Added: 
    llvm/test/Transforms/MergeFunc/mergefunc-preserve-vfe-intrinsics.ll

Modified: 
    llvm/lib/Transforms/Utils/FunctionComparator.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
index b1d74f67377e27f..79ca99d1566ce25 100644
--- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -160,10 +160,23 @@ int FunctionComparator::cmpAttrs(const AttributeList L,
 int FunctionComparator::cmpMetadata(const Metadata *L,
                                     const Metadata *R) const {
   // TODO: the following routine coerce the metadata contents into constants
-  // before comparison.
+  // or MDStrings before comparison.
   // It ignores any other cases, so that the metadata nodes are considered
   // equal even though this is not correct.
   // We should structurally compare the metadata nodes to be perfect here.
+
+  auto *MDStringL = dyn_cast<MDString>(L);
+  auto *MDStringR = dyn_cast<MDString>(R);
+  if (MDStringL && MDStringR) {
+    if (MDStringL == MDStringR)
+      return 0;
+    return MDStringL->getString().compare(MDStringR->getString());
+  }
+  if (MDStringR)
+    return -1;
+  if (MDStringL)
+    return 1;
+
   auto *CL = dyn_cast<ConstantAsMetadata>(L);
   auto *CR = dyn_cast<ConstantAsMetadata>(R);
   if (CL == CR)
@@ -820,6 +833,21 @@ int FunctionComparator::cmpValues(const Value *L, const Value *R) const {
   if (ConstR)
     return -1;
 
+  const MetadataAsValue *MetadataValueL = dyn_cast<MetadataAsValue>(L);
+  const MetadataAsValue *MetadataValueR = dyn_cast<MetadataAsValue>(R);
+  if (MetadataValueL && MetadataValueR) {
+    if (MetadataValueL == MetadataValueR)
+      return 0;
+
+    return cmpMetadata(MetadataValueL->getMetadata(),
+                       MetadataValueR->getMetadata());
+  }
+
+  if (MetadataValueL)
+    return 1;
+  if (MetadataValueR)
+    return -1;
+
   const InlineAsm *InlineAsmL = dyn_cast<InlineAsm>(L);
   const InlineAsm *InlineAsmR = dyn_cast<InlineAsm>(R);
 

diff  --git a/llvm/test/Transforms/MergeFunc/mergefunc-preserve-vfe-intrinsics.ll b/llvm/test/Transforms/MergeFunc/mergefunc-preserve-vfe-intrinsics.ll
new file mode 100644
index 000000000000000..1c29aec8d8f28d1
--- /dev/null
+++ b/llvm/test/Transforms/MergeFunc/mergefunc-preserve-vfe-intrinsics.ll
@@ -0,0 +1,44 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -passes=mergefunc -S %s | FileCheck %s
+
+; This test contains three identical functions, aside from the metadata
+; they pass to a function call. This test verifies that the function merger
+; pass is able to merge the two functions that are truly identical,
+; but the third that passes 
diff erent metadata is preserved
+
+declare { ptr, i1 } @llvm.type.checked.load(ptr, i32, metadata)
+
+define i1 @merge_candidate_a(ptr %ptr, i32 %offset) {
+; CHECK-LABEL: define i1 @merge_candidate_a(
+; CHECK-SAME: ptr [[PTR:%.*]], i32 [[OFFSET:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = call { ptr, i1 } @llvm.type.checked.load(ptr [[PTR]], i32 [[OFFSET]], metadata !"common_metadata")
+; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = call { ptr, i1 } @llvm.type.checked.load(ptr %ptr, i32 %offset, metadata !"common_metadata")
+  %2 = extractvalue { ptr, i1 } %1, 1
+  ret i1 %2
+}
+
+define i1 @merge_candidate_c(ptr %ptr, i32 %offset) {
+; CHECK-LABEL: define i1 @merge_candidate_c(
+; CHECK-SAME: ptr [[PTR:%.*]], i32 [[OFFSET:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = call { ptr, i1 } @llvm.type.checked.load(ptr [[PTR]], i32 [[OFFSET]], metadata !"
diff erent_metadata")
+; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i1 } [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = call { ptr, i1 } @llvm.type.checked.load(ptr %ptr, i32 %offset, metadata !"
diff erent_metadata")
+  %2 = extractvalue { ptr, i1 } %1, 1
+  ret i1 %2
+}
+
+define i1 @merge_candidate_b(ptr %ptr, i32 %offset) {
+; CHECK-LABEL: define i1 @merge_candidate_b(
+; CHECK-SAME: ptr [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
+; CHECK-NEXT:    [[TMP3:%.*]] = tail call i1 @merge_candidate_a(ptr [[TMP0]], i32 [[TMP1]])
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %1 = call { ptr, i1 } @llvm.type.checked.load(ptr %ptr, i32 %offset, metadata !"common_metadata")
+  %2 = extractvalue { ptr, i1 } %1, 1
+  ret i1 %2
+}


        


More information about the llvm-commits mailing list