[llvm] [SPARC] Implement TargetInstrInfo::insertIndirectBranch() (PR #226678)

Daniel Cederman via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 11 09:41:53 PDT 2026


================
@@ -162,3 +287,244 @@ false:
   call void asm sideeffect "nop\0A\09nop\0A\09nop\0A\09nop\0A\09nop\0A\09nop\0A\09nop\0A\09nop", ""()
   ret float 0.0
 }
+
+define i32 @branch_relax_large(i32 %in) {
+; SPARC-LABEL: branch_relax_large:
+; SPARC:         .cfi_startproc
+; SPARC-NEXT:  ! %bb.0:
+; SPARC-NEXT:    save %sp, -96, %sp
+; SPARC-NEXT:    .cfi_def_cfa_register %fp
+; SPARC-NEXT:    .cfi_window_save
+; SPARC-NEXT:    .cfi_register %o7, %i7
+; SPARC-NEXT:    cmp %i0, 0
+; SPARC-NEXT:    bne .LBB3_1
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  ! %bb.3:
+; SPARC-NEXT:    call .LBB3_2
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  .LBB3_1: ! %false
+; SPARC-NEXT:    !APP
+; SPARC-NEXT:    .skip 268435456
+; SPARC-NEXT:    !NO_APP
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %g0, %o0
+; SPARC-NEXT:  .LBB3_2: ! %true
+; SPARC-NEXT:    mov 4, %i0
+; SPARC-NEXT:    !APP
+; SPARC-NEXT:    .skip 268435456
+; SPARC-NEXT:    !NO_APP
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore
+;
+; SPARC64-LABEL: branch_relax_large:
+; SPARC64:         .cfi_startproc
+; SPARC64-NEXT:  ! %bb.0:
+; SPARC64-NEXT:    save %sp, -128, %sp
+; SPARC64-NEXT:    .cfi_def_cfa_register %fp
+; SPARC64-NEXT:    .cfi_window_save
+; SPARC64-NEXT:    .cfi_register %o7, %i7
+; SPARC64-NEXT:    cmp %i0, 0
+; SPARC64-NEXT:    bne %icc, .LBB3_1
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:  ! %bb.3:
+; SPARC64-NEXT:    call .LBB3_2
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:  .LBB3_1: ! %false
+; SPARC64-NEXT:    !APP
+; SPARC64-NEXT:    .skip 268435456
+; SPARC64-NEXT:    !NO_APP
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %g0, %o0
+; SPARC64-NEXT:  .LBB3_2: ! %true
+; SPARC64-NEXT:    mov 4, %i0
+; SPARC64-NEXT:    !APP
+; SPARC64-NEXT:    .skip 268435456
+; SPARC64-NEXT:    !NO_APP
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %tst = icmp eq i32 %in, 0
+  br i1 %tst, label %true, label %false
+
+true:
+  call void asm sideeffect ".space 268435456", ""()
+  ret i32 4
+
+false:
+  call void asm sideeffect ".space 268435456", ""()
+  ret i32 0
+}
+
+define i32 @branch_relax_large_o7_used(i32 %in) {
+; SPARC-LABEL: branch_relax_large_o7_used:
+; SPARC:         .cfi_startproc
+; SPARC-NEXT:  ! %bb.0:
+; SPARC-NEXT:    save %sp, -96, %sp
+; SPARC-NEXT:    .cfi_def_cfa_register %fp
+; SPARC-NEXT:    .cfi_window_save
+; SPARC-NEXT:    .cfi_register %o7, %i7
+; SPARC-NEXT:    cmp %i0, 0
+; SPARC-NEXT:    !APP
+; SPARC-NEXT:  .Ltmp0:
+; SPARC-NEXT:    call .Ltmp0+8
+; SPARC-NEXT:    nop
+; SPARC-NEXT:    !NO_APP
+; SPARC-NEXT:    bne .LBB4_1
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  ! %bb.3:
+; SPARC-NEXT:    mov %o7, %i0
+; SPARC-NEXT:    call .LBB4_4
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  .LBB4_1: ! %false
+; SPARC-NEXT:    !APP
+; SPARC-NEXT:    .skip 268435456
+; SPARC-NEXT:    !NO_APP
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %g0, %o0
+; SPARC-NEXT:  .LBB4_4: ! %true
+; SPARC-NEXT:    mov %i0, %o7
+; SPARC-NEXT:  ! %bb.2: ! %true
+; SPARC-NEXT:    !APP
+; SPARC-NEXT:    .skip 268435456
+; SPARC-NEXT:    !NO_APP
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %o7, %o0
+;
+; SPARC64-LABEL: branch_relax_large_o7_used:
+; SPARC64:         .cfi_startproc
+; SPARC64-NEXT:  ! %bb.0:
+; SPARC64-NEXT:    save %sp, -128, %sp
+; SPARC64-NEXT:    .cfi_def_cfa_register %fp
+; SPARC64-NEXT:    .cfi_window_save
+; SPARC64-NEXT:    .cfi_register %o7, %i7
+; SPARC64-NEXT:    cmp %i0, 0
+; SPARC64-NEXT:    !APP
+; SPARC64-NEXT:  .Ltmp0:
+; SPARC64-NEXT:    call .Ltmp0+8
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:    !NO_APP
+; SPARC64-NEXT:    bne %icc, .LBB4_1
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:  ! %bb.3:
+; SPARC64-NEXT:    mov %o7, %i0
+; SPARC64-NEXT:    call .LBB4_4
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:  .LBB4_1: ! %false
+; SPARC64-NEXT:    !APP
+; SPARC64-NEXT:    .skip 268435456
+; SPARC64-NEXT:    !NO_APP
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %g0, %o0
+; SPARC64-NEXT:  .LBB4_4: ! %true
+; SPARC64-NEXT:    mov %i0, %o7
+; SPARC64-NEXT:  ! %bb.2: ! %true
+; SPARC64-NEXT:    !APP
+; SPARC64-NEXT:    .skip 268435456
+; SPARC64-NEXT:    !NO_APP
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %o7, %o0
+  %tst = icmp eq i32 %in, 0
+  %ret = call i32 asm sideeffect "call .+8\0Anop", "={o7}"()
+  br i1 %tst, label %true, label %false
+
+true:
+  call void asm sideeffect ".space 268435456", ""()
+  ret i32 %ret
+
+false:
+  call void asm sideeffect ".space 268435456", ""()
+  ret i32 0
+}
+
+;; For these we reserve everything except %o7 to make sure it is spilled.
+; RUN: llc < %s -mtriple=sparc -mattr=+reserve-g1 -mattr=+reserve-g2 -mattr=+reserve-g3 -mattr=+reserve-g4 -mattr=+reserve-g5 -mattr=+reserve-g6 -mattr=+reserve-g7 -mattr=+reserve-o0 -mattr=+reserve-o1 -mattr=+reserve-o2 -mattr=+reserve-o3 -mattr=+reserve-o4 -mattr=+reserve-o5 -mattr=+reserve-l1 -mattr=+reserve-l2 -mattr=+reserve-l3 -mattr=+reserve-l4 -mattr=+reserve-l5 -mattr=+reserve-l6 -mattr=+reserve-l7 -mattr=+reserve-l0 -mattr=+reserve-i0 -mattr=+reserve-i1 -mattr=+reserve-i2 -mattr=+reserve-i3 -mattr=+reserve-i4 -mattr=+reserve-i5 -verify-machineinstrs | FileCheck --check-prefix=SPARC-SPILL-O7 %s
+; RUN: llc < %s -mtriple=sparc64 -mattr=+reserve-g1 -mattr=+reserve-g2 -mattr=+reserve-g3 -mattr=+reserve-g4 -mattr=+reserve-g5 -mattr=+reserve-g6 -mattr=+reserve-g7 -mattr=+reserve-o0 -mattr=+reserve-o1 -mattr=+reserve-o2 -mattr=+reserve-o3 -mattr=+reserve-o4 -mattr=+reserve-o5 -mattr=+reserve-l1 -mattr=+reserve-l2 -mattr=+reserve-l3 -mattr=+reserve-l4 -mattr=+reserve-l5 -mattr=+reserve-l6 -mattr=+reserve-l7 -mattr=+reserve-l0 -mattr=+reserve-i0 -mattr=+reserve-i1 -mattr=+reserve-i2 -mattr=+reserve-i3 -mattr=+reserve-i4 -mattr=+reserve-i5 -verify-machineinstrs -sparc-bpcc-offset-bits=4 -sparc-bpr-offset-bits=4 | FileCheck --check-prefix=SPARC64-SPILL-O7 %s
+
+define i32 @branch_relax_large_o7_spilled(i32 %in) {
+; SPARC-SPILL-O7-LABEL: branch_relax_large_o7_spilled:
+; SPARC-SPILL-O7:         .cfi_startproc
+; SPARC-SPILL-O7-NEXT:  ! %bb.0:
+; SPARC-SPILL-O7-NEXT:    save %sp, -96, %sp
+; SPARC-SPILL-O7-NEXT:    .cfi_def_cfa_register %fp
+; SPARC-SPILL-O7-NEXT:    .cfi_window_save
+; SPARC-SPILL-O7-NEXT:    .cfi_register %o7, %i7
+; SPARC-SPILL-O7-NEXT:    mov %i0, %o7
+; SPARC-SPILL-O7-NEXT:    cmp %o7, 0
+; SPARC-SPILL-O7-NEXT:    !APP
+; SPARC-SPILL-O7-NEXT:  .Ltmp1:
+; SPARC-SPILL-O7-NEXT:    call .Ltmp1+8
+; SPARC-SPILL-O7-NEXT:    nop
+; SPARC-SPILL-O7-NEXT:    !NO_APP
+; SPARC-SPILL-O7-NEXT:    !APP
+; SPARC-SPILL-O7-NEXT:    mov %g0, %i0
+; SPARC-SPILL-O7-NEXT:    !NO_APP
+; SPARC-SPILL-O7-NEXT:    bne .LBB5_1
+; SPARC-SPILL-O7-NEXT:    nop
+; SPARC-SPILL-O7-NEXT:  ! %bb.3:
+; SPARC-SPILL-O7-NEXT:    st %o7, [%fp] ! 4-byte Folded Spill
----------------
doac wrote:

%fp points to the start of the register save area for the previous function, so it might get overwritten if you get an interrupt.

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


More information about the llvm-commits mailing list