mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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
This commit is contained in:
parent
0ac59590bb
commit
945c948972
@ -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;
|
||||
|
@ -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 (...)** }
|
||||
|
||||
@_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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user