[llvm] 41e06ae - [CallPromotionUtils] Add missing promotion legality check to tryPromoteCall.

Hiroshi Yamauchi via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 28 09:35:37 PST 2020


Author: Hiroshi Yamauchi
Date: 2020-02-28T09:35:09-08:00
New Revision: 41e06ae7ba911661962c9f190ae88d1f29c076da

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

LOG: [CallPromotionUtils] Add missing promotion legality check to tryPromoteCall.

Summary: This fixes the crash that led to the revert of D69591.

Reviewers: davidxl

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
index 09cd537e3cab..19e7efe328fc 100644
--- a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -511,6 +511,9 @@ bool llvm::tryPromoteCall(CallSite &CS) {
   if (!DirectCallee)
     return false; // No function pointer found.
 
+  if (!isLegalToPromote(CS, DirectCallee))
+    return false;
+
   // Success.
   promoteCall(CS, DirectCallee);
   return true;

diff  --git a/llvm/unittests/Transforms/Utils/CallPromotionUtilsTest.cpp b/llvm/unittests/Transforms/Utils/CallPromotionUtilsTest.cpp
index add2934d1d39..18db4623f368 100644
--- a/llvm/unittests/Transforms/Utils/CallPromotionUtilsTest.cpp
+++ b/llvm/unittests/Transforms/Utils/CallPromotionUtilsTest.cpp
@@ -330,3 +330,50 @@ declare i32 @_ZN1A3vf2Ev(%struct.A* %this)
   F = dyn_cast<Function>(GV);
   EXPECT_EQ(F, CS2.getCalledFunction());
 }
+
+// Check that it isn't crashing due to missing promotion legality.
+TEST(CallPromotionUtilsTest, TryPromoteCall_Legality) {
+  LLVMContext C;
+  std::unique_ptr<Module> M = parseIR(C,
+                                      R"IR(
+%struct1 = type <{ i32, i64 }>
+%struct2 = type <{ i32, i64 }>
+
+%class.Impl = type <{ %class.Interface, i32, [4 x i8] }>
+%class.Interface = type { i32 (...)** }
+
+ at _ZTV4Impl = constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (%struct2 (%class.Impl*)* @_ZN4Impl3RunEv to i8*)] }
+
+define %struct1 @f() {
+entry:
+  %o = alloca %class.Impl
+  %base = getelementptr %class.Impl, %class.Impl* %o, i64 0, i32 0, i32 0
+  store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV4Impl, i64 0, inrange i32 0, i64 2) to i32 (...)**), i32 (...)*** %base
+  %f = getelementptr inbounds %class.Impl, %class.Impl* %o, i64 0, i32 1
+  store i32 3, i32* %f
+  %base.i = getelementptr inbounds %class.Impl, %class.Impl* %o, i64 0, i32 0
+  %c = bitcast %class.Interface* %base.i to %struct1 (%class.Interface*)***
+  %vtable.i = load %struct1 (%class.Interface*)**, %struct1 (%class.Interface*)*** %c
+  %fp = load %struct1 (%class.Interface*)*, %struct1 (%class.Interface*)** %vtable.i
+  %rv = call %struct1 %fp(%class.Interface* nonnull %base.i)
+  ret %struct1 %rv
+}
+
+declare %struct2 @_ZN4Impl3RunEv(%class.Impl* %this)
+)IR");
+
+  auto *GV = M->getNamedValue("f");
+  ASSERT_TRUE(GV);
+  auto *F = dyn_cast<Function>(GV);
+  ASSERT_TRUE(F);
+  Instruction *Inst = &F->front().front();
+  auto *AI = dyn_cast<AllocaInst>(Inst);
+  ASSERT_TRUE(AI);
+  Inst = &*++F->front().rbegin();
+  auto *CI = dyn_cast<CallInst>(Inst);
+  ASSERT_TRUE(CI);
+  CallSite CS(CI);
+  ASSERT_FALSE(CS.getCalledFunction());
+  bool IsPromoted = tryPromoteCall(CS);
+  EXPECT_FALSE(IsPromoted);
+}


        


More information about the llvm-commits mailing list