[clang] [llvm] [SystemZ] Add support for __builtin_setjmp and __builtin_longjmp (PR #116642)

Ulrich Weigand via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 3 10:55:22 PST 2024


================
@@ -0,0 +1,255 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Simulate register pressure  around setjmp call for integer arguments.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to int.
+; Test setjmp  store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s -mtriple=s390x-linux-gnu -O2 | FileCheck %s
+
+declare i32 @llvm.eh.sjlj.setjmp(ptr)
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr
+ at buf = global [10 x ptr] zeroinitializer, align 8
+ at t = global i32 0, align 4
+ at s = global i32 0, align 4
+ at r = global i32 0, align 4
+ at q = global i32 0, align 4
+ at p = global i32 0, align 4
+ at o = global i32 0, align 4
+ at n = global i32 0, align 4
+ at m = global i32 0, align 4
+ at l = global i32 0, align 4
+ at k = global i32 0, align 4
+ at j = global i32 0, align 4
+ at i = global i32 0, align 4
+ at h = global i32 0, align 4
+ at g = global i32 0, align 4
+ at f = global i32 0, align 4
+ at e = global i32 0, align 4
+ at d = global i32 0, align 4
+ at c = global i32 0, align 4
+ at b = global i32 0, align 4
+ at a = global i32 0, align 4
+
+define signext i32 @func() {
+; CHECK-LABEL: func:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stmg %r6, %r15, 48(%r15)
+; CHECK-NEXT:    .cfi_offset %r6, -112
+; CHECK-NEXT:    .cfi_offset %r7, -104
+; CHECK-NEXT:    .cfi_offset %r8, -96
+; CHECK-NEXT:    .cfi_offset %r9, -88
+; CHECK-NEXT:    .cfi_offset %r10, -80
+; CHECK-NEXT:    .cfi_offset %r11, -72
+; CHECK-NEXT:    .cfi_offset %r12, -64
+; CHECK-NEXT:    .cfi_offset %r13, -56
+; CHECK-NEXT:    .cfi_offset %r14, -48
+; CHECK-NEXT:    .cfi_offset %r15, -40
+; CHECK-NEXT:    aghi %r15, -448
+; CHECK-NEXT:    .cfi_def_cfa_offset 608
+; CHECK-NEXT:    std %f8, 440(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f9, 432(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f10, 424(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f11, 416(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f12, 408(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f13, 400(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f14, 392(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    std %f15, 384(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    .cfi_offset %f8, -168
+; CHECK-NEXT:    .cfi_offset %f9, -176
+; CHECK-NEXT:    .cfi_offset %f10, -184
+; CHECK-NEXT:    .cfi_offset %f11, -192
+; CHECK-NEXT:    .cfi_offset %f12, -200
+; CHECK-NEXT:    .cfi_offset %f13, -208
+; CHECK-NEXT:    .cfi_offset %f14, -216
+; CHECK-NEXT:    .cfi_offset %f15, -224
+; CHECK-NEXT:    lgrl %r1, buf at GOT
+; CHECK-NEXT:    larl %r0, .LBB0_1
+; CHECK-NEXT:    stg %r0, 8(%r1)
+; CHECK-NEXT:    stg %r15, 24(%r1)
+; CHECK-NEXT:  .LBB0_1: # Block address taken
+; CHECK-NEXT:    # %entry
+; CHECK-NEXT:  .LBB0_2: # %entry
+; CHECK-NEXT:    lgrl %r1, t at GOT
+; CHECK-NEXT:    stg %r1, 312(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    lgrl %r2, s at GOT
+; CHECK-NEXT:    stg %r2, 304(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    lgrl %r3, r at GOT
+; CHECK-NEXT:    stg %r3, 296(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    lgrl %r4, q at GOT
+; CHECK-NEXT:    stg %r4, 288(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r1), 1
+; CHECK-NEXT:    mvhi 0(%r2), 1
+; CHECK-NEXT:    mvhi 0(%r3), 1
+; CHECK-NEXT:    mvhi 0(%r4), 1
+; CHECK-NEXT:    lgrl %r5, p at GOT
+; CHECK-NEXT:    lgrl %r14, o at GOT
+; CHECK-NEXT:    lgrl %r1, n at GOT
+; CHECK-NEXT:    stg %r1, 280(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    lgrl %r9, m at GOT
+; CHECK-NEXT:    mvhi 0(%r5), 1
+; CHECK-NEXT:    stg %r5, 376(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r14), 1
+; CHECK-NEXT:    stg %r14, 368(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r1), 1
+; CHECK-NEXT:    mvhi 0(%r9), 1
+; CHECK-NEXT:    stg %r9, 360(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    lgrl %r1, l at GOT
+; CHECK-NEXT:    lgrl %r2, k at GOT
+; CHECK-NEXT:    lgrl %r3, j at GOT
+; CHECK-NEXT:    lgrl %r4, i at GOT
+; CHECK-NEXT:    stg %r4, 344(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r1), 1
+; CHECK-NEXT:    stg %r1, 352(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r2), 1
+; CHECK-NEXT:    stg %r2, 336(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r3), 1
+; CHECK-NEXT:    stg %r3, 328(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r4), 1
+; CHECK-NEXT:    lgrl %r4, h at GOT
+; CHECK-NEXT:    lgrl %r8, g at GOT
+; CHECK-NEXT:    lgrl %r7, f at GOT
+; CHECK-NEXT:    lgrl %r6, e at GOT
+; CHECK-NEXT:    mvhi 0(%r4), 1
+; CHECK-NEXT:    stg %r4, 320(%r15) # 8-byte Folded Spill
+; CHECK-NEXT:    mvhi 0(%r8), 1
+; CHECK-NEXT:    mvhi 0(%r7), 1
+; CHECK-NEXT:    mvhi 0(%r6), 1
+; CHECK-NEXT:    lgrl %r13, d at GOT
+; CHECK-NEXT:    lgrl %r12, c at GOT
+; CHECK-NEXT:    lgrl %r11, b at GOT
+; CHECK-NEXT:    lgrl %r10, a at GOT
+; CHECK-NEXT:    mvhi 0(%r13), 1
+; CHECK-NEXT:    mvhi 0(%r12), 1
+; CHECK-NEXT:    mvhi 0(%r11), 1
+; CHECK-NEXT:    mvhi 0(%r10), 1
+; CHECK-NEXT:    mvc 272(8,%r15), 312(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    mvc 264(8,%r15), 304(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    mvc 256(8,%r15), 296(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    mvc 248(8,%r15), 288(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    stg %r5, 240(%r15)
+; CHECK-NEXT:    stg %r14, 232(%r15)
+; CHECK-NEXT:    mvc 224(8,%r15), 280(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    stg %r9, 216(%r15)
+; CHECK-NEXT:    stg %r1, 208(%r15)
+; CHECK-NEXT:    stg %r2, 200(%r15)
+; CHECK-NEXT:    stg %r3, 192(%r15)
+; CHECK-NEXT:    lg %r9, 344(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    stg %r9, 184(%r15)
+; CHECK-NEXT:    stg %r4, 176(%r15)
+; CHECK-NEXT:    stg %r8, 168(%r15)
+; CHECK-NEXT:    stg %r7, 160(%r15)
+; CHECK-NEXT:    lgr %r2, %r10
+; CHECK-NEXT:    lgr %r3, %r11
+; CHECK-NEXT:    lgr %r4, %r12
+; CHECK-NEXT:    lgr %r5, %r13
+; CHECK-NEXT:    brasl %r14, foo at PLT
+; CHECK-NEXT:    l %r0, 0(%r11)
+; CHECK-NEXT:    a %r0, 0(%r10)
+; CHECK-NEXT:    a %r0, 0(%r12)
+; CHECK-NEXT:    a %r0, 0(%r13)
+; CHECK-NEXT:    a %r0, 0(%r6)
+; CHECK-NEXT:    a %r0, 0(%r7)
+; CHECK-NEXT:    a %r0, 0(%r8)
+; CHECK-NEXT:    lg %r1, 320(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    a %r0, 0(%r9)
+; CHECK-NEXT:    lg %r1, 328(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 336(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 352(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 360(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 280(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 368(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 376(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 288(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 296(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 304(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lg %r1, 312(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    a %r0, 0(%r1)
+; CHECK-NEXT:    lgfr %r2, %r0
+; CHECK-NEXT:    ld %f8, 440(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f9, 432(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f10, 424(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f11, 416(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f12, 408(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f13, 400(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f14, 392(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    ld %f15, 384(%r15) # 8-byte Folded Reload
+; CHECK-NEXT:    lmg %r6, %r15, 496(%r15)
+; CHECK-NEXT:    br %r14
+entry:
+  %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
----------------
uweigand wrote:

Looking at this again, I'm a bit confused what this is supposed to test?  There are no registers live across the setjmp anyway ...

I'd have throught a good test would be to make a large number of virtual registers live *before* the setjmp, and then use all of them *after* the setjmp.  The test would then verify that the compiler doesn't attempt to keep any of these virtual registers alive in call-saved GPRs, but rather saves all of them to the stack.

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


More information about the cfe-commits mailing list