blob: f980340cbf9fab9d4218dd5c16b7d54768bbac4f [file] [log] [blame]
Robert Lougher2428a402016-12-14 17:49:19 +00001; RUN: opt -instcombine -S < %s | FileCheck %s
2
3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-unknown-linux-gnu"
5
6; If all the operands to a phi node are of the same operation, instcombine
7; will try to pull them through the phi node, combining them into a single
8; operation. Check that when it does this the combined operation does not
9; have a debug location set.
10
11; Test folding of a binary operation. Generated from source:
12
13; extern int foo(void);
14; extern int bar(void);
15;
16; int binop(int a, int b) {
17; if(a)
18; b -= foo();
19; else
20; b -= bar();
21; return b;
22; }
23
24; CHECK: define i32 @binop
25; CHECK-LABEL: if.end:
26; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
27; CHECK: sub nsw i32 %b, %[[PHI]]
28; CHECK-NOT: !dbg
29; CHECK: ret i32
30
31define i32 @binop(i32 %a, i32 %b) !dbg !6 {
32entry:
33 %tobool = icmp ne i32 %a, 0, !dbg !8
34 br i1 %tobool, label %if.then, label %if.else, !dbg !8
35
36if.then: ; preds = %entry
37 %call = call i32 @foo(), !dbg !9
38 %sub = sub nsw i32 %b, %call, !dbg !10
39 br label %if.end, !dbg !11
40
41if.else: ; preds = %entry
42 %call1 = call i32 @bar(), !dbg !12
43 %sub2 = sub nsw i32 %b, %call1, !dbg !13
44 br label %if.end
45
46if.end: ; preds = %if.else, %if.then
47 %b.addr.0 = phi i32 [ %sub, %if.then ], [ %sub2, %if.else ]
48 ret i32 %b.addr.0, !dbg !14
49}
50
Robert Lougher4b0790d2016-12-14 18:14:57 +000051; Test folding of a compare. Generated from source (with editing to
52; common the zext):
53
54; extern int foo(void);
55; extern int bar(void);
56;
57; int cmp(int a, int b) {
58; int r;
59; if(a)
60; r = foo() < b;
61; else
62; r = bar() < b;
63; return r;
64; }
65
66; CHECK: define i32 @cmp
67; CHECK-LABEL: if.end:
68; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
69; CHECK: icmp slt i32 %[[PHI]], %b
70; CHECK-NOT: !dbg
71; CHECK: ret i32
72
73define i32 @cmp(i32 %a, i32 %b) !dbg !15 {
74entry:
75 %tobool = icmp ne i32 %a, 0, !dbg !16
76 br i1 %tobool, label %if.then, label %if.else, !dbg !16
77
78if.then: ; preds = %entry
79 %call = call i32 @foo(), !dbg !17
80 %cmp = icmp slt i32 %call, %b, !dbg !18
81 br label %if.end, !dbg !19
82
83if.else: ; preds = %entry
84 %call1 = call i32 @bar(), !dbg !20
85 %cmp2 = icmp slt i32 %call1, %b, !dbg !21
86 br label %if.end
87
88if.end: ; preds = %if.else, %if.then
89 %r.0 = phi i1 [ %cmp, %if.then ], [ %cmp2, %if.else ]
90 %conv = zext i1 %r.0 to i32
91 ret i32 %conv, !dbg !22
92}
93
Robert Lougher8fc1e892016-12-14 18:37:50 +000094; Test folding of getelementptr. Generated from source:
95
96; extern long long foo2(void);
97; extern long long bar2(void);
98;
99; int *gep(int a, int *b) {
100; int *r;
101; if(a)
102; r = &b[foo2()];
103; else
104; r = &b[bar2()];
105; return p;
106; }
107
108; CHECK: define i32* @gep
109; CHECK-LABEL: if.end:
110; CHECK: %[[PHI:.*]] = phi i64 [ %call, %if.then ], [ %call1, %if.else ]
111; CHECK: getelementptr inbounds i32, i32* %b, i64 %[[PHI]]
112; CHECK-NOT: !dbg
113; CHECK: ret i32*
114
115define i32* @gep(i32 %a, i32* %b) !dbg !23 {
116entry:
117 %tobool = icmp ne i32 %a, 0, !dbg !24
118 br i1 %tobool, label %if.then, label %if.else, !dbg !24
119
120if.then: ; preds = %entry
121 %call = call i64 @foo2(), !dbg !25
122 %arrayidx = getelementptr inbounds i32, i32* %b, i64 %call, !dbg !26
123 br label %if.end, !dbg !27
124
125if.else: ; preds = %entry
126 %call1 = call i64 @bar2(), !dbg !28
127 %arrayidx2 = getelementptr inbounds i32, i32* %b, i64 %call1, !dbg !29
128 br label %if.end
129
130if.end: ; preds = %if.else, %if.then
131 %r.0 = phi i32* [ %arrayidx, %if.then ], [ %arrayidx2, %if.else ]
132 ret i32* %r.0, !dbg !30
133}
134
Robert Lougher373e36a2016-12-14 19:02:14 +0000135; Test folding of load. Generated from source:
136
137; extern int *foo3(void);
138; extern int *bar3(void);
139;
140; int load(int a) {
141; int r;
142; if(a)
143; r = *foo3();
144; else
145; r = *bar3();
146; return r;
147; }
148
149; CHECK: define i32 @load
150; CHECK-LABEL: if.end:
151; CHECK: %[[PHI:.*]] = phi i32* [ %call, %if.then ], [ %call1, %if.else ]
152; CHECK: load i32, i32* %[[PHI]]
153; CHECK-NOT: !dbg
154; CHECK: ret i32
155
156define i32 @load(i32 %a) !dbg !31 {
157entry:
158 %tobool = icmp ne i32 %a, 0, !dbg !32
159 br i1 %tobool, label %if.then, label %if.else, !dbg !32
160
161if.then: ; preds = %entry
162 %call = call i32* @foo3(), !dbg !33
163 %0 = load i32, i32* %call, align 4, !dbg !34
164 br label %if.end, !dbg !35
165
166if.else: ; preds = %entry
167 %call1 = call i32* @bar3(), !dbg !36
168 %1 = load i32, i32* %call1, align 4, !dbg !37
169 br label %if.end
170
171if.end: ; preds = %if.else, %if.then
172 %r.0 = phi i32 [ %0, %if.then ], [ %1, %if.else ]
173 ret i32 %r.0, !dbg !38
174}
175
Robert Lougherf02d9b82016-12-14 19:24:01 +0000176; Test folding of a cast. Generated from source:
177
178; extern int foo(void);
179; extern int bar(void);
180;
181; long long cast(int a) {
182; long long r;
183; if(a)
184; r = foo();
185; else
186; r = bar();
187; return r;
188; }
189
190; CHECK: define i64 @cast
191; CHECK-LABEL: if.end:
192; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
193; CHECK: sext i32 %[[PHI]] to i64
194; CHECK-NOT: !dbg
195; CHECK: ret i64
196
197define i64 @cast(i32 %a) !dbg !39 {
198entry:
199 %tobool = icmp ne i32 %a, 0, !dbg !40
200 br i1 %tobool, label %if.then, label %if.else, !dbg !40
201
202if.then: ; preds = %entry
203 %call = call i32 @foo(), !dbg !41
204 %conv = sext i32 %call to i64, !dbg !41
205 br label %if.end, !dbg !42
206
207if.else: ; preds = %entry
208 %call1 = call i32 @bar(), !dbg !43
209 %conv2 = sext i32 %call1 to i64, !dbg !43
210 br label %if.end
211
212if.end: ; preds = %if.else, %if.then
213 %r.0 = phi i64 [ %conv, %if.then ], [ %conv2, %if.else ]
214 ret i64 %r.0, !dbg !44
215}
216
Robert Lougherc9f73542016-12-14 20:07:49 +0000217; Test folding of a binary op with a RHS constant. Generated from source:
218
219; extern int foo(void);
220; extern int bar(void);
221;
222; int binop_const(int a) {
223; int r;
224; if(a)
225; r = foo() - 5;
226; else
227; r = bar() - 5;
228; return r;
229; }
230
231; CHECK: define i32 @binop_const
232; CHECK-LABEL: if.end:
233; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
234; CHECK: add nsw i32 %[[PHI]], -5
235; CHECK-NOT: !dbg
236; CHECK: ret i32
237
238define i32 @binop_const(i32 %a) !dbg !45 {
239entry:
240 %tobool = icmp ne i32 %a, 0, !dbg !46
241 br i1 %tobool, label %if.then, label %if.else, !dbg !46
242
243if.then: ; preds = %entry
244 %call = call i32 @foo(), !dbg !47
245 %sub = sub nsw i32 %call, 5, !dbg !48
246 br label %if.end, !dbg !49
247
248if.else: ; preds = %entry
249 %call1 = call i32 @bar(), !dbg !50
250 %sub2 = sub nsw i32 %call1, 5, !dbg !51
251 br label %if.end
252
253if.end: ; preds = %if.else, %if.then
254 %r.0 = phi i32 [ %sub, %if.then ], [ %sub2, %if.else ]
255 ret i32 %r.0, !dbg !52
256}
257
Robert Loughercfd71982016-12-14 20:27:22 +0000258; Test folding of a compare with RHS constant. Generated from source (with
259; editing to common the zext):
260
261; extern int foo(void);
262; extern int bar(void);
263;
264; int cmp_const(int a) {
265; int r;
266; if(a)
267; r = foo() < 10;
268; else
269; r = bar() < 10;
270; return r;
271; }
272
273; CHECK: define i32 @cmp_const
274; CHECK-LABEL: if.end:
275; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
276; CHECK: icmp slt i32 %[[PHI]], 10
277; CHECK-NOT: !dbg
278; CHECK: ret i32
279
280define i32 @cmp_const(i32 %a) !dbg !53 {
281entry:
282 %tobool = icmp ne i32 %a, 0, !dbg !54
283 br i1 %tobool, label %if.then, label %if.else, !dbg !54
284
285if.then: ; preds = %entry
286 %call = call i32 @foo(), !dbg !55
287 %cmp = icmp slt i32 %call, 10, !dbg !56
288 br label %if.end, !dbg !57
289
290if.else: ; preds = %entry
291 %call1 = call i32 @bar(), !dbg !58
292 %cmp2 = icmp slt i32 %call1, 10, !dbg !59
293 br label %if.end
294
295if.end: ; preds = %if.else, %if.then
296 %r.0 = phi i1 [ %cmp, %if.then ], [ %cmp2, %if.else ]
297 %conv = zext i1 %r.0 to i32
298 ret i32 %conv, !dbg !60
299}
300
Robert Lougher2428a402016-12-14 17:49:19 +0000301declare i32 @foo()
302declare i32 @bar()
Robert Lougher8fc1e892016-12-14 18:37:50 +0000303declare i64 @foo2()
304declare i64 @bar2()
Robert Lougher373e36a2016-12-14 19:02:14 +0000305declare i32* @foo3()
306declare i32* @bar3()
Robert Lougher2428a402016-12-14 17:49:19 +0000307
308!llvm.dbg.cu = !{!0}
309!llvm.module.flags = !{!3, !4}
310
311!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2)
312!1 = !DIFile(filename: "test.c", directory: "")
313!2 = !{}
314!3 = !{i32 2, !"Dwarf Version", i32 4}
315!4 = !{i32 2, !"Debug Info Version", i32 3}
316!6 = distinct !DISubprogram(name: "binop", scope: !1, file: !1, line: 8, type: !7, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
317!7 = !DISubroutineType(types: !2)
318!8 = !DILocation(line: 9, column: 6, scope: !6)
319!9 = !DILocation(line: 10, column: 10, scope: !6)
320!10 = !DILocation(line: 10, column: 7, scope: !6)
321!11 = !DILocation(line: 10, column: 5, scope: !6)
322!12 = !DILocation(line: 12, column: 10, scope: !6)
323!13 = !DILocation(line: 12, column: 7, scope: !6)
324!14 = !DILocation(line: 13, column: 3, scope: !6)
Robert Lougher4b0790d2016-12-14 18:14:57 +0000325!15 = distinct !DISubprogram(name: "cmp", scope: !1, file: !1, line: 16, type: !7, isLocal: false, isDefinition: true, scopeLine: 16, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
326!16 = !DILocation(line: 18, column: 6, scope: !15)
327!17 = !DILocation(line: 19, column: 9, scope: !15)
328!18 = !DILocation(line: 19, column: 15, scope: !15)
329!19 = !DILocation(line: 19, column: 5, scope: !15)
330!20 = !DILocation(line: 21, column: 9, scope: !15)
331!21 = !DILocation(line: 21, column: 15, scope: !15)
332!22 = !DILocation(line: 22, column: 3, scope: !15)
Robert Lougher8fc1e892016-12-14 18:37:50 +0000333!23 = distinct !DISubprogram(name: "gep", scope: !1, file: !1, line: 25, type: !7, isLocal: false, isDefinition: true, scopeLine: 25, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
334!24 = !DILocation(line: 27, column: 6, scope: !23)
335!25 = !DILocation(line: 28, column: 12, scope: !23)
336!26 = !DILocation(line: 28, column: 10, scope: !23)
337!27 = !DILocation(line: 28, column: 5, scope: !23)
338!28 = !DILocation(line: 30, column: 12, scope: !23)
339!29 = !DILocation(line: 30, column: 10, scope: !23)
340!30 = !DILocation(line: 31, column: 3, scope: !23)
Robert Lougher373e36a2016-12-14 19:02:14 +0000341!31 = distinct !DISubprogram(name: "load", scope: !1, file: !1, line: 34, type: !7, isLocal: false, isDefinition: true, scopeLine: 34, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
342!32 = !DILocation(line: 36, column: 6, scope: !31)
343!33 = !DILocation(line: 37, column: 10, scope: !31)
344!34 = !DILocation(line: 37, column: 9, scope: !31)
345!35 = !DILocation(line: 37, column: 5, scope: !31)
346!36 = !DILocation(line: 39, column: 10, scope: !31)
347!37 = !DILocation(line: 39, column: 9, scope: !31)
348!38 = !DILocation(line: 40, column: 3, scope: !31)
Robert Lougherf02d9b82016-12-14 19:24:01 +0000349!39 = distinct !DISubprogram(name: "cast", scope: !1, file: !1, line: 43, type: !7, isLocal: false, isDefinition: true, scopeLine: 43, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
350!40 = !DILocation(line: 45, column: 6, scope: !39)
351!41 = !DILocation(line: 46, column: 9, scope: !39)
352!42 = !DILocation(line: 46, column: 5, scope: !39)
353!43 = !DILocation(line: 48, column: 9, scope: !39)
354!44 = !DILocation(line: 49, column: 3, scope: !39)
Robert Lougherc9f73542016-12-14 20:07:49 +0000355!45 = distinct !DISubprogram(name: "binop_const", scope: !1, file: !1, line: 52, type: !7, isLocal: false, isDefinition: true, scopeLine: 52, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
356!46 = !DILocation(line: 54, column: 6, scope: !45)
357!47 = !DILocation(line: 55, column: 9, scope: !45)
358!48 = !DILocation(line: 55, column: 15, scope: !45)
359!49 = !DILocation(line: 55, column: 5, scope: !45)
360!50 = !DILocation(line: 57, column: 9, scope: !45)
361!51 = !DILocation(line: 57, column: 15, scope: !45)
362!52 = !DILocation(line: 58, column: 3, scope: !45)
Robert Loughercfd71982016-12-14 20:27:22 +0000363!53 = distinct !DISubprogram(name: "cmp_const", scope: !1, file: !1, line: 61, type: !7, isLocal: false, isDefinition: true, scopeLine: 61, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
364!54 = !DILocation(line: 63, column: 6, scope: !53)
365!55 = !DILocation(line: 64, column: 9, scope: !53)
366!56 = !DILocation(line: 64, column: 15, scope: !53)
367!57 = !DILocation(line: 64, column: 5, scope: !53)
368!58 = !DILocation(line: 66, column: 9, scope: !53)
369!59 = !DILocation(line: 66, column: 15, scope: !53)
370!60 = !DILocation(line: 67, column: 3, scope: !53)