llvm.org GIT mirror llvm / 152c656
[ICP] Do not attempt type matching for variable length arguments. Summary: When performing indirect call promotion, current implementation inspects "all" parameters of the callsite and attemps to match with the formal argument type of the callee function. However, it is not possible to find the type for variable length arguments, and the compiler crashes when it attemps to match the type for variable lenght argument. It seems that the bug is introduced with D40658. Prior to that, the type matching is performed only for the parameters whose ID is less than callee->getFunctionNumParams(). The attached test case will crash without the patch. Reviewers: mssimpso, davidxl, davide Reviewed By: mssimpso Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D46026 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330844 91177308-0d34-0410-b5e6-96231b3b80d8 Taewook Oh 1 year, 4 months ago
2 changed file(s) with 35 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
388388 // Inspect the arguments of the call site. If an argument's type doesn't
389389 // match the corresponding formal argument's type in the callee, bitcast it
390390 // to the correct type.
391 for (Use &U : CS.args()) {
392 unsigned ArgNo = CS.getArgumentNo(&U);
393 Type *FormalTy = Callee->getFunctionType()->getParamType(ArgNo);
394 Type *ActualTy = U.get()->getType();
391 auto CalleeType = Callee->getFunctionType();
392 auto CalleeParamNum = CalleeType->getNumParams();
393 for (unsigned ArgNo = 0; ArgNo < CalleeParamNum; ++ArgNo) {
394 auto *Arg = CS.getArgument(ArgNo);
395 Type *FormalTy = CalleeType->getParamType(ArgNo);
396 Type *ActualTy = Arg->getType();
395397 if (FormalTy != ActualTy) {
396 auto *Cast = CastInst::Create(Instruction::BitCast, U.get(), FormalTy, "",
398 auto *Cast = CastInst::Create(Instruction::BitCast, Arg, FormalTy, "",
397399 CS.getInstruction());
398400 CS.setArgument(ArgNo, Cast);
399401 }
0 ; RUN: opt < %s -pgo-icall-prom -S | FileCheck %s
1
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 %struct.A = type { i8 }
6 %struct.B = type { i8 }
7 @foo = common global i32 (%struct.A*, ...)* null, align 8
8
9 define i32 @func1(%struct.B* %x, ...) {
10 entry:
11 ret i32 0
12 }
13
14 define i32 @bar(%struct.A* %x) {
15 entry:
16 %tmp = load i32 (%struct.A*, ...)*, i32 (%struct.A*, ...)** @foo, align 8
17 ; CHECK: [[CMP:%[0-9]+]] = icmp eq i32 (%struct.A*, ...)* %tmp, bitcast (i32 (%struct.B*, ...)* @func1 to i32 (%struct.A*, ...)*)
18 ; CHECK: br i1 [[CMP]], label %if.true.direct_targ, label %if.false.orig_indirect, !prof [[BRANCH_WEIGHT:![0-9]+]]
19 ; CHECK: if.true.direct_targ:
20 ; CHECK: [[DIRCALL_RET:%[0-9]+]] = call i32 (%struct.B*, ...) @func1
21 ; CHECK: br label %if.end.icp
22 %call = call i32 (%struct.A*, ...) %tmp(%struct.A* %x, i32 0), !prof !1
23 ret i32 %call
24 }
25
26 ; CHECK: [[BRANCH_WEIGHT]] = !{!"branch_weights", i32 1500, i32 100}
27 !1 = !{!"VP", i32 0, i64 1600, i64 -2545542355363006406, i64 1500}