1; Ensure that IR count remarks in the legacy pass manager work.
2; What this test should check for:
3; * Positive, nonzero sizes before/after for whole-module remarks
4;   (It's okay to have nonzero sizes in per-function remarks, since a function
5;    can be created/destroyed by a pass.)
6; * Nonzero deltas
7; * Sizes are being tracked properly across multiple remarks. E.g, if we have
8;     original_count_1, final_count_1, and
9;     original_count_2, final_count_2,
10;  Then original_count_2 == final_count_1.
11
12; For these remarks, the "function" field in the YAML file doesn't matter.
13; Each of the testcases work by combining the output remarks with the
14; optimization record emit using -pass-remarks-output. This is done to prevent
15; test flakiness wrt instruction counts, but also ensure that the output values
16; are equivalent in both outputs.
17
18; RUN: opt -enable-new-pm=0 < %s -inline -pass-remarks-analysis='size-info' \
19; RUN: -pass-remarks-output=%t.yaml -S -o /dev/null 2> %t; \
20; RUN: cat %t %t.yaml | FileCheck %s -check-prefix=CGSCC
21; CGSCC: remark: <unknown>:0:0: Function Integration/Inlining:
22; CGSCC-SAME: IR instruction count changed from
23; CGSCC-SAME: [[ORIG:[1-9][0-9]*]] to [[FINAL:[1-9][0-9]*]];
24; CGSCC-SAME: Delta: [[DELTA:-?[1-9][0-9]*]]
25; CGSCC-NEXT: remark: <unknown>:0:0: Function Integration/Inlining:
26; CGSCC-SAME: Function: bar: IR instruction count changed from
27; CGSCC-SAME: [[ORIGFN:[1-9][0-9]*]] to [[FINALFN:[0-9][0-9]*]];
28; CGSCC-SAME: Delta: [[DELTAFN:-?[1-9][0-9]*]]
29; CGSCC-NEXT: ---
30; CGSCC-DAG: !Analysis
31; CGSCC-NEXT: Pass:            size-info
32; CGSCC-NEXT: Name:            IRSizeChange
33; CGSCC-NEXT: Function:
34; CGSCC-NEXT: Args:
35; CGSCC-NEXT:  - Pass:            'Function Integration/Inlining'
36; CGSCC-NEXT:  - String:          ': IR instruction count changed from '
37; CGSCC-NEXT:  - IRInstrsBefore:  '[[ORIG]]'
38; CGSCC-NEXT:  - String:          ' to '
39; CGSCC-NEXT:  - IRInstrsAfter:   '[[FINAL]]'
40; CGSCC-NEXT:  - String:          '; Delta: '
41; CGSCC-NEXT:  - DeltaInstrCount: '[[DELTA]]'
42; CGSCC-DAG: --- !Analysis
43; CGSCC-NEXT: Pass:            size-info
44; CGSCC-NEXT: Name:            FunctionIRSizeChange
45; CGSCC-NEXT: Function:
46; CGSCC-NEXT: Args:
47; CGSCC-NEXT:   - Pass:            'Function Integration/Inlining'
48; CGSCC-NEXT:   - String:          ': Function: '
49; CGSCC-NEXT:   - Function:        bar
50; CGSCC-NEXT:   - String:          ': IR instruction count changed from '
51; CGSCC-NEXT:   - IRInstrsBefore:  '[[ORIGFN]]'
52; CGSCC-NEXT:   - String:          ' to '
53; CGSCC-NEXT:   - IRInstrsAfter:   '[[FINALFN]]'
54; CGSCC-NEXT:   - String:          '; Delta: '
55; CGSCC-NEXT:   - DeltaInstrCount: '[[DELTAFN]]'
56; CGSCC-NEXT: ...
57
58; RUN: opt -enable-new-pm=0 < %s -instcombine -pass-remarks-analysis='size-info' \
59; RUN:-pass-remarks-output=%t.yaml -S -o /dev/null 2> %t; \
60; RUN: cat %t %t.yaml | FileCheck %s -check-prefix=FUNC
61; FUNC: remark: <unknown>:0:0: Combine redundant instructions:
62; FUNC-SAME: IR instruction count changed from
63; FUNC-SAME: [[SIZE1:[1-9][0-9]*]] to [[SIZE2:[0-9][0-9]*]];
64; FUNC-SAME: Delta: [[DELTA1:-?[1-9][0-9]*]]
65; FUNC-NEXT: remark: <unknown>:0:0: Combine redundant instructions: Function:
66; FUNC-SAME: foo: IR instruction count changed from
67; FUNC-SAME: [[FOOSIZE1:[1-9][0-9]*]] to [[FOOSIZE2:[0-9][0-9]*]];
68; FUNC-SAME: Delta: [[DELTAFOO:-?[1-9][0-9]*]]
69; FUNC-NEXT: remark: <unknown>:0:0: Combine redundant instructions:
70; FUNC-SAME: IR instruction count changed from
71; FUNC-SAME: [[SIZE2]] to [[SIZE3:[1-9][0-9]*]];
72; FUNC-SAME: Delta: [[DELTA2:-?[1-9][0-9]*]]
73; FUNC-NEXT: remark: <unknown>:0:0: Combine redundant instructions: Function:
74; FUNC-SAME: bar: IR instruction count changed from
75; FUNC-SAME: [[BARSIZE1:[1-9][0-9]*]] to [[BARSIZE2:[0-9][0-9]*]];
76; FUNC-SAME: Delta: [[DELTABAR:-?[1-9][0-9]*]]
77; FUNC-NEXT: ---
78; FUNC-DAG: !Analysis
79; FUNC-NEXT: Pass:            size-info
80; FUNC-NEXT: Name:            IRSizeChange
81; FUNC-NEXT: Function:
82; FUNC-NEXT: Args:
83; FUNC-NEXT:  - Pass:            Combine redundant instructions
84; FUNC-NEXT:  - String:          ': IR instruction count changed from '
85; FUNC-NEXT:  - IRInstrsBefore:  '[[SIZE1]]'
86; FUNC-NEXT:  - String:          ' to '
87; FUNC-NEXT:  - IRInstrsAfter:   '[[SIZE2]]'
88; FUNC-NEXT:  - String:          '; Delta: '
89; FUNC-NEXT:  - DeltaInstrCount: '[[DELTA1]]'
90; FUNC-DAG: --- !Analysis
91; FUNC-NEXT: Pass:            size-info
92; FUNC-NEXT: Name:            FunctionIRSizeChange
93; FUNC-NEXT: Function:
94; FUNC-NEXT: Args:
95; FUNC-NEXT:   - Pass:            Combine redundant instructions
96; FUNC-NEXT:   - String:          ': Function: '
97; FUNC-NEXT:   - Function:        foo
98; FUNC-NEXT:   - String:          ': IR instruction count changed from '
99; FUNC-NEXT:   - IRInstrsBefore:  '[[FOOSIZE1]]'
100; FUNC-NEXT:   - String:          ' to '
101; FUNC-NEXT:   - IRInstrsAfter:   '[[FOOSIZE2]]'
102; FUNC-NEXT:   - String:          '; Delta: '
103; FUNC-NEXT:   - DeltaInstrCount: '[[DELTAFOO]]'
104; FUNC: --- !Analysis
105; FUNC-NEXT: Pass:            size-info
106; FUNC-NEXT: Name:            IRSizeChange
107; FUNC-NEXT: Function:
108; FUNC-NEXT: Args:
109; FUNC-NEXT:   - Pass:            Combine redundant instructions
110; FUNC-NEXT:   - String:          ': IR instruction count changed from '
111; FUNC-NEXT:   - IRInstrsBefore:  '[[SIZE2]]'
112; FUNC-NEXT:   - String:          ' to '
113; FUNC-NEXT:   - IRInstrsAfter:   '[[SIZE3]]'
114; FUNC-NEXT:   - String:          '; Delta: '
115; FUNC-NEXT:   - DeltaInstrCount: '[[DELTA2]]'
116; FUNC-DAG: --- !Analysis
117; FUNC-NEXT: Pass:            size-info
118; FUNC-NEXT: Name:            FunctionIRSizeChange
119; FUNC-NEXT: Function:
120; FUNC-NEXT: Args:
121; FUNC-NEXT:   - Pass:            Combine redundant instructions
122; FUNC-NEXT:   - String:          ': Function: '
123; FUNC-NEXT:   - Function:        bar
124; FUNC-NEXT:   - String:          ': IR instruction count changed from '
125; FUNC-NEXT:   - IRInstrsBefore:  '[[BARSIZE1]]'
126; FUNC-NEXT:   - String:          ' to '
127; FUNC-NEXT:   - IRInstrsAfter:   '[[BARSIZE2]]'
128; FUNC-NEXT:   - String:          '; Delta: '
129; FUNC-NEXT:   - DeltaInstrCount: '[[DELTABAR]]'
130
131; RUN: opt -enable-new-pm=0 < %s -globaldce -pass-remarks-analysis='size-info' \
132; RUN: -pass-remarks-output=%t.yaml -S -o /dev/null 2> %t; \
133; RUN: cat %t %t.yaml | FileCheck %s -check-prefix=MODULE
134; MODULE: remark:
135; MODULE-SAME: Dead Global Elimination:
136; MODULE-SAME: IR instruction count changed from
137; MODULE-SAME: [[ORIG:[1-9][0-9]*]] to [[FINAL:[1-9][0-9]*]];
138; MODULE-SAME: Delta: [[DELTA:-?[1-9][0-9]*]]
139; MODULE-NEXT: remark:
140; MODULE-SAME: Dead Global Elimination: Function: pluto:
141; MODULE-SAME: IR instruction count changed from [[ORIGFN:[1-9][0-9]*]] to
142; MODULE-SAME: [[FINALFN:[0-9][0-9]*]]; Delta: [[DELTAFN:-?[1-9][0-9]*]]
143; MODULE-NEXT: ---
144; MODULE-DAG: !Analysis
145; MODULE-NEXT: Pass:            size-info
146; MODULE-NEXT: Name:            IRSizeChange
147; MODULE-NEXT: Function:
148; MODULE-NEXT: Args:
149; MODULE-NEXT:   - Pass:            Dead Global Elimination
150; MODULE-NEXT:   - String:          ': IR instruction count changed from '
151; MODULE-NEXT:   - IRInstrsBefore:  '[[ORIG]]'
152; MODULE-NEXT:   - String:          ' to '
153; MODULE-NEXT:   - IRInstrsAfter:   '[[FINAL]]'
154; MODULE-NEXT:   - String:          '; Delta: '
155; MODULE-NEXT:   - DeltaInstrCount: '[[DELTA]]'
156; MODULE-DAG: --- !Analysis
157; MODULE-NEXT: Pass:            size-info
158; MODULE-NEXT: Name:            FunctionIRSizeChange
159; MODULE-NEXT: Function:
160; MODULE-NEXT: Args:
161; MODULE-NEXT:   - Pass:            Dead Global Elimination
162; MODULE-NEXT:   - String:          ': Function: '
163; MODULE-NEXT:   - Function:        pluto
164; MODULE-NEXT:   - String:          ': IR instruction count changed from '
165; MODULE-NEXT:   - IRInstrsBefore:  '[[ORIGFN]]'
166; MODULE-NEXT:   - String:          ' to '
167; MODULE-NEXT:   - IRInstrsAfter:   '[[FINALFN]]'
168; MODULE-NEXT:   - String:          '; Delta: '
169; MODULE-NEXT:   - DeltaInstrCount: '[[DELTAFN]]'
170
171; RUN: opt -enable-new-pm=0 < %s -dce -pass-remarks-analysis='size-info' \
172; RUN: -pass-remarks-output=%t.yaml -S -o /dev/null 2> %t; \
173; RUN: cat %t %t.yaml | FileCheck %s -check-prefix=BB
174; BB: remark: <unknown>:0:0: Dead Code Elimination:
175; BB-SAME: IR instruction count changed from
176; BB-SAME: [[ORIG:[1-9][0-9]*]] to [[FINAL:[1-9][0-9]*]];
177; BB-SAME: Delta: [[DELTA:-?[1-9][0-9]*]]
178; BB-NEXT: remark: <unknown>:0:0: Dead Code Elimination: Function: bar:
179; BB-SAME: IR instruction count changed from [[ORIGFN:[1-9][0-9]*]] to
180; BB-SAME: [[FINALFN:[0-9][0-9]*]]; Delta: [[DELTAFN:-?[1-9][0-9]*]]
181; BB-NEXT: ---
182; BB-DAG: !Analysis
183; BB-NEXT: Pass:            size-info
184; BB-NEXT: Name:            IRSizeChange
185; BB-NEXT: Function:
186; BB-NEXT: Args:
187; BB-NEXT:   - Pass:            Dead Code Elimination
188; BB-NEXT:   - String:          ': IR instruction count changed from '
189; BB-NEXT:   - IRInstrsBefore:  '[[ORIG]]'
190; BB-NEXT:   - String:          ' to '
191; BB-NEXT:   - IRInstrsAfter:   '[[FINAL]]'
192; BB-NEXT:   - String:          '; Delta: '
193; BB-NEXT:   - DeltaInstrCount: '[[DELTA]]'
194; BB-DAG: --- !Analysis
195; BB-NEXT: Pass:            size-info
196; BB-NEXT: Name:            FunctionIRSizeChange
197; BB-NEXT: Function:
198; BB-NEXT: Args:
199; BB-NEXT:   - Pass:            Dead Code Elimination
200; BB-NEXT:   - String:          ': Function: '
201; BB-NEXT:   - Function:        bar
202; BB-NEXT:   - String:          ': IR instruction count changed from '
203; BB-NEXT:   - IRInstrsBefore:  '[[ORIGFN]]'
204; BB-NEXT:   - String:          ' to '
205; BB-NEXT:   - IRInstrsAfter:   '[[FINALFN]]'
206; BB-NEXT:   - String:          '; Delta: '
207; BB-NEXT:   - DeltaInstrCount: '[[DELTAFN]]'
208
209; RUN: opt -enable-new-pm=0 < %s -loop-unroll -pass-remarks-analysis='size-info' \
210; RUN: -pass-remarks-output=%t.yaml -S -o /dev/null 2> %t; \
211; RUN: cat %t %t.yaml | FileCheck %s -check-prefix=LOOP
212; LOOP: remark: <unknown>:0:0: Unroll loops:
213; LOOP-SAME: IR instruction count changed from
214; LOOP-SAME: [[ORIG:[1-9][0-9]*]] to [[FINAL:[1-9][0-9]*]];
215; LOOP-SAME: Delta: [[DELTA:-?[1-9][0-9]*]]
216; LOOP-NEXT: remark: <unknown>:0:0: Unroll loops: Function: bar:
217; LOOP-SAME: IR instruction count changed from [[ORIGFN:[1-9][0-9]*]]
218; LOOP-SAME: to [[FINALFN:[0-9][0-9]*]];
219; Since bar is the only function containing a loop, its delta must be identical
220; to the whole module remark's delta.
221; LOOP-SAME: Delta: [[DELTA]]
222; LOOP-NEXT: ---
223; LOOP-DAG: !Analysis
224; LOOP-NEXT: Pass:            size-info
225; LOOP-NEXT: Name:            IRSizeChange
226; LOOP-NEXT: Function:
227; LOOP-NEXT: Args:
228; LOOP-DAG:   - Pass:            Unroll loops
229; LOOP-NEXT:   - String:          ': IR instruction count changed from '
230; LOOP-NEXT:   - IRInstrsBefore:  '[[ORIG]]'
231; LOOP-NEXT:   - String:          ' to '
232; LOOP-NEXT:   - IRInstrsAfter:   '[[FINAL]]'
233; LOOP-NEXT:   - String:          '; Delta: '
234; LOOP-NEXT:   - DeltaInstrCount: '[[DELTA]]'
235; LOOP-DAG: --- !Analysis
236; LOOP-NEXT: Pass:            size-info
237; LOOP-NEXT: Name:            FunctionIRSizeChange
238; LOOP-NEXT: Function:
239; LOOP-NEXT: Args:
240; LOOP-NEXT:   - Pass:            Unroll loops
241; LOOP-NEXT:   - String:          ': Function: '
242; LOOP-NEXT:   - Function:        bar
243; LOOP-NEXT:   - String:          ': IR instruction count changed from '
244; LOOP-NEXT:   - IRInstrsBefore:  '[[ORIGFN]]'
245; LOOP-NEXT:   - String:          ' to '
246; LOOP-NEXT:   - IRInstrsAfter:   '[[FINALFN]]'
247; LOOP-NEXT:   - String:          '; Delta: '
248; LOOP-NEXT:   - DeltaInstrCount: '[[DELTA]]'
249declare i1 ()* @boop()
250
251define internal i1 @pluto() {
252  %F = call i1 ()* () @boop( )
253  %c = icmp eq i1 ()* %F, @pluto
254  ret i1 %c
255}
256
257define i32 @foo(i32 %x) {
258entry:
259  %x.addr = alloca i32, align 4
260  store i32 %x, i32* %x.addr, align 4
261  %0 = load i32, i32* %x.addr, align 4
262  ret i32 %0
263}
264
265define i32 @bar(i32 %x) {
266entry:
267  %x.addr = alloca i32, align 4
268  store i32 %x, i32* %x.addr, align 4
269  %0 = load i32, i32* %x.addr, align 4
270  %call = call i32 @foo(i32 %0)
271  br label %for.body
272for.body:
273  %s.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
274  %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
275  %add = add nsw i32 %i.05, 4
276  %inc = add nsw i32 %i.05, 1
277  %exitcond = icmp eq i32 %inc, 16
278  br i1 %exitcond, label %for.end, label %for.body
279for.end:
280  ret i32 %add
281}
282