[llvm] c19d7f8 - [CallPromotion] Check for inalloca/byval mismatch

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 13 16:56:06 PDT 2021


Author: Arthur Eubanks
Date: 2021-08-13T16:52:04-07:00
New Revision: c19d7f8af0321d1b90343496ebd1c1aec3f1dc8c

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

LOG: [CallPromotion] Check for inalloca/byval mismatch

Previously we would allow promotion even if the byval/inalloca
attributes on the call and the callee didn't match.

It's ok if the byval/inalloca types aren't the same. For example, LTO
importing may rename types.

Fixes PR51397.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D107998

Added: 
    llvm/test/Transforms/PGOProfile/mismatched-byval.ll
    llvm/test/Transforms/PGOProfile/mismatched-inalloca.ll

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
index 33cb8823086e0..ebe19f1751e55 100644
--- a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -424,6 +424,21 @@ bool llvm::isLegalToPromote(const CallBase &CB, Function *Callee,
         *FailureReason = "Argument type mismatch";
       return false;
     }
+    // Make sure that the callee and call agree on byval/inalloca. The types do
+    // not have to match.
+
+    if (Callee->hasParamAttribute(I, Attribute::ByVal) !=
+        CB.getAttributes().hasParamAttr(I, Attribute::ByVal)) {
+      if (FailureReason)
+        *FailureReason = "byval mismatch";
+      return false;
+    }
+    if (Callee->hasParamAttribute(I, Attribute::InAlloca) !=
+        CB.getAttributes().hasParamAttr(I, Attribute::InAlloca)) {
+      if (FailureReason)
+        *FailureReason = "inalloca mismatch";
+      return false;
+    }
   }
   for (; I < NumArgs; I++) {
     // Vararg functions can have more arguments than parameters.
@@ -488,10 +503,11 @@ CallBase &llvm::promoteCall(CallBase &CB, Function *Callee,
       AttrBuilder ArgAttrs(CallerPAL.getParamAttrs(ArgNo));
       ArgAttrs.remove(AttributeFuncs::typeIncompatible(FormalTy));
 
-      // If byval is used, this must be a pointer type, and the byval type must
-      // match the element type. Update it if present.
+      // We may have a 
diff erent byval/inalloca type.
       if (ArgAttrs.getByValType())
         ArgAttrs.addByValAttr(Callee->getParamByValType(ArgNo));
+      if (ArgAttrs.getInAllocaType())
+        ArgAttrs.addInAllocaAttr(Callee->getParamInAllocaType(ArgNo));
 
       NewArgAttrs.push_back(AttributeSet::get(Ctx, ArgAttrs));
       AttributeChanged = true;

diff  --git a/llvm/test/Transforms/PGOProfile/mismatched-byval.ll b/llvm/test/Transforms/PGOProfile/mismatched-byval.ll
new file mode 100644
index 0000000000000..84c335c678473
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/mismatched-byval.ll
@@ -0,0 +1,22 @@
+; RUN: opt -passes=pgo-icall-prom -profile-summary-hot-count=10 -S < %s -pass-remarks-output=- | FileCheck %s
+
+; CHECK: byval mismatch
+
+define void @a(i8* %0) !prof !0 {
+  ret void
+}
+
+define void @b(void (i64*)** %v, i64* %p) !prof !1 {
+; CHECK-LABEL: @b
+; CHECK-NEXT: load
+; CHECK-NEXT: call void {{.*}}(i64* byval(i64)
+; CHECK-NEXT: ret void
+;
+  %a = load void (i64*)*, void (i64*)** %v
+  call void %a(i64* byval(i64) %p), !prof !2
+  ret void
+}
+
+!0 = !{!"function_entry_count", i64 36}
+!1 = !{!"function_entry_count", i64 1}
+!2 = !{!"VP", i32 0, i64 18, i64 12157170054180749580, i64 18}

diff  --git a/llvm/test/Transforms/PGOProfile/mismatched-inalloca.ll b/llvm/test/Transforms/PGOProfile/mismatched-inalloca.ll
new file mode 100644
index 0000000000000..5ac174cd7c733
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/mismatched-inalloca.ll
@@ -0,0 +1,21 @@
+; RUN: opt -passes=pgo-icall-prom -profile-summary-hot-count=10 -S < %s -pass-remarks-output=- | FileCheck %s
+
+; CHECK: inalloca mismatch
+
+define void @a(i8* %0) !prof !0 {
+  ret void
+}
+
+define void @b(void (i64*)** %v, i64* %p) !prof !1 {
+; CHECK-LABEL: @b
+; CHECK-NEXT: load
+; CHECK-NEXT: call void {{.*}}(i64* inalloca(i64)
+; CHECK-NEXT: ret void
+  %a = load void (i64*)*, void (i64*)** %v
+  call void %a(i64* inalloca(i64) %p), !prof !2
+  ret void
+}
+
+!0 = !{!"function_entry_count", i64 36}
+!1 = !{!"function_entry_count", i64 1}
+!2 = !{!"VP", i32 0, i64 18, i64 12157170054180749580, i64 18}


        


More information about the llvm-commits mailing list