| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc < %s -regalloc-csr-cost-scale=80 | FileCheck %s |
| |
| target triple = "aarch64" |
| |
| ; In cold basic blocks we should spill a register instead of using callee saved |
| ; register. |
| |
| @Func = external global ptr |
| |
| define void @foo(ptr %param) #0 { |
| ; CHECK-LABEL: foo: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: ldr x8, [x0] |
| ; CHECK-NEXT: cbz x8, .LBB0_4 |
| ; CHECK-NEXT: // %bb.1: // %if.end |
| ; CHECK-NEXT: sub sp, sp, #32 |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 |
| ; CHECK-NEXT: stp x29, x30, [sp, #16] // 16-byte Folded Spill |
| ; CHECK-NEXT: add x29, sp, #16 |
| ; CHECK-NEXT: .cfi_def_cfa w29, 16 |
| ; CHECK-NEXT: .cfi_offset w30, -8 |
| ; CHECK-NEXT: .cfi_offset w29, -16 |
| ; CHECK-NEXT: .cfi_remember_state |
| ; CHECK-NEXT: ldr w1, [x0, #8] |
| ; CHECK-NEXT: cbnz w1, .LBB0_5 |
| ; CHECK-NEXT: // %bb.2: // %if.end6 |
| ; CHECK-NEXT: ldr w8, [x0, #12] |
| ; CHECK-NEXT: cbnz w8, .LBB0_6 |
| ; CHECK-NEXT: .LBB0_3: // %if.end24 |
| ; CHECK-NEXT: ldrb w8, [x0, #16] |
| ; CHECK-NEXT: .cfi_def_cfa wsp, 32 |
| ; CHECK-NEXT: ldp x29, x30, [sp, #16] // 16-byte Folded Reload |
| ; CHECK-NEXT: add sp, sp, #32 |
| ; CHECK-NEXT: .cfi_def_cfa_offset 0 |
| ; CHECK-NEXT: .cfi_restore w30 |
| ; CHECK-NEXT: .cfi_restore w29 |
| ; CHECK-NEXT: tbnz w8, #0, .LBB0_8 |
| ; CHECK-NEXT: .LBB0_4: // %common.ret |
| ; CHECK-NEXT: ret |
| ; CHECK-NEXT: .LBB0_5: // %cold1 |
| ; CHECK-NEXT: .cfi_restore_state |
| ; CHECK-NEXT: str x0, [sp, #8] // 8-byte Spill |
| ; CHECK-NEXT: mov x0, x8 |
| ; CHECK-NEXT: bl fuzz |
| ; CHECK-NEXT: ldr x0, [sp, #8] // 8-byte Reload |
| ; CHECK-NEXT: ldr w8, [x0, #12] |
| ; CHECK-NEXT: cbz w8, .LBB0_3 |
| ; CHECK-NEXT: .LBB0_6: // %cold2 |
| ; CHECK-NEXT: adrp x8, :got:Func |
| ; CHECK-NEXT: ldr x8, [x8, :got_lo12:Func] |
| ; CHECK-NEXT: str x0, [sp, #8] // 8-byte Spill |
| ; CHECK-NEXT: ldr x8, [x8] |
| ; CHECK-NEXT: blr x8 |
| ; CHECK-NEXT: mov w8, w0 |
| ; CHECK-NEXT: ldr x0, [sp, #8] // 8-byte Reload |
| ; CHECK-NEXT: tbz w8, #0, .LBB0_3 |
| ; CHECK-NEXT: // %bb.7: // %cold3 |
| ; CHECK-NEXT: ldr x8, [x0] |
| ; CHECK-NEXT: ldr w1, [x0, #12] |
| ; CHECK-NEXT: mov x0, x8 |
| ; CHECK-NEXT: bl bar |
| ; CHECK-NEXT: ldr x0, [sp, #8] // 8-byte Reload |
| ; CHECK-NEXT: b .LBB0_3 |
| ; CHECK-NEXT: .LBB0_8: // %if.then35 |
| ; CHECK-NEXT: .cfi_def_cfa wsp, 0 |
| ; CHECK-NEXT: .cfi_same_value w30 |
| ; CHECK-NEXT: .cfi_same_value w29 |
| ; CHECK-NEXT: ldr x0, [x0] |
| ; CHECK-NEXT: b bob |
| entry: |
| %load0 = load ptr, ptr %param, align 8 |
| %cmp = icmp eq ptr %load0, null |
| br i1 %cmp, label %return, label %if.end |
| |
| if.end: ; preds = %entry |
| %b = getelementptr inbounds nuw i8, ptr %param, i64 8 |
| %load1 = load i32, ptr %b, align 8 |
| %cmp1.not = icmp eq i32 %load1, 0 |
| br i1 %cmp1.not, label %if.end6, label %cold1, !prof !12 |
| |
| cold1: ; preds = %if.end |
| %call = tail call i64 @fuzz(ptr %load0, i32 %load1) |
| br label %if.end6 |
| |
| if.end6: ; preds = %cold1, %if.end |
| %c = getelementptr inbounds nuw i8, ptr %param, i64 12 |
| %load2 = load i32, ptr %c, align 4 |
| %cmp7.not = icmp eq i32 %load2, 0 |
| br i1 %cmp7.not, label %if.end24, label %cold2, !prof !12 |
| |
| cold2: ; preds = %if.end6 |
| %func = load ptr, ptr @Func, align 8 |
| %call17 = tail call i1 %func() |
| br i1 %call17, label %cold3, label %if.end24 |
| |
| cold3: ; preds = %cold2 |
| %load4 = load ptr, ptr %param, align 8 |
| %sunkaddr = getelementptr inbounds i8, ptr %param, i64 12 |
| %load5 = load i32, ptr %sunkaddr, align 4 |
| %conv21 = trunc i32 %load5 to i16 |
| %call22 = tail call i64 @bar(ptr %load4, i16 %conv21) |
| br label %if.end24 |
| |
| if.end24: ; preds = %cold2, %cold3, %if.end6 |
| %d = getelementptr inbounds nuw i8, ptr %param, i64 16 |
| %bf.load = load i8, ptr %d, align 8 |
| %zext = zext i8 %bf.load to i32 |
| %bf.clear = and i32 %zext, 1 |
| %cmp26.not = icmp eq i32 %bf.clear, 0 |
| br i1 %cmp26.not, label %return, label %if.then35, !prof !12 |
| |
| if.then35: ; preds = %if.end24 |
| %load6 = load ptr, ptr %param, align 8 |
| tail call void @bob(ptr %load6) |
| ret void |
| |
| return: ; preds = %if.end24, %entry |
| ret void |
| } |
| |
| declare i64 @fuzz(ptr, i32) |
| |
| declare i64 @bar(ptr, i16) |
| |
| declare void @bob(ptr) |
| |
| attributes #0 = { uwtable "frame-pointer"="non-leaf-no-reserve" } |
| |
| !12 = !{!"branch_weights", !"expected", i32 2000, i32 1} |