Skip to content

Commit 6608bac

Browse files
[CGP] Consider arguments and ret values in dupRetToEnableTailCallOpts
Hint further tail call optimization opportunities when the examined returned value is either the return value of a call instruction, or a function argument. Moreover, take into account the cases in which incoming values from phi-nodes, not directly tail call instructions, may still be simplified. Fixes: #75455.
1 parent 9fbef3e commit 6608bac

File tree

4 files changed

+65
-44
lines changed

4 files changed

+65
-44
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2524,7 +2524,8 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
25242524
}
25252525

25262526
/// Look for opportunities to duplicate return instructions to the predecessor
2527-
/// to enable tail call optimizations. The case it is currently looking for is:
2527+
/// to enable tail call optimizations. The case it is currently looking for are
2528+
/// simple return of call values, function arguments, or phi nodes as follows:
25282529
/// @code
25292530
/// bb0:
25302531
/// %tmp0 = tail call i32 @f0()
@@ -2581,7 +2582,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
25812582
}
25822583

25832584
PN = dyn_cast<PHINode>(V);
2584-
if (!PN)
2585+
if (!PN && !isa<Argument>(V) && !isa<CallInst>(V))
25852586
return false;
25862587
}
25872588

@@ -2621,8 +2622,38 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
26212622
// Make sure the phi value is indeed produced by the tail call.
26222623
if (CI && CI->hasOneUse() && CI->getParent() == PredBB &&
26232624
TLI->mayBeEmittedAsTailCall(CI) &&
2624-
attributesPermitTailCall(F, CI, RetI, *TLI))
2625+
attributesPermitTailCall(F, CI, RetI, *TLI)) {
26252626
TailCallBBs.push_back(PredBB);
2627+
} else {
2628+
/// Consider the cases in which the phi value is indirectly produced by
2629+
/// the tail call, for example when encountering memset(), memmove(),
2630+
/// whose return value may have been optimized out.
2631+
/// @code
2632+
/// bb0:
2633+
/// tail call void @llvm.memset.p0.i64()
2634+
/// br label %return
2635+
/// @endcode
2636+
if (PredBB && PredBB->getSingleSuccessor() == BB)
2637+
CI = dyn_cast_or_null<CallInst>(
2638+
PredBB->getTerminator()->getPrevNonDebugInstruction(true));
2639+
2640+
// If we return void from the call site, it must be an intrinsic.
2641+
if (CI && CI->getType()->isVoidTy() && !isa<IntrinsicInst>(CI))
2642+
continue;
2643+
2644+
/// If we return a value, it must not be used. A valid case may be when
2645+
/// strcpy()'ing, where its first argument is used in the phi-node.
2646+
/// @code
2647+
/// bb0:
2648+
/// %1 = tail call ptr @strcpy()
2649+
/// br label %return
2650+
/// @endcode
2651+
if (CI && CI->use_empty() && CI->hasArgument(IncomingVal) &&
2652+
IncomingVal == CI->getArgOperand(0) &&
2653+
TLI->mayBeEmittedAsTailCall(CI) &&
2654+
attributesPermitTailCall(F, CI, RetI, *TLI))
2655+
TailCallBBs.push_back(PredBB);
2656+
}
26262657
}
26272658
} else {
26282659
SmallPtrSet<BasicBlock *, 4> VisitedBBs;

llvm/test/CodeGen/Thumb2/constant-islands-cbz.ll

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ define ptr @test(ptr returned %this, i32 %event_size, ptr %event_pointer) {
88
; CHECK-T1-NEXT: .save {r4, lr}
99
; CHECK-T1-NEXT: push {r4, lr}
1010
; CHECK-T1-NEXT: mov r4, r0
11-
; CHECK-T1-NEXT: movs r0, #0
12-
; CHECK-T1-NEXT: str r0, [r4, #4]
13-
; CHECK-T1-NEXT: str r0, [r4, #8]
14-
; CHECK-T1-NEXT: str r0, [r4, #12]
15-
; CHECK-T1-NEXT: str r0, [r4, #16]
16-
; CHECK-T1-NEXT: mov r0, r4
11+
; CHECK-T1-NEXT: movs r3, #0
12+
; CHECK-T1-NEXT: str r3, [r0, #4]
13+
; CHECK-T1-NEXT: str r3, [r0, #8]
14+
; CHECK-T1-NEXT: str r3, [r0, #12]
15+
; CHECK-T1-NEXT: str r3, [r0, #16]
1716
; CHECK-T1-NEXT: cbz r2, .LBB0_2
1817
; CHECK-T1-NEXT: @ %bb.1: @ %if.else
1918
; CHECK-T1-NEXT: bl equeue_create_inplace
@@ -28,11 +27,10 @@ define ptr @test(ptr returned %this, i32 %event_size, ptr %event_pointer) {
2827
; CHECK-T2: @ %bb.0: @ %entry
2928
; CHECK-T2-NEXT: .save {r4, lr}
3029
; CHECK-T2-NEXT: push {r4, lr}
30+
; CHECK-T2-NEXT: movs r3, #0
3131
; CHECK-T2-NEXT: mov r4, r0
32-
; CHECK-T2-NEXT: movs r0, #0
33-
; CHECK-T2-NEXT: strd r0, r0, [r4, #4]
34-
; CHECK-T2-NEXT: strd r0, r0, [r4, #12]
35-
; CHECK-T2-NEXT: mov r0, r4
32+
; CHECK-T2-NEXT: strd r3, r3, [r0, #4]
33+
; CHECK-T2-NEXT: strd r3, r3, [r0, #12]
3634
; CHECK-T2-NEXT: cbz r2, .LBB0_2
3735
; CHECK-T2-NEXT: @ %bb.1: @ %if.else
3836
; CHECK-T2-NEXT: bl equeue_create_inplace

llvm/test/CodeGen/X86/tailcall-cgp-dup.ll

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -188,18 +188,14 @@ return:
188188
define ptr @memset_tailc(ptr %ret_val, i64 %sz) {
189189
; CHECK-LABEL: memset_tailc:
190190
; CHECK: ## %bb.0: ## %entry
191-
; CHECK: pushq %rbx
192-
; CHECK: movq %rdi, %rbx
193191
; CHECK: testq %rdi, %rdi
194-
; CHECK: je LBB4_2
195-
; CHECK: ## %bb.1: ## %if.then
192+
; CHECK: je LBB4_1
193+
; CHECK: ## %bb.2: ## %if.then
196194
; CHECK: movq %rsi, %rdx
197-
; CHECK: movq %rbx, %rdi
198195
; CHECK: xorl %esi, %esi
199-
; CHECK: callq _memset
200-
; CHECK: LBB4_2: ## %return
201-
; CHECK: movq %rbx, %rax
202-
; CHECK: popq %rbx
196+
; CHECK: jmp _memset ## TAILCALL
197+
; CHECK: LBB4_1: ## %return
198+
; CHECK: movq %rdi, %rax
203199
; CHECK: retq
204200
entry:
205201
%cmp = icmp eq ptr %ret_val, null
@@ -216,21 +212,15 @@ return:
216212
define ptr @memcpy_tailc(ptr %ret_val, i64 %sz, ptr %src) {
217213
; CHECK-LABEL: memcpy_tailc:
218214
; CHECK: ## %bb.0: ## %entry
219-
; CHECK: pushq %rbx
220215
; CHECK: testq %rsi, %rsi
221216
; CHECK: je LBB5_1
222217
; CHECK: ## %bb.2: ## %if.then
223218
; CHECK: movq %rsi, %rax
224-
; CHECK: movq %rdi, %rbx
225219
; CHECK: movq %rdx, %rsi
226220
; CHECK: movq %rax, %rdx
227-
; CHECK: callq _memcpy
228-
; CHECK: jmp LBB5_3
229-
; CHECK: LBB5_1:
230-
; CHECK: movq %rdx, %rbx
231-
; CHECK: LBB5_3: ## %return
232-
; CHECK: movq %rbx, %rax
233-
; CHECK: popq %rbx
221+
; CHECK: jmp _memcpy ## TAILCALL
222+
; CHECK: LBB5_1: ## %return
223+
; CHECK: movq %rdx, %rax
234224
; CHECK: retq
235225
entry:
236226
%cmp = icmp eq i64 %sz, 0
@@ -256,13 +246,15 @@ define ptr @strcpy_tailc(i64 %0, ptr %src) {
256246
; CHECK: movl $20, %edi
257247
; CHECK: callq _malloc
258248
; CHECK: testq %r14, %r14
259-
; CHECK: je LBB6_2
260-
; CHECK: ## %bb.1: ## %if.then
249+
; CHECK: je LBB6_1
250+
; CHECK: ## %bb.2: ## %if.then
261251
; CHECK: movq %rax, %rdi
262252
; CHECK: movq %rbx, %rsi
263-
; CHECK: movq %rax, %rbx
264-
; CHECK: callq _strcpy
265-
; CHECK: LBB6_2: ## %return
253+
; CHECK: addq $8, %rsp
254+
; CHECK: popq %rbx
255+
; CHECK: popq %r14
256+
; CHECK: jmp _strcpy ## TAILCALL
257+
; CHECK: LBB6_1: ## %return
266258
; CHECK: movq %rbx, %rax
267259
; CHECK: addq $8, %rsp
268260
; CHECK: popq %rbx

llvm/test/DebugInfo/X86/live-debug-values-expr-conflict.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@
2424
; one in the block two, and none in block three.
2525
; CHECK: ![[BAZVAR:[0-9]+]] = !DILocalVariable(name: "baz",
2626
; CHECK-LABEL: bb.0.entry:
27-
; CHECK: DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
27+
; CHECK: DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
2828
; CHECK-SAME: !DIExpression()
2929
; CHECK-LABEL: bb.1.if.then:
30-
; CHECK-LABEL: bb.2.if.else:
31-
; CHECK: DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
30+
; CHECK-LABEL: bb.3.if.else:
31+
; CHECK: DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
3232
; CHECK-SAME: !DIExpression()
33-
; CHECK: DBG_VALUE_LIST ![[BAZVAR]],
34-
; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 1, DW_OP_stack_value)
35-
; CHECK-SAME: {{[0-9a-zA-Z$%_]*}}
36-
; CHECK-LABEL: bb.3.if.end:
33+
; CHECK: DBG_VALUE_LIST ![[BAZVAR]],
34+
; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 1, DW_OP_stack_value)
35+
; CHECK-SAME: {{[0-9a-zA-Z$%_]*}}
36+
; CHECK-LABEL: bb.2.if.then:
3737
; CHECK-NOT: DBG_VALUE
38-
; CHECK-NOT: DBG_VALUE_LIST
38+
; CHECK-NOT: DBG_VALUE_LIST
3939

4040
declare void @escape1(i32)
4141
declare void @escape2(i32)

0 commit comments

Comments
 (0)