[llvm] [RegAlloc] Change the computation of CSRCost (PR #177226)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 21 11:57:10 PST 2026


================
@@ -0,0 +1,131 @@
+; 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 datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "aarch64"
+
+; In cold basic blocks we should spill a register instead of using callee saved
+; register.
+
+ at 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:
+  %0 = load ptr, ptr %param, align 8
+  %cmp = icmp eq ptr %0, null
+  br i1 %cmp, label %return, label %if.end
+
+if.end:                                           ; preds = %entry
+  %b = getelementptr inbounds nuw i8, ptr %param, i64 8
+  %1 = load i32, ptr %b, align 8
+  %cmp1.not = icmp eq i32 %1, 0
+  br i1 %cmp1.not, label %if.end6, label %cold1, !prof !12
+
+cold1:                                         ; preds = %if.end
+  %call = tail call i64 @fuzz(ptr %0, i32 %1)
+  br label %if.end6
+
+if.end6:                                          ; preds = %cold1, %if.end
+  %c = getelementptr inbounds nuw i8, ptr %param, i64 12
+  %2 = load i32, ptr %c, align 4
+  %cmp7.not = icmp eq i32 %2, 0
+  br i1 %cmp7.not, label %if.end24, label %cold2, !prof !12
+
+cold2:                                        ; preds = %if.end6
+  %3 = load ptr, ptr @Func, align 8
+  %call17 = tail call i1 %3()
+  br i1 %call17, label %cold3, label %if.end24
+
+cold3:                                        ; preds = %cold2
+  %4 = load ptr, ptr %param, align 8
+  %sunkaddr = getelementptr inbounds i8, ptr %param, i64 12
+  %5 = load i32, ptr %sunkaddr, align 4
+  %conv21 = trunc i32 %5 to i16
+  %call22 = tail call i64 @bar(ptr %4, 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
+  %6 = zext i8 %bf.load to i32
+  %bf.clear = and i32 %6, 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
+  %7 = load ptr, ptr %param, align 8
+  tail call void @bob(ptr %7)
+  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 = { nounwind uwtable "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
----------------
arsenm wrote:

Remove unnecessary attributes 

https://github.com/llvm/llvm-project/pull/177226


More information about the llvm-commits mailing list