• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -S -loop-unroll -unroll-force-peel-count=3 -verify-dom-info -simplifycfg -instcombine | FileCheck %s
2; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop-unroll,simplify-cfg,instcombine' -unroll-force-peel-count=3 -verify-dom-info | FileCheck %s
3; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop-unroll<peeling;no-runtime>,simplify-cfg,instcombine' -unroll-force-peel-count=3 -verify-dom-info | FileCheck %s
4
5; Basic loop peeling - check that we can peel-off the first 3 loop iterations
6; when explicitly requested.
7; CHECK-LABEL: @basic
8; CHECK: %[[CMP0:.*]] = icmp sgt i32 %k, 0
9; CHECK: br i1 %[[CMP0]], label %[[NEXT0:.*]], label %for.end
10; CHECK: [[NEXT0]]:
11; CHECK: store i32 0, i32* %p, align 4
12; CHECK: %[[CMP1:.*]] = icmp eq i32 %k, 1
13; CHECK: br i1 %[[CMP1]], label %for.end, label %[[NEXT1:[^,]*]]
14; Verify that MD_loop metadata is dropped.
15; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}
16; CHECK: [[NEXT1]]:
17; CHECK: %[[INC1:.*]] = getelementptr inbounds i32, i32* %p, i64 1
18; CHECK: store i32 1, i32* %[[INC1]], align 4
19; CHECK: %[[CMP2:.*]] = icmp sgt i32 %k, 2
20; CHECK: br i1 %[[CMP2]], label %[[NEXT2:.*]], label %for.end
21; Verify that MD_loop metadata is dropped.
22; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}
23; CHECK: [[NEXT2]]:
24; CHECK: %[[INC2:.*]] = getelementptr inbounds i32, i32* %p, i64 2
25; CHECK: store i32 2, i32* %[[INC2]], align 4
26; CHECK: %[[CMP3:.*]] = icmp eq i32 %k, 3
27; CHECK: br i1 %[[CMP3]], label %for.end, label %[[LOOP_PH:[^,]*]]
28; Verify that MD_loop metadata is dropped.
29; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}
30; CHECK: br i1 %[[CMP4:.*]], label %[[LOOP_PH]], label %for.end, !llvm.loop !{{.*}}
31; CHECK: for.end:
32; CHECK: ret void
33
34define void @basic(i32* %p, i32 %k) #0 {
35entry:
36  %cmp3 = icmp slt i32 0, %k
37  br i1 %cmp3, label %for.body.lr.ph, label %for.end
38
39for.body.lr.ph:                                   ; preds = %entry
40  br label %for.body
41
42for.body:                                         ; preds = %for.body.lr.ph, %for.body
43  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
44  %p.addr.04 = phi i32* [ %p, %for.body.lr.ph ], [ %incdec.ptr, %for.body ]
45  %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.04, i32 1
46  store i32 %i.05, i32* %p.addr.04, align 4
47  %inc = add nsw i32 %i.05, 1
48  %cmp = icmp slt i32 %inc, %k
49  br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge, !llvm.loop !1
50
51for.cond.for.end_crit_edge:                       ; preds = %for.body
52  br label %for.end
53
54for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
55  ret void
56}
57
58!1 = distinct !{!1}
59
60; Make sure peeling works correctly when a value defined in a loop is used
61; in later code - we need to correctly plumb the phi depending on which
62; iteration is actually used.
63; CHECK-LABEL: @output
64; CHECK: %[[CMP0:.*]] = icmp sgt i32 %k, 0
65; CHECK: br i1 %[[CMP0]], label %[[NEXT0:.*]], label %for.end
66; CHECK: [[NEXT0]]:
67; CHECK: store i32 0, i32* %p, align 4
68; CHECK: %[[CMP1:.*]] = icmp eq i32 %k, 1
69; CHECK: br i1 %[[CMP1]], label %for.end, label %[[NEXT1:[^,]*]]
70; Verify that MD_loop metadata is dropped.
71; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}
72; CHECK: [[NEXT1]]:
73; CHECK: %[[INC1:.*]] = getelementptr inbounds i32, i32* %p, i64 1
74; CHECK: store i32 1, i32* %[[INC1]], align 4
75; CHECK: %[[CMP2:.*]] = icmp sgt i32 %k, 2
76; CHECK: br i1 %[[CMP2]], label %[[NEXT2:.*]], label %for.end
77; Verify that MD_loop metadata is dropped.
78; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}
79; CHECK: [[NEXT2]]:
80; CHECK: %[[INC2:.*]] = getelementptr inbounds i32, i32* %p, i64 2
81; CHECK: store i32 2, i32* %[[INC2]], align 4
82; CHECK: %[[CMP3:.*]] = icmp eq i32 %k, 3
83; CHECK: br i1 %[[CMP3]], label %for.end, label %[[LOOP_PH:[^,]*]]
84; Verify that MD_loop metadata is dropped.
85; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}
86; CHECK: br i1 %[[CMP4:.*]], label %[[LOOP_PH]], label %for.end, !llvm.loop !{{.*}}
87; CHECK: for.end:
88; CHECK: %ret = phi i32 [ 0, %entry ], [ 1, %[[NEXT0]] ], [ 2, %[[NEXT1]] ], [ 3, %[[NEXT2]] ], [ %inc, %for.body ]
89; CHECK: ret i32 %ret
90define i32 @output(i32* %p, i32 %k) #0 {
91entry:
92  %cmp3 = icmp slt i32 0, %k
93  br i1 %cmp3, label %for.body.lr.ph, label %for.end
94
95for.body.lr.ph:                                   ; preds = %entry
96  br label %for.body
97
98for.body:                                         ; preds = %for.body.lr.ph, %for.body
99  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
100  %p.addr.04 = phi i32* [ %p, %for.body.lr.ph ], [ %incdec.ptr, %for.body ]
101  %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.04, i32 1
102  store i32 %i.05, i32* %p.addr.04, align 4
103  %inc = add nsw i32 %i.05, 1
104  %cmp = icmp slt i32 %inc, %k
105  br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge, !llvm.loop !2
106
107for.cond.for.end_crit_edge:                       ; preds = %for.body
108  br label %for.end
109
110for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
111  %ret = phi i32 [ 0, %entry], [ %inc, %for.cond.for.end_crit_edge ]
112  ret i32 %ret
113}
114
115!2 = distinct !{!2}
116