Skip to content

Commit

Permalink
[CGP] Permit tail call optimization on undefined return value
Browse files Browse the repository at this point in the history
We may freely allow tail call optzs on undef values as well.

Fixes: #82387.
  • Loading branch information
antoniofrighetto committed Feb 22, 2024
1 parent fde344a commit 25e7e8d
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 17 deletions.
5 changes: 3 additions & 2 deletions llvm/lib/CodeGen/CodeGenPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2686,8 +2686,9 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
attributesPermitTailCall(F, CI, RetI, *TLI)) {
// Either we return void or the return value must be the first
// argument of a known intrinsic or library function.
if (!V || (isIntrinsicOrLFToBeTailCalled(TLInfo, CI) &&
V == CI->getArgOperand(0))) {
if (!V || isa<UndefValue>(V) ||
(isIntrinsicOrLFToBeTailCalled(TLInfo, CI) &&
V == CI->getArgOperand(0))) {
TailCallBBs.push_back(Pred);
}
}
Expand Down
6 changes: 1 addition & 5 deletions llvm/test/CodeGen/AArch64/addsub.ll
Original file line number Diff line number Diff line change
Expand Up @@ -662,17 +662,13 @@ define dso_local i32 @_extract_crng_crng() {
; CHECK-NEXT: cmn x8, #1272
; CHECK-NEXT: b.pl .LBB36_3
; CHECK-NEXT: .LBB36_2: // %if.then
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: adrp x8, primary_crng
; CHECK-NEXT: ldr w8, [x8, :lo12:primary_crng]
; CHECK-NEXT: cmp w8, #0
; CHECK-NEXT: adrp x8, input_pool
; CHECK-NEXT: add x8, x8, :lo12:input_pool
; CHECK-NEXT: csel x0, xzr, x8, eq
; CHECK-NEXT: bl crng_reseed
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: b crng_reseed
; CHECK-NEXT: .LBB36_3: // %if.end
; CHECK-NEXT: ret
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ declare dso_local i32 @g(...) local_unnamed_addr
declare dso_local i32 @i(...) local_unnamed_addr

; CHECK-LABEL: <test2>:
; CHECK: bl {{.*}} <test2+0x18>
; CHECK: b {{.*}} <test2+0x1c>
; CHECK-LABEL: <$d.5>:
; CHECK-LABEL: <$x.6>:
; CHECK-NEXT: b {{.*}} <test2+0x18>
Expand Down
12 changes: 4 additions & 8 deletions llvm/test/CodeGen/RISCV/pr51206.ll
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,12 @@ define signext i32 @wobble() nounwind {
; CHECK-NEXT: lui a2, %hi(global.3)
; CHECK-NEXT: li a3, 5
; CHECK-NEXT: sw a1, %lo(global.3)(a2)
; CHECK-NEXT: bltu a0, a3, .LBB0_2
; CHECK-NEXT: # %bb.1: # %bb10
; CHECK-NEXT: addi sp, sp, -16
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT: call quux
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-NEXT: .LBB0_2: # %bb12
; CHECK-NEXT: bgeu a0, a3, .LBB0_2
; CHECK-NEXT: # %bb.1: # %bb12
; CHECK-NEXT: li a0, 0
; CHECK-NEXT: ret
; CHECK-NEXT: .LBB0_2: # %bb10
; CHECK-NEXT: tail quux
bb:
%tmp = load i8, ptr @global, align 1
%tmp1 = zext i8 %tmp to i32
Expand Down
58 changes: 57 additions & 1 deletion llvm/test/CodeGen/X86/tailcall-cgp-dup.ll
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ return:

define ptr @strcpy_illegal_tailc(ptr %dest, i64 %sz, ptr readonly returned %src) nounwind {
; CHECK-LABEL: strcpy_illegal_tailc:
; CHECK: ## %bb.0:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: movq %rdx, %rbx
; CHECK-NEXT: testq %rsi, %rsi
Expand All @@ -351,6 +351,7 @@ define ptr @strcpy_illegal_tailc(ptr %dest, i64 %sz, ptr readonly returned %src)
; CHECK-NEXT: movq %rbx, %rax
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: retq
entry:
%cmp = icmp eq i64 %sz, 0
br i1 %cmp, label %return, label %if.then

Expand All @@ -362,8 +363,63 @@ return:
ret ptr %src
}

@i = global i32 0, align 4

define i32 @undef_tailc() nounwind {
; CHECK-LABEL: undef_tailc:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: cmpl $0, _i(%rip)
; CHECK-NEXT: jne _qux ## TAILCALL
; CHECK-NEXT: ## %bb.1: ## %return
; CHECK-NEXT: retq
entry:
%val = load i32, ptr @i, align 4
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %return, label %if.then

if.then:
%rv_unused = tail call i32 @qux()
br label %return

return:
ret i32 undef
}

define i32 @undef_and_known_tailc() nounwind {
; CHECK-LABEL: undef_and_known_tailc:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl _i(%rip), %eax
; CHECK-NEXT: cmpl $5, %eax
; CHECK-NEXT: je _qux ## TAILCALL
; CHECK-NEXT: ## %bb.1: ## %entry
; CHECK-NEXT: cmpl $2, %eax
; CHECK-NEXT: je _quux ## TAILCALL
; CHECK-NEXT: ## %bb.2: ## %return
; CHECK-NEXT: retq
entry:
%val = load i32, ptr @i, align 4
switch i32 %val, label %return [
i32 2, label %case_2
i32 5, label %case_5
]

case_2:
%rv_unused = tail call i32 @quux()
br label %return

case_5:
%rv = tail call i32 @qux()
br label %return

return:
%phi = phi i32 [ undef, %case_2 ], [ %rv, %case_5 ], [ undef, %entry ]
ret i32 %phi
}

declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1)
declare noalias ptr @malloc(i64)
declare ptr @strcpy(ptr noalias returned writeonly, ptr noalias nocapture readonly)
declare ptr @baz(ptr, ptr)
declare i32 @qux()
declare i32 @quux()

0 comments on commit 25e7e8d

Please sign in to comment.