[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnroll / pr45939-peel-count-and-complete-unroll.ll
blob654b94c2434d69edd58dd80a2e8a0b87b18388fb
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -loop-unroll -unroll-peel-count=2 -S %s | FileCheck --check-prefix=PEEL2 %s
3 ; RUN: opt -loop-unroll -unroll-peel-count=8 -S %s | FileCheck --check-prefix=PEEL8 %s
5 ; Test case for PR45939. Make sure unroll count is adjusted when loop is peeled and unrolled.
7 @a = global [8 x i32] zeroinitializer, align 16
9 define void @test1() {
10 ; PEEL2-LABEL: @test1(
11 ; PEEL2-NEXT:  entry:
12 ; PEEL2-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]
13 ; PEEL2:       for.body.peel.begin:
14 ; PEEL2-NEXT:    br label [[FOR_BODY_PEEL:%.*]]
15 ; PEEL2:       for.body.peel:
16 ; PEEL2-NEXT:    [[ARRAYIDX_PEEL:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 0
17 ; PEEL2-NEXT:    [[TMP0:%.*]] = trunc i64 0 to i32
18 ; PEEL2-NEXT:    store i32 [[TMP0]], i32* [[ARRAYIDX_PEEL]], align 4
19 ; PEEL2-NEXT:    [[INDVARS_IV_NEXT_PEEL:%.*]] = add nuw nsw i64 0, 1
20 ; PEEL2-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL]], 8
21 ; PEEL2-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_EXIT:%.*]]
22 ; PEEL2:       for.body.peel.next:
23 ; PEEL2-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]
24 ; PEEL2:       for.body.peel2:
25 ; PEEL2-NEXT:    [[ARRAYIDX_PEEL3:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL]]
26 ; PEEL2-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL]] to i32
27 ; PEEL2-NEXT:    store i32 [[TMP1]], i32* [[ARRAYIDX_PEEL3]], align 4
28 ; PEEL2-NEXT:    [[INDVARS_IV_NEXT_PEEL4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL]], 1
29 ; PEEL2-NEXT:    [[EXITCOND_PEEL5:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL4]], 8
30 ; PEEL2-NEXT:    br i1 [[EXITCOND_PEEL5]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_EXIT]]
31 ; PEEL2:       for.body.peel.next1:
32 ; PEEL2-NEXT:    br label [[FOR_BODY_PEEL_NEXT6:%.*]]
33 ; PEEL2:       for.body.peel.next6:
34 ; PEEL2-NEXT:    br label [[ENTRY_PEEL_NEWPH:%.*]]
35 ; PEEL2:       entry.peel.newph:
36 ; PEEL2-NEXT:    br label [[FOR_BODY:%.*]]
37 ; PEEL2:       for.body:
38 ; PEEL2-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PEEL4]], [[ENTRY_PEEL_NEWPH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
39 ; PEEL2-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV]]
40 ; PEEL2-NEXT:    [[TMP2:%.*]] = trunc i64 [[INDVARS_IV]] to i32
41 ; PEEL2-NEXT:    store i32 [[TMP2]], i32* [[ARRAYIDX]], align 4
42 ; PEEL2-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
43 ; PEEL2-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 8
44 ; PEEL2-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
45 ; PEEL2:       for.exit.loopexit:
46 ; PEEL2-NEXT:    br label [[FOR_EXIT]]
47 ; PEEL2:       for.exit:
48 ; PEEL2-NEXT:    ret void
50 ; PEEL8-LABEL: @test1(
51 ; PEEL8-NEXT:  entry:
52 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]
53 ; PEEL8:       for.body.peel.begin:
54 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL:%.*]]
55 ; PEEL8:       for.body.peel:
56 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 0
57 ; PEEL8-NEXT:    [[TMP0:%.*]] = trunc i64 0 to i32
58 ; PEEL8-NEXT:    store i32 [[TMP0]], i32* [[ARRAYIDX_PEEL]], align 4
59 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL:%.*]] = add nuw nsw i64 0, 1
60 ; PEEL8-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL]], 8
61 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_EXIT:%.*]]
62 ; PEEL8:       for.body.peel.next:
63 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]
64 ; PEEL8:       for.body.peel2:
65 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL3:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL]]
66 ; PEEL8-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL]] to i32
67 ; PEEL8-NEXT:    store i32 [[TMP1]], i32* [[ARRAYIDX_PEEL3]], align 4
68 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL]], 1
69 ; PEEL8-NEXT:    [[EXITCOND_PEEL5:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL4]], 8
70 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL5]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_EXIT]]
71 ; PEEL8:       for.body.peel.next1:
72 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL7:%.*]]
73 ; PEEL8:       for.body.peel7:
74 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL8:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL4]]
75 ; PEEL8-NEXT:    [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL4]] to i32
76 ; PEEL8-NEXT:    store i32 [[TMP2]], i32* [[ARRAYIDX_PEEL8]], align 4
77 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL9:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL4]], 1
78 ; PEEL8-NEXT:    [[EXITCOND_PEEL10:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL9]], 8
79 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL10]], label [[FOR_BODY_PEEL_NEXT6:%.*]], label [[FOR_EXIT]]
80 ; PEEL8:       for.body.peel.next6:
81 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL12:%.*]]
82 ; PEEL8:       for.body.peel12:
83 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL13:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL9]]
84 ; PEEL8-NEXT:    [[TMP3:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL9]] to i32
85 ; PEEL8-NEXT:    store i32 [[TMP3]], i32* [[ARRAYIDX_PEEL13]], align 4
86 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL14:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL9]], 1
87 ; PEEL8-NEXT:    [[EXITCOND_PEEL15:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL14]], 8
88 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL15]], label [[FOR_BODY_PEEL_NEXT11:%.*]], label [[FOR_EXIT]]
89 ; PEEL8:       for.body.peel.next11:
90 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL17:%.*]]
91 ; PEEL8:       for.body.peel17:
92 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL18:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL14]]
93 ; PEEL8-NEXT:    [[TMP4:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL14]] to i32
94 ; PEEL8-NEXT:    store i32 [[TMP4]], i32* [[ARRAYIDX_PEEL18]], align 4
95 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL19:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL14]], 1
96 ; PEEL8-NEXT:    [[EXITCOND_PEEL20:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL19]], 8
97 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL20]], label [[FOR_BODY_PEEL_NEXT16:%.*]], label [[FOR_EXIT]]
98 ; PEEL8:       for.body.peel.next16:
99 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL22:%.*]]
100 ; PEEL8:       for.body.peel22:
101 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL23:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL19]]
102 ; PEEL8-NEXT:    [[TMP5:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL19]] to i32
103 ; PEEL8-NEXT:    store i32 [[TMP5]], i32* [[ARRAYIDX_PEEL23]], align 4
104 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL24:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL19]], 1
105 ; PEEL8-NEXT:    [[EXITCOND_PEEL25:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL24]], 8
106 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL25]], label [[FOR_BODY_PEEL_NEXT21:%.*]], label [[FOR_EXIT]]
107 ; PEEL8:       for.body.peel.next21:
108 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL27:%.*]]
109 ; PEEL8:       for.body.peel27:
110 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL28:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL24]]
111 ; PEEL8-NEXT:    [[TMP6:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL24]] to i32
112 ; PEEL8-NEXT:    store i32 [[TMP6]], i32* [[ARRAYIDX_PEEL28]], align 4
113 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL29:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL24]], 1
114 ; PEEL8-NEXT:    [[EXITCOND_PEEL30:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL29]], 8
115 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL30]], label [[FOR_BODY_PEEL_NEXT26:%.*]], label [[FOR_EXIT]]
116 ; PEEL8:       for.body.peel.next26:
117 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL32:%.*]]
118 ; PEEL8:       for.body.peel32:
119 ; PEEL8-NEXT:    [[ARRAYIDX_PEEL33:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL29]]
120 ; PEEL8-NEXT:    [[TMP7:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL29]] to i32
121 ; PEEL8-NEXT:    store i32 [[TMP7]], i32* [[ARRAYIDX_PEEL33]], align 4
122 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT_PEEL34:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL29]], 1
123 ; PEEL8-NEXT:    [[EXITCOND_PEEL35:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL34]], 8
124 ; PEEL8-NEXT:    br i1 [[EXITCOND_PEEL35]], label [[FOR_BODY_PEEL_NEXT31:%.*]], label [[FOR_EXIT]]
125 ; PEEL8:       for.body.peel.next31:
126 ; PEEL8-NEXT:    br label [[FOR_BODY_PEEL_NEXT36:%.*]]
127 ; PEEL8:       for.body.peel.next36:
128 ; PEEL8-NEXT:    br label [[ENTRY_PEEL_NEWPH:%.*]]
129 ; PEEL8:       entry.peel.newph:
130 ; PEEL8-NEXT:    br label [[FOR_BODY:%.*]]
131 ; PEEL8:       for.body:
132 ; PEEL8-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PEEL34]], [[ENTRY_PEEL_NEWPH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
133 ; PEEL8-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV]]
134 ; PEEL8-NEXT:    [[TMP8:%.*]] = trunc i64 [[INDVARS_IV]] to i32
135 ; PEEL8-NEXT:    store i32 [[TMP8]], i32* [[ARRAYIDX]], align 4
136 ; PEEL8-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
137 ; PEEL8-NEXT:    br i1 true, label [[FOR_BODY]], label [[FOR_EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
138 ; PEEL8:       for.exit.loopexit:
139 ; PEEL8-NEXT:    br label [[FOR_EXIT]]
140 ; PEEL8:       for.exit:
141 ; PEEL8-NEXT:    ret void
143 entry:
144   br label %for.body
146 for.body:                                         ; preds = %entry, %for.body
147   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
148   %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 %indvars.iv
149   %0 = trunc i64 %indvars.iv to i32
150   store i32 %0, i32* %arrayidx, align 4
151   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
152   %exitcond = icmp ne i64 %indvars.iv.next, 8
153   br i1 %exitcond, label %for.body, label %for.exit
155 for.exit:                        ; preds = %for.body
156   ret void