xref: /llvm-project/llvm/test/CodeGen/PowerPC/stack-restore-with-setjmp.ll (revision a51712751c184ebe056718c938d2526693a31564)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=powerpc64le -verify-machineinstrs | FileCheck %s
3; RUN: llc < %s -mtriple=powerpc64 -mcpu=ppc -verify-machineinstrs | FileCheck %s \
4; RUN:   --check-prefix=BE
5%struct.__jmp_buf_tag = type { [64 x i64], i32, %struct.__sigset_t, [8 x i8] }
6%struct.__sigset_t = type { [16 x i64] }
7
8@.str = private unnamed_addr constant [33 x i8] c"Successfully returned from main\0A\00", align 1
9
10; Function Attrs: nounwind
11define dso_local signext i32 @main(i32 signext %argc, ptr nocapture readnone %argv) local_unnamed_addr #0 {
12; CHECK-LABEL: main:
13; CHECK:       # %bb.0: # %entry
14; CHECK-NEXT:    mfocrf 12, 32
15; CHECK-NEXT:    std 31, -8(1)
16; CHECK-NEXT:    stw 12, 8(1)
17; CHECK-NEXT:    mflr 0
18; CHECK-NEXT:    stdu 1, -784(1)
19; CHECK-NEXT:    # kill: def $r3 killed $r3 killed $x3
20; CHECK-NEXT:    cmpwi 2, 3, 2
21; CHECK-NEXT:    li 4, 0
22; CHECK-NEXT:    # kill: def $r4 killed $r4 killed $x4
23; CHECK-NEXT:    mr 3, 4
24; CHECK-NEXT:    std 0, 800(1)
25; CHECK-NEXT:    mr 31, 1
26; CHECK-NEXT:    blt 2, .LBB0_3
27; CHECK-NEXT:  # %bb.1: # %if.end
28; CHECK-NEXT:    addi 3, 31, 112
29; CHECK-NEXT:    bl _setjmp
30; CHECK-NEXT:    nop
31; CHECK-NEXT:    # kill: def $r3 killed $r3 killed $x3
32; CHECK-NEXT:    cmpwi 3, 0
33; CHECK-NEXT:    crorc 20, 10, 2
34; CHECK-NEXT:    bc 4, 20, .LBB0_4
35; CHECK-NEXT:  # %bb.2: # %if.end5
36; CHECK-NEXT:    addis 3, 2, .L.str@toc@ha
37; CHECK-NEXT:    addi 3, 3, .L.str@toc@l
38; CHECK-NEXT:    bl printf
39; CHECK-NEXT:    nop
40; CHECK-NEXT:    # kill: def $r3 killed $r3 killed $x3
41; CHECK-NEXT:  .LBB0_3: # %return
42; CHECK-NEXT:    # kill: def $r3 killed $r3 def $x3
43; CHECK-NEXT:    addi 1, 31, 784
44; CHECK-NEXT:    ld 0, 16(1)
45; CHECK-NEXT:    lwz 12, 8(1)
46; CHECK-NEXT:    ld 31, -8(1)
47; CHECK-NEXT:    mtlr 0
48; CHECK-NEXT:    mtocrf 32, 12
49; CHECK-NEXT:    blr
50; CHECK-NEXT:  .LBB0_4: # %if.then3
51; CHECK-NEXT:    ld 4, 0(1)
52; CHECK-NEXT:    stdu 4, -16(1)
53; CHECK-NEXT:    addi 3, 1, 96
54; CHECK-NEXT:    li 4, -1
55; CHECK-NEXT:    stb 4, 0(3)
56; CHECK-NEXT:    addi 4, 31, 112
57; CHECK-NEXT:    bl test
58; CHECK-NEXT:    nop
59;
60; BE-LABEL: main:
61; BE:       # %bb.0: # %entry
62; BE-NEXT:    mfcr 12
63; BE-NEXT:    mflr 0
64; BE-NEXT:    std 31, -8(1)
65; BE-NEXT:    stw 12, 8(1)
66; BE-NEXT:    stdu 1, -800(1)
67; BE-NEXT:    li 4, 0
68; BE-NEXT:    # kill: def $r3 killed $r3 killed $x3
69; BE-NEXT:    # kill: def $r4 killed $r4 killed $x4
70; BE-NEXT:    cmpwi 2, 3, 2
71; BE-NEXT:    mr 3, 4
72; BE-NEXT:    std 0, 816(1)
73; BE-NEXT:    mr 31, 1
74; BE-NEXT:    blt 2, .LBB0_3
75; BE-NEXT:  # %bb.1: # %if.end
76; BE-NEXT:    addi 3, 31, 128
77; BE-NEXT:    bl _setjmp
78; BE-NEXT:    nop
79; BE-NEXT:    # kill: def $r3 killed $r3 killed $x3
80; BE-NEXT:    cmpwi 3, 0
81; BE-NEXT:    crorc 20, 10, 2
82; BE-NEXT:    bc 4, 20, .LBB0_4
83; BE-NEXT:  # %bb.2: # %if.end5
84; BE-NEXT:    addis 3, 2, .L.str@toc@ha
85; BE-NEXT:    addi 3, 3, .L.str@toc@l
86; BE-NEXT:    bl printf
87; BE-NEXT:    nop
88; BE-NEXT:    # kill: def $r3 killed $r3 killed $x3
89; BE-NEXT:  .LBB0_3: # %return
90; BE-NEXT:    # kill: def $r3 killed $r3 def $x3
91; BE-NEXT:    addi 1, 31, 800
92; BE-NEXT:    ld 0, 16(1)
93; BE-NEXT:    lwz 12, 8(1)
94; BE-NEXT:    ld 31, -8(1)
95; BE-NEXT:    mtlr 0
96; BE-NEXT:    mtcrf 32, 12 # cr2
97; BE-NEXT:    blr
98; BE-NEXT:  .LBB0_4: # %if.then3
99; BE-NEXT:    ld 4, 0(1)
100; BE-NEXT:    stdu 4, -16(1)
101; BE-NEXT:    addi 3, 1, 112
102; BE-NEXT:    li 4, -1
103; BE-NEXT:    stb 4, 0(3)
104; BE-NEXT:    addi 4, 31, 128
105; BE-NEXT:    bl test
106; BE-NEXT:    nop
107entry:
108  %env_buffer = alloca [1 x %struct.__jmp_buf_tag], align 16
109  %cmp = icmp slt i32 %argc, 2
110  br i1 %cmp, label %return, label %if.end
111
112if.end:                                           ; preds = %entry
113  call void @llvm.lifetime.start.p0(i64 656, ptr nonnull %env_buffer) #5
114  %call = call signext i32 @_setjmp(ptr nonnull %env_buffer) #6
115  %cmp1 = icmp ne i32 %argc, 2
116  %cmp2 = icmp eq i32 %call, 0
117  %or.cond = and i1 %cmp1, %cmp2
118  br i1 %or.cond, label %if.then3, label %if.end5
119
120if.then3:                                         ; preds = %if.end
121  %0 = alloca [8 x i8], align 16
122  store i8 -1, ptr %0, align 16
123  call void @test(ptr nonnull %0, ptr nonnull %env_buffer) #7
124  unreachable
125
126if.end5:                                          ; preds = %if.end
127  %call6 = call signext i32 (ptr, ...) @printf(ptr nonnull dereferenceable(1) @.str)
128  call void @llvm.lifetime.end.p0(i64 656, ptr nonnull %env_buffer) #5
129  br label %return
130
131return:                                           ; preds = %entry, %if.end5
132  %retval.0 = phi i32 [ %call6, %if.end5 ], [ 0, %entry ]
133  ret i32 %retval.0
134}
135
136; Function Attrs: argmemonly nofree nosync nounwind willreturn
137declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
138
139; Function Attrs: nounwind returns_twice
140declare signext i32 @_setjmp(ptr) local_unnamed_addr
141
142; Function Attrs: noreturn
143declare void @test(ptr, ptr) local_unnamed_addr
144
145; Function Attrs: nofree nounwind
146declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr
147
148; Function Attrs: argmemonly nofree nosync nounwind willreturn
149declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
150
151attributes #0 = { nounwind }
152attributes #6 = { nounwind returns_twice }
153