llvm.org GIT mirror llvm / 2dc1928
Create PHI node for the return value only when the return value has uses. Summary: Currently, a phi node is created in the normal destination to unify the return values from promoted calls and the original indirect call. This patch makes this phi node to be created only when the return value has uses. This patch is necessary to generate valid code, as compiler crashes with the attached test case without this patch. Without this patch, an illegal phi node that has no incoming value from `entry`/`catch` is created in `cleanup` block. I think existing implementation is good as far as there is at least one use of the original indirect call. `insertCallRetPHI` creates a new phi node in the normal destination block only when the original indirect call dominates its use and the normal destination block. Otherwise, `fixupPHINodeForNormalDest` will handle the unification of return values naturally without creating a new phi node. However, if there's no use, `insertCallRetPHI` still creates a new phi node even when the original indirect call does not dominate the normal destination block, because `getCallRetPHINode` returns false. Reviewers: xur, davidxl, danielcdh Reviewed By: xur Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D37176 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311906 91177308-0d34-0410-b5e6-96231b3b80d8 Taewook Oh 2 years ago
3 changed file(s) with 74 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
507507 if (Inst->getType()->isVoidTy())
508508 return;
509509
510 if (Inst->use_empty())
511 return;
512
510513 BasicBlock *RetValBB = CallResult->getParent();
511514
512515 BasicBlock *PHIBB;
1111 declare void @_ZN1DC2Ev(%struct.D*);
1212 declare %struct.Derived* @_ZN1D4funcEv(%struct.D*);
1313
14 define i32 @bar() {
14 define %struct.Base* @bar() {
1515 entry:
1616 %call = call noalias i8* @_Znwm(i64 8)
1717 %tmp = bitcast i8* %call to %struct.D*
3535 ; ICALL-PROM:if.end.icp:
3636 ; ICALL-PROM: [[PHI_RET:%[0-9]+]] = phi %struct.Base* [ %call1, %if.false.orig_indirect ], [ [[DIRCALL_RET_CAST]], %if.true.direct_targ ]
3737 %call1 = call %struct.Base* %tmp3(%struct.B* %tmp1), !prof !1
38 ret i32 0
38 ret %struct.Base* %call1
3939 }
4040
4141 !1 = !{!"VP", i32 0, i64 12345, i64 -3913987384944532146, i64 12345}
0 ; RUN: opt < %s -icp-lto -pgo-icall-prom -S | FileCheck %s --check-prefix=ICP
1 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 @_ZTISt9exception = external constant i8*
5 @pfptr = global i32()* null, align 8
6
7 define internal i32 @_ZL4bar1v() !PGOFuncName !0 {
8 entry:
9 ret i32 100
10 }
11
12 ; Function Attrs: uwtable
13 define i32 @_Z3fooi(i32 %x) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
14 entry:
15 %tobool = icmp eq i32 %x, 0
16 br i1 %tobool, label %if.end, label %cleanup
17
18 if.end: ; preds = %entry
19 %fptr = load i32 ()*, i32 ()** @pfptr, align 8
20 ; ICP: [[BITCAST_IC1:%[0-9]+]] = bitcast i32 ()* %fptr to i8*
21 ; ICP: [[CMP_IC1:%[0-9]+]] = icmp eq i8* [[BITCAST_IC1]], bitcast (i32 ()* @_ZL4bar1v to i8*)
22 ; ICP: br i1 [[CMP_IC1]], label %[[TRUE_LABEL_IC1:.*]], label %[[FALSE_LABEL_IC1:.*]], !prof [[BRANCH_WEIGHT:![0-9]+]]
23 ; ICP:[[TRUE_LABEL_IC1]]:
24 ; ICP: invoke i32 @_ZL4bar1v()
25 ; ICP: to label %[[DCALL_NORMAL_DEST_IC1:.*]] unwind label %lpad
26 ; ICP:[[FALSE_LABEL_IC1]]:
27 %call = invoke i32 %fptr()
28 to label %cleanup unwind label %lpad, !prof !1
29
30 ; ICP:[[DCALL_NORMAL_DEST_IC1]]:
31 ; ICP: br label %cleanup
32
33 lpad: ; preds = %if.end
34 %0 = landingpad { i8*, i32 }
35 cleanup
36 catch i8* bitcast (i8** @_ZTISt9exception to i8*)
37 %1 = extractvalue { i8*, i32 } %0, 1
38 %2 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTISt9exception to i8*))
39 %matches = icmp eq i32 %1, %2
40 br i1 %matches, label %catch, label %ehcleanup
41
42 catch: ; preds = %lpad
43 %3 = extractvalue { i8*, i32 } %0, 0
44 %4 = tail call i8* @__cxa_begin_catch(i8* %3)
45 tail call void @__cxa_end_catch()
46 br label %cleanup
47
48 cleanup: ; preds = %catch, %if.end, %entry
49 ; ICP-NOT: %[0-9]+ = phi
50 ret i32 0
51
52 ehcleanup: ; preds = %lpad
53 resume { i8*, i32 } %0
54 }
55
56 declare i32 @_Z3barv() local_unnamed_addr
57
58 declare i32 @__gxx_personality_v0(...)
59
60 ; Function Attrs: nounwind readnone
61 declare i32 @llvm.eh.typeid.for(i8*)
62
63 declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr
64
65 declare void @__cxa_end_catch() local_unnamed_addr
66
67 !0 = !{!"invoke.ll:_ZL4bar1v"}
68 !1 = !{!"VP", i32 0, i64 10000, i64 -2732222848796217051, i64 10000}