xref: /llvm-project/llvm/test/Transforms/LoopVectorize/X86/fixed-order-recurrence.ll (revision 7f3428d3ed71d87a2088b77b6cab9f3d86544234)
1e29f9f75SDavid Green; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2c48a1ebeSFlorian Hahn; RUN: opt -passes=loop-vectorize -S -o - %s  | FileCheck %s
3e29f9f75SDavid Green
4e29f9f75SDavid Greentarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5e29f9f75SDavid Greentarget triple = "x86_64-pc_linux"
6e29f9f75SDavid Green
7e29f9f75SDavid Greendefine void @firstorderrec(ptr nocapture noundef readonly %x, ptr noalias nocapture noundef writeonly %y, i32 noundef %n) {
8e29f9f75SDavid Green; CHECK-LABEL: @firstorderrec(
9e29f9f75SDavid Green; CHECK-NEXT:  entry:
10e29f9f75SDavid Green; CHECK-NEXT:    [[CMP18:%.*]] = icmp sgt i32 [[N:%.*]], 1
11e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[CMP18]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
12e29f9f75SDavid Green; CHECK:       for.body.preheader:
13e29f9f75SDavid Green; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N]] to i64
14e29f9f75SDavid Green; CHECK-NEXT:    [[DOTPRE:%.*]] = load i8, ptr [[X:%.*]], align 1
15e29f9f75SDavid Green; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i64 [[WIDE_TRIP_COUNT]], -1
16e29f9f75SDavid Green; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 32
17e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
18e29f9f75SDavid Green; CHECK:       vector.ph:
19e29f9f75SDavid Green; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 32
20e29f9f75SDavid Green; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
21e29f9f75SDavid Green; CHECK-NEXT:    [[IND_END:%.*]] = add i64 1, [[N_VEC]]
22e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR_INIT:%.*]] = insertelement <16 x i8> poison, i8 [[DOTPRE]], i32 15
23e29f9f75SDavid Green; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
24e29f9f75SDavid Green; CHECK:       vector.body:
25e29f9f75SDavid Green; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
26e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR:%.*]] = phi <16 x i8> [ [[VECTOR_RECUR_INIT]], [[VECTOR_PH]] ], [ [[WIDE_LOAD1:%.*]], [[VECTOR_BODY]] ]
27e29f9f75SDavid Green; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[INDEX]]
28e29f9f75SDavid Green; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
29e29f9f75SDavid Green; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[TMP1]]
30e29f9f75SDavid Green; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0
31e29f9f75SDavid Green; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 16
32f18536d6SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[TMP5]], align 1
33e29f9f75SDavid Green; CHECK-NEXT:    [[WIDE_LOAD1]] = load <16 x i8>, ptr [[TMP6]], align 1
34e29f9f75SDavid Green; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <16 x i8> [[VECTOR_RECUR]], <16 x i8> [[WIDE_LOAD]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
35e29f9f75SDavid Green; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <16 x i8> [[WIDE_LOAD]], <16 x i8> [[WIDE_LOAD1]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
36e29f9f75SDavid Green; CHECK-NEXT:    [[TMP9:%.*]] = add <16 x i8> [[WIDE_LOAD]], [[TMP7]]
37e29f9f75SDavid Green; CHECK-NEXT:    [[TMP10:%.*]] = add <16 x i8> [[WIDE_LOAD1]], [[TMP8]]
38e29f9f75SDavid Green; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 [[TMP1]]
39e29f9f75SDavid Green; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[TMP11]], i32 0
40e29f9f75SDavid Green; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[TMP11]], i32 16
41f18536d6SFlorian Hahn; CHECK-NEXT:    store <16 x i8> [[TMP9]], ptr [[TMP13]], align 1
42e29f9f75SDavid Green; CHECK-NEXT:    store <16 x i8> [[TMP10]], ptr [[TMP14]], align 1
43e29f9f75SDavid Green; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32
44e29f9f75SDavid Green; CHECK-NEXT:    [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
45e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[TMP15]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
46e29f9f75SDavid Green; CHECK:       middle.block:
473808ba78SFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <16 x i8> [[WIDE_LOAD1]], i32 15
4899d6c6d9SFlorian Hahn; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
49e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[SCALAR_PH]]
50e29f9f75SDavid Green; CHECK:       scalar.ph:
519a5a8731SFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i8 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ [[DOTPRE]], [[FOR_BODY_PREHEADER]] ]
52*7f3428d3SFlorian Hahn; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 1, [[FOR_BODY_PREHEADER]] ]
53e29f9f75SDavid Green; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
54e29f9f75SDavid Green; CHECK:       for.cond.cleanup.loopexit:
55e29f9f75SDavid Green; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
56e29f9f75SDavid Green; CHECK:       for.cond.cleanup:
57e29f9f75SDavid Green; CHECK-NEXT:    ret void
58e29f9f75SDavid Green; CHECK:       for.body:
59c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP16:%.*]] = phi i8 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[TMP17:%.*]], [[FOR_BODY]] ]
60e29f9f75SDavid Green; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
61e29f9f75SDavid Green; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[INDVARS_IV]]
62c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP17]] = load i8, ptr [[ARRAYIDX4]], align 1
63c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[ADD7:%.*]] = add i8 [[TMP17]], [[TMP16]]
64e29f9f75SDavid Green; CHECK-NEXT:    [[ARRAYIDX10:%.*]] = getelementptr inbounds i8, ptr [[Y]], i64 [[INDVARS_IV]]
65e29f9f75SDavid Green; CHECK-NEXT:    store i8 [[ADD7]], ptr [[ARRAYIDX10]], align 1
66e29f9f75SDavid Green; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
67e29f9f75SDavid Green; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
6835af27c3SFlorian Hahn; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
69e29f9f75SDavid Green;
70e29f9f75SDavid Greenentry:
71e29f9f75SDavid Green  %cmp18 = icmp sgt i32 %n, 1
72e29f9f75SDavid Green  br i1 %cmp18, label %for.body.preheader, label %for.cond.cleanup
73e29f9f75SDavid Green
74e29f9f75SDavid Greenfor.body.preheader:                               ; preds = %entry
75e29f9f75SDavid Green  %wide.trip.count = zext i32 %n to i64
76e29f9f75SDavid Green  %.pre = load i8, ptr %x, align 1
77e29f9f75SDavid Green  br label %for.body
78e29f9f75SDavid Green
79e29f9f75SDavid Greenfor.cond.cleanup:                                 ; preds = %for.body, %entry
80e29f9f75SDavid Green  ret void
81e29f9f75SDavid Green
82e29f9f75SDavid Greenfor.body:                                         ; preds = %for.body.preheader, %for.body
83e29f9f75SDavid Green  %0 = phi i8 [ %.pre, %for.body.preheader ], [ %1, %for.body ]
84e29f9f75SDavid Green  %indvars.iv = phi i64 [ 1, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
85e29f9f75SDavid Green  %arrayidx4 = getelementptr inbounds i8, ptr %x, i64 %indvars.iv
86e29f9f75SDavid Green  %1 = load i8, ptr %arrayidx4, align 1
87e29f9f75SDavid Green  %add7 = add i8 %1, %0
88e29f9f75SDavid Green  %arrayidx10 = getelementptr inbounds i8, ptr %y, i64 %indvars.iv
89e29f9f75SDavid Green  store i8 %add7, ptr %arrayidx10, align 1
90e29f9f75SDavid Green  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
91e29f9f75SDavid Green  %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
92e29f9f75SDavid Green  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
93e29f9f75SDavid Green}
94e29f9f75SDavid Green
95e29f9f75SDavid Greendefine void @thirdorderrec(ptr nocapture noundef readonly %x, ptr noalias nocapture noundef writeonly %y, i32 noundef %n) #0 {
96e29f9f75SDavid Green; CHECK-LABEL: @thirdorderrec(
97e29f9f75SDavid Green; CHECK-NEXT:  entry:
98e29f9f75SDavid Green; CHECK-NEXT:    [[CMP38:%.*]] = icmp sgt i32 [[N:%.*]], 3
99e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[CMP38]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
100e29f9f75SDavid Green; CHECK:       for.body.preheader:
101e29f9f75SDavid Green; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N]] to i64
102e29f9f75SDavid Green; CHECK-NEXT:    [[DOTPRE:%.*]] = load i8, ptr [[X:%.*]], align 1
103e29f9f75SDavid Green; CHECK-NEXT:    [[ARRAYIDX5_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 1
104e29f9f75SDavid Green; CHECK-NEXT:    [[DOTPRE44:%.*]] = load i8, ptr [[ARRAYIDX5_PHI_TRANS_INSERT]], align 1
105e29f9f75SDavid Green; CHECK-NEXT:    [[ARRAYIDX12_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 2
106e29f9f75SDavid Green; CHECK-NEXT:    [[DOTPRE45:%.*]] = load i8, ptr [[ARRAYIDX12_PHI_TRANS_INSERT]], align 1
107e29f9f75SDavid Green; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i64 [[WIDE_TRIP_COUNT]], -3
108e29f9f75SDavid Green; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 32
109e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
110e29f9f75SDavid Green; CHECK:       vector.ph:
111e29f9f75SDavid Green; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 32
112e29f9f75SDavid Green; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
113e29f9f75SDavid Green; CHECK-NEXT:    [[IND_END:%.*]] = add i64 3, [[N_VEC]]
114e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR_INIT:%.*]] = insertelement <16 x i8> poison, i8 [[DOTPRE45]], i32 15
115e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR_INIT1:%.*]] = insertelement <16 x i8> poison, i8 [[DOTPRE44]], i32 15
116e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR_INIT3:%.*]] = insertelement <16 x i8> poison, i8 [[DOTPRE]], i32 15
117e29f9f75SDavid Green; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
118e29f9f75SDavid Green; CHECK:       vector.body:
119e29f9f75SDavid Green; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
120e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR:%.*]] = phi <16 x i8> [ [[VECTOR_RECUR_INIT]], [[VECTOR_PH]] ], [ [[WIDE_LOAD5:%.*]], [[VECTOR_BODY]] ]
121e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR2:%.*]] = phi <16 x i8> [ [[VECTOR_RECUR_INIT1]], [[VECTOR_PH]] ], [ [[TMP8:%.*]], [[VECTOR_BODY]] ]
122e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR4:%.*]] = phi <16 x i8> [ [[VECTOR_RECUR_INIT3]], [[VECTOR_PH]] ], [ [[TMP10:%.*]], [[VECTOR_BODY]] ]
123e29f9f75SDavid Green; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX]]
124e29f9f75SDavid Green; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
125e29f9f75SDavid Green; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[TMP1]]
126e29f9f75SDavid Green; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0
127e29f9f75SDavid Green; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 16
128f18536d6SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[TMP5]], align 1
129e29f9f75SDavid Green; CHECK-NEXT:    [[WIDE_LOAD5]] = load <16 x i8>, ptr [[TMP6]], align 1
130e29f9f75SDavid Green; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <16 x i8> [[VECTOR_RECUR]], <16 x i8> [[WIDE_LOAD]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
131e29f9f75SDavid Green; CHECK-NEXT:    [[TMP8]] = shufflevector <16 x i8> [[WIDE_LOAD]], <16 x i8> [[WIDE_LOAD5]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
132e29f9f75SDavid Green; CHECK-NEXT:    [[TMP9:%.*]] = shufflevector <16 x i8> [[VECTOR_RECUR2]], <16 x i8> [[TMP7]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
133e29f9f75SDavid Green; CHECK-NEXT:    [[TMP10]] = shufflevector <16 x i8> [[TMP7]], <16 x i8> [[TMP8]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
134e29f9f75SDavid Green; CHECK-NEXT:    [[TMP11:%.*]] = shufflevector <16 x i8> [[VECTOR_RECUR4]], <16 x i8> [[TMP9]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
135e29f9f75SDavid Green; CHECK-NEXT:    [[TMP12:%.*]] = shufflevector <16 x i8> [[TMP9]], <16 x i8> [[TMP10]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
136e29f9f75SDavid Green; CHECK-NEXT:    [[TMP13:%.*]] = add <16 x i8> [[TMP9]], [[TMP11]]
137e29f9f75SDavid Green; CHECK-NEXT:    [[TMP14:%.*]] = add <16 x i8> [[TMP10]], [[TMP12]]
138e29f9f75SDavid Green; CHECK-NEXT:    [[TMP15:%.*]] = add <16 x i8> [[TMP13]], [[TMP7]]
139e29f9f75SDavid Green; CHECK-NEXT:    [[TMP16:%.*]] = add <16 x i8> [[TMP14]], [[TMP8]]
140e29f9f75SDavid Green; CHECK-NEXT:    [[TMP17:%.*]] = add <16 x i8> [[TMP15]], [[WIDE_LOAD]]
141e29f9f75SDavid Green; CHECK-NEXT:    [[TMP18:%.*]] = add <16 x i8> [[TMP16]], [[WIDE_LOAD5]]
142e29f9f75SDavid Green; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 [[TMP1]]
143e29f9f75SDavid Green; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds i8, ptr [[TMP19]], i32 0
144e29f9f75SDavid Green; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[TMP19]], i32 16
145f18536d6SFlorian Hahn; CHECK-NEXT:    store <16 x i8> [[TMP17]], ptr [[TMP21]], align 1
146e29f9f75SDavid Green; CHECK-NEXT:    store <16 x i8> [[TMP18]], ptr [[TMP22]], align 1
147e29f9f75SDavid Green; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32
148e29f9f75SDavid Green; CHECK-NEXT:    [[TMP23:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
149e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[TMP23]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
150e29f9f75SDavid Green; CHECK:       middle.block:
151e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <16 x i8> [[WIDE_LOAD5]], i32 15
152e29f9f75SDavid Green; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT6:%.*]] = extractelement <16 x i8> [[TMP8]], i32 15
15399d6c6d9SFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT7:%.*]] = extractelement <16 x i8> [[TMP10]], i32 15
15499d6c6d9SFlorian Hahn; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
155e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[SCALAR_PH]]
156e29f9f75SDavid Green; CHECK:       scalar.ph:
1579a5a8731SFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i8 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ [[DOTPRE45]], [[FOR_BODY_PREHEADER]] ]
1589a5a8731SFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT8:%.*]] = phi i8 [ [[VECTOR_RECUR_EXTRACT6]], [[MIDDLE_BLOCK]] ], [ [[DOTPRE44]], [[FOR_BODY_PREHEADER]] ]
159c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT9:%.*]] = phi i8 [ [[VECTOR_RECUR_EXTRACT7]], [[MIDDLE_BLOCK]] ], [ [[DOTPRE]], [[FOR_BODY_PREHEADER]] ]
160*7f3428d3SFlorian Hahn; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 3, [[FOR_BODY_PREHEADER]] ]
161e29f9f75SDavid Green; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
162e29f9f75SDavid Green; CHECK:       for.cond.cleanup.loopexit:
163e29f9f75SDavid Green; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
164e29f9f75SDavid Green; CHECK:       for.cond.cleanup:
165e29f9f75SDavid Green; CHECK-NEXT:    ret void
166e29f9f75SDavid Green; CHECK:       for.body:
167c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP24:%.*]] = phi i8 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[TMP27:%.*]], [[FOR_BODY]] ]
168c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP25:%.*]] = phi i8 [ [[SCALAR_RECUR_INIT8]], [[SCALAR_PH]] ], [ [[TMP24]], [[FOR_BODY]] ]
169c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP26:%.*]] = phi i8 [ [[SCALAR_RECUR_INIT9]], [[SCALAR_PH]] ], [ [[TMP25]], [[FOR_BODY]] ]
170e29f9f75SDavid Green; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
171c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[ADD8:%.*]] = add i8 [[TMP25]], [[TMP26]]
172c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[ADD15:%.*]] = add i8 [[ADD8]], [[TMP24]]
173e29f9f75SDavid Green; CHECK-NEXT:    [[ARRAYIDX18:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[INDVARS_IV]]
174c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP27]] = load i8, ptr [[ARRAYIDX18]], align 1
175c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[ADD21:%.*]] = add i8 [[ADD15]], [[TMP27]]
176e29f9f75SDavid Green; CHECK-NEXT:    [[ARRAYIDX24:%.*]] = getelementptr inbounds i8, ptr [[Y]], i64 [[INDVARS_IV]]
177e29f9f75SDavid Green; CHECK-NEXT:    store i8 [[ADD21]], ptr [[ARRAYIDX24]], align 1
178e29f9f75SDavid Green; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
179e29f9f75SDavid Green; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
180e29f9f75SDavid Green; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
181e29f9f75SDavid Green;
182e29f9f75SDavid Greenentry:
183e29f9f75SDavid Green  %cmp38 = icmp sgt i32 %n, 3
184e29f9f75SDavid Green  br i1 %cmp38, label %for.body.preheader, label %for.cond.cleanup
185e29f9f75SDavid Green
186e29f9f75SDavid Greenfor.body.preheader:                               ; preds = %entry
187e29f9f75SDavid Green  %wide.trip.count = zext i32 %n to i64
188e29f9f75SDavid Green  %.pre = load i8, ptr %x, align 1
189e29f9f75SDavid Green  %arrayidx5.phi.trans.insert = getelementptr inbounds i8, ptr %x, i64 1
190e29f9f75SDavid Green  %.pre44 = load i8, ptr %arrayidx5.phi.trans.insert, align 1
191e29f9f75SDavid Green  %arrayidx12.phi.trans.insert = getelementptr inbounds i8, ptr %x, i64 2
192e29f9f75SDavid Green  %.pre45 = load i8, ptr %arrayidx12.phi.trans.insert, align 1
193e29f9f75SDavid Green  br label %for.body
194e29f9f75SDavid Green
195e29f9f75SDavid Greenfor.cond.cleanup:                                 ; preds = %for.body, %entry
196e29f9f75SDavid Green  ret void
197e29f9f75SDavid Green
198e29f9f75SDavid Greenfor.body:                                         ; preds = %for.body.preheader, %for.body
199e29f9f75SDavid Green  %0 = phi i8 [ %.pre45, %for.body.preheader ], [ %3, %for.body ]
200e29f9f75SDavid Green  %1 = phi i8 [ %.pre44, %for.body.preheader ], [ %0, %for.body ]
201e29f9f75SDavid Green  %2 = phi i8 [ %.pre, %for.body.preheader ], [ %1, %for.body ]
202e29f9f75SDavid Green  %indvars.iv = phi i64 [ 3, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
203e29f9f75SDavid Green  %add8 = add i8 %1, %2
204e29f9f75SDavid Green  %add15 = add i8 %add8, %0
205e29f9f75SDavid Green  %arrayidx18 = getelementptr inbounds i8, ptr %x, i64 %indvars.iv
206e29f9f75SDavid Green  %3 = load i8, ptr %arrayidx18, align 1
207e29f9f75SDavid Green  %add21 = add i8 %add15, %3
208e29f9f75SDavid Green  %arrayidx24 = getelementptr inbounds i8, ptr %y, i64 %indvars.iv
209e29f9f75SDavid Green  store i8 %add21, ptr %arrayidx24, align 1
210e29f9f75SDavid Green  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
211e29f9f75SDavid Green  %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
212e29f9f75SDavid Green  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
213e29f9f75SDavid Green}
2144c51a45eSFlorian Hahn
215f47084ecSFlorian Hahndefine i64 @test_pr62954_scalar_epilogue_required(ptr %A, ptr noalias %B, ptr %C)  {
216f47084ecSFlorian Hahn; CHECK-LABEL: @test_pr62954_scalar_epilogue_required(
2174c51a45eSFlorian Hahn; CHECK-NEXT:  entry:
2184c51a45eSFlorian Hahn; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 872
2194c51a45eSFlorian Hahn; CHECK-NEXT:    [[REC_START:%.*]] = load i64, ptr [[GEP]], align 8
220f47084ecSFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
221f47084ecSFlorian Hahn; CHECK:       vector.ph:
222c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR_INIT:%.*]] = insertelement <2 x i64> poison, i64 [[REC_START]], i32 1
223f47084ecSFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
224f47084ecSFlorian Hahn; CHECK:       vector.body:
225f47084ecSFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
226c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
227c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR:%.*]] = phi <2 x i64> [ [[VECTOR_RECUR_INIT]], [[VECTOR_PH]] ], [ [[TMP1:%.*]], [[VECTOR_BODY]] ]
22838fffa63SPaul Walker; CHECK-NEXT:    [[STEP_ADD:%.*]] = add <2 x i64> [[VEC_IND]], splat (i64 4)
229c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP1]] = sub nsw <2 x i64> zeroinitializer, [[STEP_ADD]]
230c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
231c48a1ebeSFlorian Hahn; CHECK-NEXT:    store i64 [[TMP2]], ptr [[GEP]], align 8
232c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
23338fffa63SPaul Walker; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[STEP_ADD]], splat (i64 4)
234c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 36
235c48a1ebeSFlorian Hahn; CHECK-NEXT:    br i1 [[TMP3]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
236f47084ecSFlorian Hahn; CHECK:       middle.block:
237c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
238f47084ecSFlorian Hahn; CHECK-NEXT:    br label [[SCALAR_PH]]
239f47084ecSFlorian Hahn; CHECK:       scalar.ph:
240c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 73, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
2419a5a8731SFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i64 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ [[REC_START]], [[ENTRY]] ]
2424c51a45eSFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
2434c51a45eSFlorian Hahn; CHECK:       loop:
244f47084ecSFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
245c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[FOR:%.*]] = phi i64 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[NEG_IV:%.*]], [[LOOP]] ]
2464c51a45eSFlorian Hahn; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr double, ptr [[B:%.*]], i64 [[IV]]
2474c51a45eSFlorian Hahn; CHECK-NEXT:    [[L_B:%.*]] = load double, ptr [[GEP_B]], align 8
2484c51a45eSFlorian Hahn; CHECK-NEXT:    [[NEG_IV]] = sub nsw i64 0, [[IV]]
2494c51a45eSFlorian Hahn; CHECK-NEXT:    store i64 [[NEG_IV]], ptr [[GEP]], align 8
2504c51a45eSFlorian Hahn; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
2514c51a45eSFlorian Hahn; CHECK-NEXT:    [[EC:%.*]] = icmp ugt i64 [[IV]], 74
252f47084ecSFlorian Hahn; CHECK-NEXT:    br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]
2534c51a45eSFlorian Hahn; CHECK:       exit:
254c48a1ebeSFlorian Hahn; CHECK-NEXT:    [[DOTIN_LCSSA:%.*]] = phi i64 [ [[FOR]], [[LOOP]] ]
2554c51a45eSFlorian Hahn; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi double [ [[L_B]], [[LOOP]] ]
2564c51a45eSFlorian Hahn; CHECK-NEXT:    store double [[DOTLCSSA]], ptr [[C:%.*]], align 8
2574c51a45eSFlorian Hahn; CHECK-NEXT:    ret i64 [[DOTIN_LCSSA]]
2584c51a45eSFlorian Hahn;
2594c51a45eSFlorian Hahnentry:
2604c51a45eSFlorian Hahn  %gep = getelementptr i8, ptr %A, i64 872
2614c51a45eSFlorian Hahn  %rec.start = load i64, ptr  %gep, align 8
2624c51a45eSFlorian Hahn  br label %loop
2634c51a45eSFlorian Hahn
2644c51a45eSFlorian Hahnloop:
2654c51a45eSFlorian Hahn  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
2664c51a45eSFlorian Hahn  %for = phi i64 [ %rec.start, %entry ], [ %neg.iv, %loop ]
2674c51a45eSFlorian Hahn  %gep.B = getelementptr double, ptr  %B, i64 %iv
2684c51a45eSFlorian Hahn  %l.B = load double, ptr  %gep.B, align 8
2694c51a45eSFlorian Hahn  %neg.iv = sub nsw i64 0, %iv
2704c51a45eSFlorian Hahn  store i64 %neg.iv, ptr %gep, align 8
2714c51a45eSFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 2
2724c51a45eSFlorian Hahn  %ec = icmp ugt i64 %iv, 74
2734c51a45eSFlorian Hahn  br i1 %ec, label %exit, label %loop
2744c51a45eSFlorian Hahn
2754c51a45eSFlorian Hahnexit:
2764c51a45eSFlorian Hahn  %.in.lcssa = phi i64 [ %for, %loop ]
2774c51a45eSFlorian Hahn  %.lcssa = phi double [ %l.B, %loop ]
2784c51a45eSFlorian Hahn  store double %.lcssa, ptr %C
2794c51a45eSFlorian Hahn  ret i64 %.in.lcssa
2804c51a45eSFlorian Hahn}
2812dfb1c66SFlorian Hahn
2822dfb1c66SFlorian Hahn; Test for https://github.com/llvm/llvm-project/issues/106523.
2832dfb1c66SFlorian Hahn; %for.2 requires no code motion, as its previous (%or) precedes its (first)
2842dfb1c66SFlorian Hahn; user (store). Furthermore, its user cannot sink, being a store.
2852dfb1c66SFlorian Hahn;
2862dfb1c66SFlorian Hahn; %for.1 requires code motion, as its previous (%trunc) follows its (first)
2872dfb1c66SFlorian Hahn; user (%or). Sinking %or past %trunc seems possible, as %or has no uses
2882dfb1c66SFlorian Hahn; (except for feeding %for.2; worth strengthening VPlan's dce?). However, %or
2892dfb1c66SFlorian Hahn; is both the user of %for.1 and the previous of %for.2, and we refrain from
2902dfb1c66SFlorian Hahn; sinking instructions that act as previous because they (may) serve points to
2912dfb1c66SFlorian Hahn; sink after.
2922dfb1c66SFlorian Hahn
2932dfb1c66SFlorian Hahn; Instead, %for.1 can be reconciled by hoisting its previous above its user
2942dfb1c66SFlorian Hahn; %or, as this user %trunc depends only on %iv.
2952dfb1c66SFlorian Hahndefine void @for_iv_trunc_optimized(ptr %dst) {
2962dfb1c66SFlorian Hahn; CHECK-LABEL: @for_iv_trunc_optimized(
2972dfb1c66SFlorian Hahn; CHECK-NEXT:  bb:
2982dfb1c66SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
2992dfb1c66SFlorian Hahn; CHECK:       vector.ph:
3002dfb1c66SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
3012dfb1c66SFlorian Hahn; CHECK:       vector.body:
3022dfb1c66SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
3032dfb1c66SFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 1>, [[VECTOR_PH]] ], [ [[STEP_ADD:%.*]], [[VECTOR_BODY]] ]
3042dfb1c66SFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR1:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 0>, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[VECTOR_BODY]] ]
3052dfb1c66SFlorian Hahn; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 1, i32 2, i32 3, i32 4>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
30638fffa63SPaul Walker; CHECK-NEXT:    [[STEP_ADD]] = add <4 x i32> [[VEC_IND]], splat (i32 4)
3072dfb1c66SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = shufflevector <4 x i32> [[VECTOR_RECUR]], <4 x i32> [[VEC_IND]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
3082dfb1c66SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[VEC_IND]], <4 x i32> [[STEP_ADD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
30938fffa63SPaul Walker; CHECK-NEXT:    [[TMP2:%.*]] = or <4 x i32> [[TMP0]], splat (i32 3)
31038fffa63SPaul Walker; CHECK-NEXT:    [[TMP3]] = or <4 x i32> [[TMP1]], splat (i32 3)
3112dfb1c66SFlorian Hahn; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> [[TMP3]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
3122dfb1c66SFlorian Hahn; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <4 x i32> [[TMP5]], i32 3
3132dfb1c66SFlorian Hahn; CHECK-NEXT:    store i32 [[TMP6]], ptr [[DST:%.*]], align 4
3142dfb1c66SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
31538fffa63SPaul Walker; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[STEP_ADD]], splat (i32 4)
3162dfb1c66SFlorian Hahn; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 336
3172dfb1c66SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
3182dfb1c66SFlorian Hahn; CHECK:       middle.block:
3192dfb1c66SFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i32> [[STEP_ADD]], i32 3
3202dfb1c66SFlorian Hahn; CHECK-NEXT:    [[VECTOR_RECUR_EXTRACT3:%.*]] = extractelement <4 x i32> [[TMP3]], i32 3
3212dfb1c66SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
3222dfb1c66SFlorian Hahn; CHECK:       scalar.ph:
3232dfb1c66SFlorian Hahn; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 337, [[MIDDLE_BLOCK]] ], [ 1, [[BB:%.*]] ]
3242dfb1c66SFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i32 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ 1, [[BB]] ]
3252dfb1c66SFlorian Hahn; CHECK-NEXT:    [[SCALAR_RECUR_INIT4:%.*]] = phi i32 [ [[VECTOR_RECUR_EXTRACT3]], [[MIDDLE_BLOCK]] ], [ 0, [[BB]] ]
3262dfb1c66SFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
3272dfb1c66SFlorian Hahn; CHECK:       loop:
3282dfb1c66SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[ADD:%.*]], [[LOOP]] ]
3292dfb1c66SFlorian Hahn; CHECK-NEXT:    [[FOR_1:%.*]] = phi i32 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[TRUNC:%.*]], [[LOOP]] ]
3302dfb1c66SFlorian Hahn; CHECK-NEXT:    [[FOR_2:%.*]] = phi i32 [ [[SCALAR_RECUR_INIT4]], [[SCALAR_PH]] ], [ [[OR:%.*]], [[LOOP]] ]
3312dfb1c66SFlorian Hahn; CHECK-NEXT:    [[OR]] = or i32 [[FOR_1]], 3
3322dfb1c66SFlorian Hahn; CHECK-NEXT:    [[ADD]] = add i64 [[IV]], 1
3332dfb1c66SFlorian Hahn; CHECK-NEXT:    store i32 [[FOR_2]], ptr [[DST]], align 4
3342dfb1c66SFlorian Hahn; CHECK-NEXT:    [[ICMP:%.*]] = icmp ult i64 [[IV]], 337
3352dfb1c66SFlorian Hahn; CHECK-NEXT:    [[TRUNC]] = trunc i64 [[IV]] to i32
3362dfb1c66SFlorian Hahn; CHECK-NEXT:    br i1 [[ICMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP9:![0-9]+]]
3372dfb1c66SFlorian Hahn; CHECK:       exit:
3382dfb1c66SFlorian Hahn; CHECK-NEXT:    ret void
3392dfb1c66SFlorian Hahn;
3402dfb1c66SFlorian Hahnbb:
3412dfb1c66SFlorian Hahn  br label %loop
3422dfb1c66SFlorian Hahn
3432dfb1c66SFlorian Hahnloop:
3442dfb1c66SFlorian Hahn  %iv = phi i64 [ 1, %bb ], [ %add, %loop ]
3452dfb1c66SFlorian Hahn  %for.1 = phi i32 [ 1, %bb ], [ %trunc, %loop ]
3462dfb1c66SFlorian Hahn  %for.2 = phi i32 [ 0, %bb ], [ %or, %loop ]
3472dfb1c66SFlorian Hahn  %or = or i32 %for.1, 3
3482dfb1c66SFlorian Hahn  %add = add i64 %iv, 1
3492dfb1c66SFlorian Hahn  store i32 %for.2, ptr %dst, align 4
3502dfb1c66SFlorian Hahn  %icmp = icmp ult i64 %iv, 337
3512dfb1c66SFlorian Hahn  %trunc = trunc i64 %iv to i32
3522dfb1c66SFlorian Hahn  br i1 %icmp, label %loop, label %exit
3532dfb1c66SFlorian Hahn
3542dfb1c66SFlorian Hahnexit:
3552dfb1c66SFlorian Hahn  ret void
3562dfb1c66SFlorian Hahn}
357