xref: /llvm-project/llvm/test/CodeGen/PowerPC/remove-redundant-toc-saves.ll (revision 5403c59c608c08c8ecd4303763f08eb046eb5e4d)
1; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
2; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix-xcoff < %s | FileCheck %s --check-prefix=AIX64
3; RUN: llc -verify-machineinstrs -mtriple=powerpc-ibm-aix-xcoff < %s | FileCheck %s --check-prefix=AIX32
4
5define signext i32 @test1(i32 signext %i, ptr nocapture %Func, ptr nocapture %Func2) {
6entry:
7; CHECK-LABEL: test1:
8; CHECK:    std 2, 24(1)
9; CHECK-NOT:    std 2, 24(1)
10
11; AIX64-LABEL: test1:
12; AIX64: std 2, 40(1)
13; AIX64-NOT: std 2, 40(1)
14
15; AIX32-LABEL: test1:
16; AIX32: stw 2, 20(1)
17; AIX32-NOT: std 2, 20(1)
18  %call = tail call signext i32 %Func(i32 signext %i)
19  %call1 = tail call signext i32 %Func2(i32 signext %i)
20  %add2 = add nsw i32 %call1, %call
21  ret i32 %add2
22}
23
24define signext i32 @test2(i32 signext %i, i32 signext %j, ptr nocapture %Func, ptr nocapture %Func2) {
25entry:
26; CHECK-LABEL: test2:
27; CHECK:    std 2, 24(1)
28; CHECK-NOT:    std 2, 24(1)
29
30; AIX64-LABEL: test2:
31; AIX64: std 2, 40(1)
32; AIX64-NOT: std 2, 40(1)
33
34; AIX32-LABEL: test2:
35; AIX32: stw 2, 20(1)
36; AIX32-NOT: std 2, 20(1)
37  %call = tail call signext i32 %Func(i32 signext %i)
38  %tobool = icmp eq i32 %j, 0
39  br i1 %tobool, label %if.end, label %if.then
40
41if.then:                                          ; preds = %entry
42  %call1 = tail call signext i32 %Func(i32 signext %i)
43  %add2 = add nsw i32 %call1, %call
44  %call3 = tail call signext i32 %Func2(i32 signext %i)
45  %add4 = add nsw i32 %add2, %call3
46  br label %if.end
47
48if.end:                                           ; preds = %entry, %if.then
49  %Sum.0 = phi i32 [ %add4, %if.then ], [ %call, %entry ]
50  %call5 = tail call signext i32 %Func(i32 signext %i)
51  %add6 = add nsw i32 %call5, %Sum.0
52  ret i32 %add6
53}
54
55; Check for multiple TOC saves with if then else where neither dominates the other.
56define signext i32 @test3(i32 signext %i, ptr nocapture %Func, ptr nocapture %Func2) {
57; CHECK-LABEL: test3:
58; CHECK:    std 2, 24(1)
59; CHECK-NOT:    std 2, 24(1)
60
61; AIX64-LABEL: test3:
62; AIX64-COUNT-3: std 2, 40(1)
63
64; AIX32-LABEL: test3:
65; AIX32-COUNT-3: stw 2, 20(1)
66entry:
67  %tobool = icmp eq i32 %i, 0
68  br i1 %tobool, label %if.else, label %if.then
69
70if.then:                                          ; preds = %entry
71  %call = tail call signext i32 %Func(i32 signext %i)
72  br label %if.end
73
74if.else:                                          ; preds = %entry
75  %call1 = tail call signext i32 %Func2(i32 signext 0)
76  br label %if.end
77
78if.end:                                           ; preds = %if.else, %if.then
79  %Sum.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
80  %call3 = tail call signext i32 %Func(i32 signext %i)
81  %add4 = add nsw i32 %call3, %Sum.0
82  ret i32 %add4
83}
84
85define signext i32 @test4(i32 signext %i, ptr nocapture %Func, ptr nocapture %Func2) {
86; CHECK-LABEL: test4:
87; CHECK:    std 2, 24(1)
88; CHECK-NOT:    std 2, 24(1)
89
90; AIX64-LABEL: test4:
91; AIX64: std 2, 40(1)
92; AIX64-NOT: std 2, 40(1)
93
94; AIX32-LABEL: test4:
95; AIX32: stw 2, 20(1)
96; AIX32-NOT: std 2, 20(1)
97entry:
98  %call = tail call signext i32 %Func(i32 signext %i)
99  %tobool = icmp eq i32 %i, 0
100  br i1 %tobool, label %if.else, label %if.then
101
102if.then:                                          ; preds = %entry
103  %call1 = tail call signext i32 %Func(i32 signext %i)
104  br label %if.end
105
106if.else:                                          ; preds = %entry
107  %call3 = tail call signext i32 %Func2(i32 signext 0)
108  br label %if.end
109
110if.end:                                           ; preds = %if.else, %if.then
111  %call1.pn = phi i32 [ %call1, %if.then ], [ %call3, %if.else ]
112  %Sum.0 = add nsw i32 %call1.pn, %call
113  ret i32 %Sum.0
114}
115
116; Check for multiple TOC saves with if then where neither is redundant.
117define signext i32 @test5(i32 signext %i, ptr nocapture %Func, ptr nocapture readnone %Func2) {
118entry:
119; CHECK-LABEL: test5:
120; CHECK:    std 2, 24(1)
121
122; AIX64-LABEL: test5:
123; AIX64: std 2, 40(1)
124
125; AIX32-LABEL: test5:
126; AIX32: stw 2, 20(1)
127  %tobool = icmp eq i32 %i, 0
128  br i1 %tobool, label %if.end, label %if.then
129
130if.then:                                          ; preds = %entry
131  %call = tail call signext i32 %Func(i32 signext %i)
132  br label %if.end
133
134if.end:                                           ; preds = %entry, %if.then
135  %Sum.0 = phi i32 [ %call, %if.then ], [ 0, %entry ]
136  %call1 = tail call signext i32 %Func(i32 signext %i)
137  %add2 = add nsw i32 %call1, %Sum.0
138  ret i32 %add2
139}
140
141; Check for multiple TOC saves if there are dynamic allocations on the stack.
142define signext i32 @test6(i32 signext %i, ptr nocapture %Func, ptr nocapture %Func2) {
143entry:
144; CHECK-LABEL: test6:
145; CHECK:    std 2, 24(1)
146; CHECK:    std 2, 24(1)
147
148; AIX64-LABEL: test6:
149; AIX64: std 2, 40(1)
150; AIX64: std 2, 40(1)
151
152; AIX32-LABEL: test6:
153; AIX32: stw 2, 20(1)
154; AIX32: stw 2, 20(1)
155  %conv = sext i32 %i to i64
156  %0 = alloca i8, i64 %conv, align 16
157  %call = tail call signext i32 %Func(i32 signext %i)
158  call void @useAlloca(ptr nonnull %0, i32 signext %call)
159  %call1 = call signext i32 %Func2(i32 signext %i)
160  %add2 = add nsw i32 %call1, %call
161  ret i32 %add2
162}
163
164declare void @useAlloca(ptr, i32 signext)
165