1 ; RUN: opt < %s -S -loop-unroll -unroll-force-peel-count=3 -verify-dom-info -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -instcombine | FileCheck %s
2 ; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop-unroll,simplifycfg,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>,simplifycfg,instcombine' -unroll-force-peel-count=3 -verify-dom-info | FileCheck %s
5 ; Basic loop peeling - check that we can peel-off the first 3 loop iterations
6 ; when explicitly requested.
8 ; CHECK: %[[CMP0:.*]] = icmp sgt i32 %k, 0
9 ; CHECK: br i1 %[[CMP0]], label %[[NEXT0:.*]], label %for.end
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]*}}
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]*}}
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 !{{.*}}
34 define void @basic(i32* %p, i32 %k) #0 {
36 %cmp3 = icmp slt i32 0, %k
37 br i1 %cmp3, label %for.body.lr.ph, label %for.end
39 for.body.lr.ph: ; preds = %entry
42 for.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
51 for.cond.for.end_crit_edge: ; preds = %for.body
54 for.end: ; preds = %for.cond.for.end_crit_edge, %entry
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
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]*}}
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]*}}
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 !{{.*}}
88 ; CHECK: %ret = phi i32 [ 0, %entry ], [ 1, %[[NEXT0]] ], [ 2, %[[NEXT1]] ], [ 3, %[[NEXT2]] ], [ %inc, %for.body ]
90 define i32 @output(i32* %p, i32 %k) #0 {
92 %cmp3 = icmp slt i32 0, %k
93 br i1 %cmp3, label %for.body.lr.ph, label %for.end
95 for.body.lr.ph: ; preds = %entry
98 for.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
107 for.cond.for.end_crit_edge: ; preds = %for.body
110 for.end: ; preds = %for.cond.for.end_crit_edge, %entry
111 %ret = phi i32 [ 0, %entry], [ %inc, %for.cond.for.end_crit_edge ]