xref: /llvm-project/llvm/test/Transforms/LICM/expr-reassociate.ll (revision dc02070d695113d581b3ea50598e3aa5f1c0f42f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt -passes='reassociate' -S < %s | FileCheck %s --check-prefix=REASSOCIATE_ONLY
3; RUN: opt -passes='licm' -S < %s | FileCheck %s --check-prefix=LICM_ONLY
4; RUN: opt -passes='licm' -licm-max-num-fp-reassociations=1 -S < %s | FileCheck %s --check-prefix=LICM_ONLY_CONSTRAINED
5; RUN: opt -passes='reassociate,loop-mssa(licm)' -S < %s | FileCheck %s --check-prefix=LICM_AFTER_REASSOCIATE
6; RUN: opt -passes='reassociate,loop-mssa(licm)' -licm-max-num-fp-reassociations=1 -S < %s | FileCheck %s --check-prefix=LICM_AFTER_REASSOCIATE_CONSTRAINED
7
8;
9; A simple loop, should not get modified:
10;
11;  int j;
12;  const double d1d = d1 * delta;
13;
14;  for (j = 0; j <= i; j++)
15;    cells[j] = d1d * cells[j + 1];
16;
17
18define void @innermost_loop_1d_fast(i32 %i, double %d1, double %delta, ptr %cells) {
19; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_1d_fast
20; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
21; REASSOCIATE_ONLY-NEXT:  entry:
22; REASSOCIATE_ONLY-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]
23; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
24; REASSOCIATE_ONLY:       for.cond:
25; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
26; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
27; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
28; REASSOCIATE_ONLY:       for.body:
29; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
30; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
31; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
32; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
33; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
34; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
35; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
36; REASSOCIATE_ONLY-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
37; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
38; REASSOCIATE_ONLY:       for.end:
39; REASSOCIATE_ONLY-NEXT:    ret void
40;
41; LICM_ONLY-LABEL: define void @innermost_loop_1d_fast
42; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
43; LICM_ONLY-NEXT:  entry:
44; LICM_ONLY-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
45; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
46; LICM_ONLY:       for.cond:
47; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
48; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
49; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
50; LICM_ONLY:       for.body:
51; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
52; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
53; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
54; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
55; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
56; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
57; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
58; LICM_ONLY-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
59; LICM_ONLY-NEXT:    br label [[FOR_COND]]
60; LICM_ONLY:       for.end:
61; LICM_ONLY-NEXT:    ret void
62;
63; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_1d_fast
64; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
65; LICM_ONLY_CONSTRAINED-NEXT:  entry:
66; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
67; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
68; LICM_ONLY_CONSTRAINED:       for.cond:
69; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
70; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
71; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
72; LICM_ONLY_CONSTRAINED:       for.body:
73; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
74; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
75; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
76; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
77; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
78; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
79; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
80; LICM_ONLY_CONSTRAINED-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
81; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
82; LICM_ONLY_CONSTRAINED:       for.end:
83; LICM_ONLY_CONSTRAINED-NEXT:    ret void
84;
85; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_1d_fast
86; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
87; LICM_AFTER_REASSOCIATE-NEXT:  entry:
88; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]
89; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
90; LICM_AFTER_REASSOCIATE:       for.cond:
91; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
92; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
93; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
94; LICM_AFTER_REASSOCIATE:       for.body:
95; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
96; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
97; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
98; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
99; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
100; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
101; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
102; LICM_AFTER_REASSOCIATE-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
103; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
104; LICM_AFTER_REASSOCIATE:       for.end:
105; LICM_AFTER_REASSOCIATE-NEXT:    ret void
106;
107; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_1d_fast
108; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
109; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
110; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]
111; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
112; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
113; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
114; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
115; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
116; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
117; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
118; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
119; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
120; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
121; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
122; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
123; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
124; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
125; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
126; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
127; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
128;
129entry:
130  %fmul.d1 = fmul fast double %d1, %delta
131  br label %for.cond
132
133for.cond:
134  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
135  %cmp.not = icmp sgt i32 %j, %i
136  br i1 %cmp.not, label %for.end, label %for.body
137
138for.body:
139  %add.j.1 = add nuw nsw i32 %j, 1
140  %idxprom.j.1 = zext i32 %add.j.1 to i64
141  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
142  %cell.1 = load double, ptr %arrayidx.j.1, align 8
143  %fmul.1 = fmul fast double %fmul.d1, %cell.1
144  %idxprom.j = zext i32 %j to i64
145  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
146  store double %fmul.1, ptr %arrayidx.j, align 8
147  br label %for.cond
148
149for.end:
150  ret void
151}
152
153;
154; A simple loop:
155;
156;  int j;
157;
158;  for (j = 0; j <= i; j++)
159;    cells[j] = d1 * cells[j + 1] * delta;
160;
161; ...should be transformed by the LICM pass into this:
162;
163;  int j;
164;  const double d1d = d1 * delta;
165;
166;  for (j = 0; j <= i; j++)
167;    cells[j] = d1d * cells[j + 1];
168;
169
170define void @innermost_loop_1d_shouldhoist_fast(i32 %i, double %d1, double %delta, ptr %cells) {
171; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_1d_shouldhoist_fast
172; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
173; REASSOCIATE_ONLY-NEXT:  entry:
174; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
175; REASSOCIATE_ONLY:       for.cond:
176; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
177; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
178; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
179; REASSOCIATE_ONLY:       for.body:
180; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
181; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
182; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
183; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
184; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]
185; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]
186; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
187; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
188; REASSOCIATE_ONLY-NEXT:    store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8
189; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
190; REASSOCIATE_ONLY:       for.end:
191; REASSOCIATE_ONLY-NEXT:    ret void
192;
193; LICM_ONLY-LABEL: define void @innermost_loop_1d_shouldhoist_fast
194; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
195; LICM_ONLY-NEXT:  entry:
196; LICM_ONLY-NEXT:    [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
197; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
198; LICM_ONLY:       for.cond:
199; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
200; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
201; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
202; LICM_ONLY:       for.body:
203; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
204; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
205; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
206; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
207; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FACTOR_OP_FMUL]], [[CELL_1]]
208; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
209; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
210; LICM_ONLY-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
211; LICM_ONLY-NEXT:    br label [[FOR_COND]]
212; LICM_ONLY:       for.end:
213; LICM_ONLY-NEXT:    ret void
214;
215; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_1d_shouldhoist_fast
216; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
217; LICM_ONLY_CONSTRAINED-NEXT:  entry:
218; LICM_ONLY_CONSTRAINED-NEXT:    [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
219; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
220; LICM_ONLY_CONSTRAINED:       for.cond:
221; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
222; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
223; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
224; LICM_ONLY_CONSTRAINED:       for.body:
225; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
226; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
227; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
228; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
229; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FACTOR_OP_FMUL]], [[CELL_1]]
230; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
231; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
232; LICM_ONLY_CONSTRAINED-NEXT:    store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
233; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
234; LICM_ONLY_CONSTRAINED:       for.end:
235; LICM_ONLY_CONSTRAINED-NEXT:    ret void
236;
237; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_1d_shouldhoist_fast
238; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
239; LICM_AFTER_REASSOCIATE-NEXT:  entry:
240; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]
241; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
242; LICM_AFTER_REASSOCIATE:       for.cond:
243; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
244; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
245; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
246; LICM_AFTER_REASSOCIATE:       for.body:
247; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
248; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
249; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
250; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
251; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]
252; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
253; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
254; LICM_AFTER_REASSOCIATE-NEXT:    store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8
255; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
256; LICM_AFTER_REASSOCIATE:       for.end:
257; LICM_AFTER_REASSOCIATE-NEXT:    ret void
258;
259; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_1d_shouldhoist_fast
260; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
261; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
262; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]
263; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
264; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
265; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
266; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
267; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
268; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
269; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
270; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
271; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
272; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
273; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]
274; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
275; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
276; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8
277; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
278; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
279; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
280;
281entry:
282  br label %for.cond
283
284for.cond:
285  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
286  %cmp.not = icmp sgt i32 %j, %i
287  br i1 %cmp.not, label %for.end, label %for.body
288
289for.body:
290  %add.j.1 = add nuw nsw i32 %j, 1
291  %idxprom.j.1 = zext i32 %add.j.1 to i64
292  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
293  %cell.1 = load double, ptr %arrayidx.j.1, align 8
294  %fmul.1 = fmul fast double %d1, %cell.1
295  %fmul.2 = fmul fast double %fmul.1, %delta
296  %idxprom.j = zext i32 %j to i64
297  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
298  store double %fmul.2, ptr %arrayidx.j, align 8
299  br label %for.cond
300
301for.end:
302  ret void
303}
304
305;
306; The following loop will be modified by the 'Reassociate expressions' pass,
307;
308;  int j;
309;  const double d1d = d1 * delta;
310;  const double d2d = d2 * delta;
311;
312;  for (j = 0; j <= i; j++)
313;    cells[j] = d1d * cells[j + 1] + d2d * cells[j];
314;
315; ...into this:
316;
317;  int j;
318;
319;  for (j = 0; j <= i; j++)
320;    cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;
321;
322; We expect the LICM pass to undo this transformation.
323;
324
325define void @innermost_loop_2d_fast(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
326; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_fast
327; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
328; REASSOCIATE_ONLY-NEXT:  entry:
329; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
330; REASSOCIATE_ONLY:       for.cond:
331; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
332; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
333; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
334; REASSOCIATE_ONLY:       for.body:
335; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
336; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
337; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
338; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
339; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
340; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
341; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
342; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
343; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
344; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
345; REASSOCIATE_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
346; REASSOCIATE_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
347; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
348; REASSOCIATE_ONLY:       for.end:
349; REASSOCIATE_ONLY-NEXT:    ret void
350;
351; LICM_ONLY-LABEL: define void @innermost_loop_2d_fast
352; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
353; LICM_ONLY-NEXT:  entry:
354; LICM_ONLY-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
355; LICM_ONLY-NEXT:    [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
356; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
357; LICM_ONLY:       for.cond:
358; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
359; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
360; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
361; LICM_ONLY:       for.body:
362; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
363; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
364; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
365; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
366; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
367; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
368; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
369; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
370; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
371; LICM_ONLY-NEXT:    [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
372; LICM_ONLY-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
373; LICM_ONLY-NEXT:    br label [[FOR_COND]]
374; LICM_ONLY:       for.end:
375; LICM_ONLY-NEXT:    ret void
376;
377; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast
378; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
379; LICM_ONLY_CONSTRAINED-NEXT:  entry:
380; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
381; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
382; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
383; LICM_ONLY_CONSTRAINED:       for.cond:
384; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
385; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
386; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
387; LICM_ONLY_CONSTRAINED:       for.body:
388; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
389; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
390; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
391; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
392; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
393; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
394; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
395; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
396; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
397; LICM_ONLY_CONSTRAINED-NEXT:    [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
398; LICM_ONLY_CONSTRAINED-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
399; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
400; LICM_ONLY_CONSTRAINED:       for.end:
401; LICM_ONLY_CONSTRAINED-NEXT:    ret void
402;
403; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_fast
404; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
405; LICM_AFTER_REASSOCIATE-NEXT:  entry:
406; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
407; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]
408; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
409; LICM_AFTER_REASSOCIATE:       for.cond:
410; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
411; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
412; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
413; LICM_AFTER_REASSOCIATE:       for.body:
414; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
415; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
416; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
417; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
418; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]
419; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
420; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
421; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
422; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]
423; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
424; LICM_AFTER_REASSOCIATE-NEXT:    store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8
425; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
426; LICM_AFTER_REASSOCIATE:       for.end:
427; LICM_AFTER_REASSOCIATE-NEXT:    ret void
428;
429; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast
430; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
431; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
432; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
433; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
434; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
435; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
436; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
437; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
438; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
439; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
440; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
441; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
442; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
443; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
444; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
445; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
446; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
447; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
448; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
449; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
450; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
451; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
452; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
453;
454entry:
455  %fmul.d1 = fmul fast double %d1, %delta
456  %fmul.d2 = fmul fast double %d2, %delta
457  br label %for.cond
458
459for.cond:
460  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
461  %cmp.not = icmp sgt i32 %j, %i
462  br i1 %cmp.not, label %for.end, label %for.body
463
464for.body:
465  %add.j.1 = add nuw nsw i32 %j, 1
466  %idxprom.j.1 = zext i32 %add.j.1 to i64
467  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
468  %cell.1 = load double, ptr %arrayidx.j.1, align 8
469  %fmul.1 = fmul fast double %fmul.d1, %cell.1
470  %idxprom.j = zext i32 %j to i64
471  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
472  %cell.2 = load double, ptr %arrayidx.j, align 8
473  %fmul.2 = fmul fast double %fmul.d2, %cell.2
474  %fadd.1 = fadd fast double %fmul.1, %fmul.2
475  store double %fadd.1, ptr %arrayidx.j, align 8
476  br label %for.cond
477
478for.end:
479  ret void
480}
481
482;
483; The following loop will be modified by the 'Reassociate expressions' pass,
484;
485;  int j;
486;  const double d1d = d1 * delta;
487;  const double d2d = d2 * delta;
488;  const double d3d = d3 * delta;
489;
490;  for (j = 0; j <= i; j++)
491;    cells[j] = d1d * cells[j + 1] + d2d * cells[j] + d3d * cells[j + 2];
492;
493; ...into this:
494;
495;  int j;
496;
497;  for (j = 0; j <= i; j++)
498;    cells[j] = (d1 * cells[j + 1] + d2 * cells[j] + d3 * cells[j + 2]) * delta;
499;
500; We expect the LICM pass to undo this transformation.
501;
502
503
504define void @innermost_loop_3d_fast(i32 %i, double %d1, double %d2, double %d3, double %delta, ptr %cells) {
505; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_3d_fast
506; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
507; REASSOCIATE_ONLY-NEXT:  entry:
508; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
509; REASSOCIATE_ONLY:       for.cond:
510; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
511; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
512; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
513; REASSOCIATE_ONLY:       for.body:
514; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
515; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
516; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
517; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
518; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
519; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
520; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
521; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
522; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
523; REASSOCIATE_ONLY-NEXT:    [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
524; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
525; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
526; REASSOCIATE_ONLY-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
527; REASSOCIATE_ONLY-NEXT:    [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[D3]]
528; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
529; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]
530; REASSOCIATE_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD1]], [[DELTA]]
531; REASSOCIATE_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J_2]], align 8
532; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
533; REASSOCIATE_ONLY:       for.end:
534; REASSOCIATE_ONLY-NEXT:    ret void
535;
536; LICM_ONLY-LABEL: define void @innermost_loop_3d_fast
537; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
538; LICM_ONLY-NEXT:  entry:
539; LICM_ONLY-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
540; LICM_ONLY-NEXT:    [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
541; LICM_ONLY-NEXT:    [[FMUL_D3:%.*]] = fmul fast double [[D3]], [[DELTA]]
542; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
543; LICM_ONLY:       for.cond:
544; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
545; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
546; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
547; LICM_ONLY:       for.body:
548; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
549; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
550; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
551; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
552; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
553; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
554; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
555; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
556; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
557; LICM_ONLY-NEXT:    [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
558; LICM_ONLY-NEXT:    [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
559; LICM_ONLY-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
560; LICM_ONLY-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
561; LICM_ONLY-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
562; LICM_ONLY-NEXT:    [[FMUL_3:%.*]] = fmul fast double [[FMUL_D3]], [[CELL_3]]
563; LICM_ONLY-NEXT:    [[FADD_2:%.*]] = fadd fast double [[FADD_1]], [[FMUL_3]]
564; LICM_ONLY-NEXT:    store double [[FADD_2]], ptr [[ARRAYIDX_J_2]], align 8
565; LICM_ONLY-NEXT:    br label [[FOR_COND]]
566; LICM_ONLY:       for.end:
567; LICM_ONLY-NEXT:    ret void
568;
569; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast
570; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
571; LICM_ONLY_CONSTRAINED-NEXT:  entry:
572; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
573; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
574; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D3:%.*]] = fmul fast double [[D3]], [[DELTA]]
575; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
576; LICM_ONLY_CONSTRAINED:       for.cond:
577; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
578; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
579; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
580; LICM_ONLY_CONSTRAINED:       for.body:
581; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
582; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
583; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
584; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
585; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
586; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
587; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
588; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
589; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
590; LICM_ONLY_CONSTRAINED-NEXT:    [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
591; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
592; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
593; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
594; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
595; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_3:%.*]] = fmul fast double [[FMUL_D3]], [[CELL_3]]
596; LICM_ONLY_CONSTRAINED-NEXT:    [[FADD_2:%.*]] = fadd fast double [[FADD_1]], [[FMUL_3]]
597; LICM_ONLY_CONSTRAINED-NEXT:    store double [[FADD_2]], ptr [[ARRAYIDX_J_2]], align 8
598; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
599; LICM_ONLY_CONSTRAINED:       for.end:
600; LICM_ONLY_CONSTRAINED-NEXT:    ret void
601;
602; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_3d_fast
603; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
604; LICM_AFTER_REASSOCIATE-NEXT:  entry:
605; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D3]], [[DELTA]]
606; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL2:%.*]] = fmul fast double [[D1]], [[DELTA]]
607; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL3:%.*]] = fmul fast double [[D2]], [[DELTA]]
608; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
609; LICM_AFTER_REASSOCIATE:       for.cond:
610; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
611; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
612; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
613; LICM_AFTER_REASSOCIATE:       for.body:
614; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
615; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
616; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
617; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
618; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL2]]
619; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
620; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
621; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
622; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL3]]
623; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
624; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
625; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
626; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
627; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[FACTOR_OP_FMUL]]
628; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
629; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]
630; LICM_AFTER_REASSOCIATE-NEXT:    store double [[REASS_ADD1]], ptr [[ARRAYIDX_J_2]], align 8
631; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
632; LICM_AFTER_REASSOCIATE:       for.end:
633; LICM_AFTER_REASSOCIATE-NEXT:    ret void
634;
635; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast
636; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
637; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
638; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
639; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
640; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
641; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
642; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
643; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
644; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
645; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
646; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
647; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
648; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
649; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
650; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
651; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
652; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
653; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
654; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
655; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
656; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
657; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[D3]]
658; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
659; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]
660; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD1]], [[DELTA]]
661; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J_2]], align 8
662; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
663; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
664; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
665;
666entry:
667  %fmul.d1 = fmul fast double %d1, %delta
668  %fmul.d2 = fmul fast double %d2, %delta
669  %fmul.d3 = fmul fast double %d3, %delta
670  br label %for.cond
671
672for.cond:
673  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
674  %cmp.not = icmp sgt i32 %j, %i
675  br i1 %cmp.not, label %for.end, label %for.body
676
677for.body:
678  %add.j.1 = add nuw nsw i32 %j, 1
679  %idxprom.j.1 = zext i32 %add.j.1 to i64
680  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
681  %cell.1 = load double, ptr %arrayidx.j.1, align 8
682  %fmul.1 = fmul fast double %fmul.d1, %cell.1
683  %idxprom.j = zext i32 %j to i64
684  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
685  %cell.2 = load double, ptr %arrayidx.j, align 8
686  %fmul.2 = fmul fast double %fmul.d2, %cell.2
687  %fadd.1 = fadd fast double %fmul.1, %fmul.2
688  %add.j.2 = add nuw nsw i32 %j, 2
689  %idxprom.j.2 = zext i32 %add.j.2 to i64
690  %arrayidx.j.2 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.2
691  %cell.3 = load double, ptr %arrayidx.j.2, align 8
692  %fmul.3 = fmul fast double %fmul.d3, %cell.3
693  %fadd.2 = fadd fast double %fadd.1, %fmul.3
694  store double %fadd.2, ptr %arrayidx.j.2, align 8
695  br label %for.cond
696
697for.end:
698  ret void
699}
700
701;
702; When there is no 'fast' attribute, the transformation should not happen.
703;
704
705define void @innermost_loop_2d_nofast(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
706; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nofast
707; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
708; REASSOCIATE_ONLY-NEXT:  entry:
709; REASSOCIATE_ONLY-NEXT:    [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
710; REASSOCIATE_ONLY-NEXT:    [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
711; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
712; REASSOCIATE_ONLY:       for.cond:
713; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
714; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
715; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
716; REASSOCIATE_ONLY:       for.body:
717; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
718; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
719; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
720; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
721; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
722; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
723; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
724; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
725; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
726; REASSOCIATE_ONLY-NEXT:    [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
727; REASSOCIATE_ONLY-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
728; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
729; REASSOCIATE_ONLY:       for.end:
730; REASSOCIATE_ONLY-NEXT:    ret void
731;
732; LICM_ONLY-LABEL: define void @innermost_loop_2d_nofast
733; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
734; LICM_ONLY-NEXT:  entry:
735; LICM_ONLY-NEXT:    [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
736; LICM_ONLY-NEXT:    [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
737; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
738; LICM_ONLY:       for.cond:
739; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
740; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
741; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
742; LICM_ONLY:       for.body:
743; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
744; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
745; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
746; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
747; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
748; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
749; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
750; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
751; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
752; LICM_ONLY-NEXT:    [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
753; LICM_ONLY-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
754; LICM_ONLY-NEXT:    br label [[FOR_COND]]
755; LICM_ONLY:       for.end:
756; LICM_ONLY-NEXT:    ret void
757;
758; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast
759; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
760; LICM_ONLY_CONSTRAINED-NEXT:  entry:
761; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
762; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
763; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
764; LICM_ONLY_CONSTRAINED:       for.cond:
765; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
766; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
767; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
768; LICM_ONLY_CONSTRAINED:       for.body:
769; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
770; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
771; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
772; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
773; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
774; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
775; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
776; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
777; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
778; LICM_ONLY_CONSTRAINED-NEXT:    [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
779; LICM_ONLY_CONSTRAINED-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
780; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
781; LICM_ONLY_CONSTRAINED:       for.end:
782; LICM_ONLY_CONSTRAINED-NEXT:    ret void
783;
784; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nofast
785; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
786; LICM_AFTER_REASSOCIATE-NEXT:  entry:
787; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
788; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
789; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
790; LICM_AFTER_REASSOCIATE:       for.cond:
791; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
792; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
793; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
794; LICM_AFTER_REASSOCIATE:       for.body:
795; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
796; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
797; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
798; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
799; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
800; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
801; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
802; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
803; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
804; LICM_AFTER_REASSOCIATE-NEXT:    [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
805; LICM_AFTER_REASSOCIATE-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
806; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
807; LICM_AFTER_REASSOCIATE:       for.end:
808; LICM_AFTER_REASSOCIATE-NEXT:    ret void
809;
810; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast
811; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
812; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
813; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
814; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
815; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
816; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
817; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
818; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
819; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
820; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
821; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
822; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
823; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
824; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
825; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
826; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
827; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
828; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
829; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
830; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
831; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
832; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
833; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
834; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
835;
836entry:
837  %fmul.d1 = fmul double %d1, %delta
838  %fmul.d2 = fmul double %d2, %delta
839  br label %for.cond
840
841for.cond:
842  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
843  %cmp.not = icmp sgt i32 %j, %i
844  br i1 %cmp.not, label %for.end, label %for.body
845
846for.body:
847  %add.j.1 = add nuw nsw i32 %j, 1
848  %idxprom.j.1 = zext i32 %add.j.1 to i64
849  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
850  %cell.1 = load double, ptr %arrayidx.j.1, align 8
851  %fmul.1 = fmul double %fmul.d1, %cell.1
852  %idxprom.j = zext i32 %j to i64
853  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
854  %cell.2 = load double, ptr %arrayidx.j, align 8
855  %fmul.2 = fmul double %fmul.d2, %cell.2
856  %fadd.1 = fadd double %fmul.1, %fmul.2
857  store double %fadd.1, ptr %arrayidx.j, align 8
858  br label %for.cond
859
860for.end:
861  ret void
862}
863
864;
865; The following loop should be modified by the LICM pass,
866;
867;  int j;
868;
869;  for (j = 0; j <= i; j++)
870;    cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;
871;
872; ...into this:
873;
874;  int j;
875;  const double d1d = d1 * delta;
876;  const double d2d = d2 * delta;
877;
878;  for (j = 0; j <= i; j++)
879;    cells[j] = d1d * cells[j + 1] + d2d * cells[j];
880;
881
882define void @innermost_loop_2d_fast_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
883; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_fast_reassociated
884; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
885; REASSOCIATE_ONLY-NEXT:  entry:
886; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
887; REASSOCIATE_ONLY:       for.cond:
888; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
889; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
890; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
891; REASSOCIATE_ONLY:       for.body:
892; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
893; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
894; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
895; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
896; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
897; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
898; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
899; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
900; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
901; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
902; REASSOCIATE_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
903; REASSOCIATE_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
904; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
905; REASSOCIATE_ONLY:       for.end:
906; REASSOCIATE_ONLY-NEXT:    ret void
907;
908; LICM_ONLY-LABEL: define void @innermost_loop_2d_fast_reassociated
909; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
910; LICM_ONLY-NEXT:  entry:
911; LICM_ONLY-NEXT:    [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
912; LICM_ONLY-NEXT:    [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]
913; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
914; LICM_ONLY:       for.cond:
915; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
916; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
917; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
918; LICM_ONLY:       for.body:
919; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
920; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
921; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
922; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
923; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]
924; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
925; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
926; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
927; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]
928; LICM_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
929; LICM_ONLY-NEXT:    store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8
930; LICM_ONLY-NEXT:    br label [[FOR_COND]]
931; LICM_ONLY:       for.end:
932; LICM_ONLY-NEXT:    ret void
933;
934; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast_reassociated
935; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
936; LICM_ONLY_CONSTRAINED-NEXT:  entry:
937; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
938; LICM_ONLY_CONSTRAINED:       for.cond:
939; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
940; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
941; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
942; LICM_ONLY_CONSTRAINED:       for.body:
943; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
944; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
945; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
946; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
947; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
948; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
949; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
950; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
951; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
952; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
953; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
954; LICM_ONLY_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
955; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
956; LICM_ONLY_CONSTRAINED:       for.end:
957; LICM_ONLY_CONSTRAINED-NEXT:    ret void
958;
959; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_fast_reassociated
960; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
961; LICM_AFTER_REASSOCIATE-NEXT:  entry:
962; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
963; LICM_AFTER_REASSOCIATE-NEXT:    [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]
964; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
965; LICM_AFTER_REASSOCIATE:       for.cond:
966; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
967; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
968; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
969; LICM_AFTER_REASSOCIATE:       for.body:
970; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
971; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
972; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
973; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
974; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]
975; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
976; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
977; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
978; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]
979; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
980; LICM_AFTER_REASSOCIATE-NEXT:    store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8
981; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
982; LICM_AFTER_REASSOCIATE:       for.end:
983; LICM_AFTER_REASSOCIATE-NEXT:    ret void
984;
985; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast_reassociated
986; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
987; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
988; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
989; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
990; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
991; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
992; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
993; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
994; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
995; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
996; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
997; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
998; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
999; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1000; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1001; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1002; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
1003; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
1004; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
1005; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1006; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1007; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
1008; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
1009;
1010entry:
1011  br label %for.cond
1012
1013for.cond:
1014  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
1015  %cmp.not = icmp sgt i32 %j, %i
1016  br i1 %cmp.not, label %for.end, label %for.body
1017
1018for.body:
1019  %add.j.1 = add nuw nsw i32 %j, 1
1020  %idxprom.j.1 = zext i32 %add.j.1 to i64
1021  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
1022  %cell.1 = load double, ptr %arrayidx.j.1, align 8
1023  %fmul.1 = fmul fast double %cell.1, %d1
1024  %idxprom.j = zext i32 %j to i64
1025  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
1026  %cell.2 = load double, ptr %arrayidx.j, align 8
1027  %fmul.2 = fmul fast double %cell.2, %d2
1028  %reass.add = fadd fast double %fmul.2, %fmul.1
1029  %reass.mul = fmul fast double %reass.add, %delta
1030  store double %reass.mul, ptr %arrayidx.j, align 8
1031  br label %for.cond
1032
1033for.end:
1034  ret void
1035}
1036
1037;
1038; When there is no 'fast' attribute, the transformation should not happen.
1039;
1040
1041define void @innermost_loop_2d_nofast_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
1042; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nofast_reassociated
1043; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1044; REASSOCIATE_ONLY-NEXT:  entry:
1045; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
1046; REASSOCIATE_ONLY:       for.cond:
1047; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1048; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1049; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1050; REASSOCIATE_ONLY:       for.body:
1051; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1052; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1053; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1054; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1055; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]
1056; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1057; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1058; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1059; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]
1060; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
1061; REASSOCIATE_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]
1062; REASSOCIATE_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1063; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
1064; REASSOCIATE_ONLY:       for.end:
1065; REASSOCIATE_ONLY-NEXT:    ret void
1066;
1067; LICM_ONLY-LABEL: define void @innermost_loop_2d_nofast_reassociated
1068; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1069; LICM_ONLY-NEXT:  entry:
1070; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
1071; LICM_ONLY:       for.cond:
1072; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1073; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1074; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1075; LICM_ONLY:       for.body:
1076; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1077; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1078; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1079; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1080; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul double [[CELL_1]], [[D1]]
1081; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1082; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1083; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1084; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul double [[CELL_2]], [[D2]]
1085; LICM_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd double [[FMUL_2]], [[FMUL_1]]
1086; LICM_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul double [[REASS_ADD]], [[DELTA]]
1087; LICM_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1088; LICM_ONLY-NEXT:    br label [[FOR_COND]]
1089; LICM_ONLY:       for.end:
1090; LICM_ONLY-NEXT:    ret void
1091;
1092; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast_reassociated
1093; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1094; LICM_ONLY_CONSTRAINED-NEXT:  entry:
1095; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
1096; LICM_ONLY_CONSTRAINED:       for.cond:
1097; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1098; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1099; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1100; LICM_ONLY_CONSTRAINED:       for.body:
1101; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1102; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1103; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1104; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1105; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul double [[CELL_1]], [[D1]]
1106; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1107; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1108; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1109; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul double [[CELL_2]], [[D2]]
1110; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd double [[FMUL_2]], [[FMUL_1]]
1111; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul double [[REASS_ADD]], [[DELTA]]
1112; LICM_ONLY_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1113; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1114; LICM_ONLY_CONSTRAINED:       for.end:
1115; LICM_ONLY_CONSTRAINED-NEXT:    ret void
1116;
1117; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nofast_reassociated
1118; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1119; LICM_AFTER_REASSOCIATE-NEXT:  entry:
1120; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
1121; LICM_AFTER_REASSOCIATE:       for.cond:
1122; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1123; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1124; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1125; LICM_AFTER_REASSOCIATE:       for.body:
1126; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1127; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1128; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1129; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1130; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]
1131; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1132; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1133; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1134; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]
1135; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
1136; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]
1137; LICM_AFTER_REASSOCIATE-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1138; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
1139; LICM_AFTER_REASSOCIATE:       for.end:
1140; LICM_AFTER_REASSOCIATE-NEXT:    ret void
1141;
1142; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast_reassociated
1143; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1144; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
1145; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
1146; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
1147; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1148; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1149; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1150; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
1151; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1152; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1153; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1154; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1155; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]
1156; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1157; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1158; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1159; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]
1160; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
1161; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]
1162; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1163; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1164; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
1165; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
1166;
1167entry:
1168  br label %for.cond
1169
1170for.cond:
1171  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
1172  %cmp.not = icmp sgt i32 %j, %i
1173  br i1 %cmp.not, label %for.end, label %for.body
1174
1175for.body:
1176  %add.j.1 = add nuw nsw i32 %j, 1
1177  %idxprom.j.1 = zext i32 %add.j.1 to i64
1178  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
1179  %cell.1 = load double, ptr %arrayidx.j.1, align 8
1180  %fmul.1 = fmul double %cell.1, %d1
1181  %idxprom.j = zext i32 %j to i64
1182  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
1183  %cell.2 = load double, ptr %arrayidx.j, align 8
1184  %fmul.2 = fmul double %cell.2, %d2
1185  %reass.add = fadd double %fmul.2, %fmul.1
1186  %reass.mul = fmul double %reass.add, %delta
1187  store double %reass.mul, ptr %arrayidx.j, align 8
1188  br label %for.cond
1189
1190for.end:
1191  ret void
1192}
1193;
1194; When there is no 'nsz' attribute, the transformation should not happen.
1195;
1196
1197define void @innermost_loop_2d_nonsz_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
1198; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nonsz_reassociated
1199; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1200; REASSOCIATE_ONLY-NEXT:  entry:
1201; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
1202; REASSOCIATE_ONLY:       for.cond:
1203; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1204; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1205; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1206; REASSOCIATE_ONLY:       for.body:
1207; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1208; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1209; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1210; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1211; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul reassoc double [[D1]], [[CELL_1]]
1212; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1213; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1214; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1215; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul reassoc double [[D2]], [[CELL_2]]
1216; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_1]], [[FMUL_2]]
1217; REASSOCIATE_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul reassoc double [[DELTA]], [[REASS_ADD]]
1218; REASSOCIATE_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1219; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
1220; REASSOCIATE_ONLY:       for.end:
1221; REASSOCIATE_ONLY-NEXT:    ret void
1222;
1223; LICM_ONLY-LABEL: define void @innermost_loop_2d_nonsz_reassociated
1224; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1225; LICM_ONLY-NEXT:  entry:
1226; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
1227; LICM_ONLY:       for.cond:
1228; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1229; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1230; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1231; LICM_ONLY:       for.body:
1232; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1233; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1234; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1235; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1236; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul reassoc double [[CELL_1]], [[D1]]
1237; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1238; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1239; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1240; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul reassoc double [[CELL_2]], [[D2]]
1241; LICM_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_2]], [[FMUL_1]]
1242; LICM_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul reassoc double [[REASS_ADD]], [[DELTA]]
1243; LICM_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1244; LICM_ONLY-NEXT:    br label [[FOR_COND]]
1245; LICM_ONLY:       for.end:
1246; LICM_ONLY-NEXT:    ret void
1247;
1248; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nonsz_reassociated
1249; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1250; LICM_ONLY_CONSTRAINED-NEXT:  entry:
1251; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
1252; LICM_ONLY_CONSTRAINED:       for.cond:
1253; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1254; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1255; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1256; LICM_ONLY_CONSTRAINED:       for.body:
1257; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1258; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1259; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1260; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1261; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul reassoc double [[CELL_1]], [[D1]]
1262; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1263; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1264; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1265; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul reassoc double [[CELL_2]], [[D2]]
1266; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_2]], [[FMUL_1]]
1267; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul reassoc double [[REASS_ADD]], [[DELTA]]
1268; LICM_ONLY_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1269; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1270; LICM_ONLY_CONSTRAINED:       for.end:
1271; LICM_ONLY_CONSTRAINED-NEXT:    ret void
1272;
1273; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nonsz_reassociated
1274; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1275; LICM_AFTER_REASSOCIATE-NEXT:  entry:
1276; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
1277; LICM_AFTER_REASSOCIATE:       for.cond:
1278; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1279; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1280; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1281; LICM_AFTER_REASSOCIATE:       for.body:
1282; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1283; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1284; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1285; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1286; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul reassoc double [[D1]], [[CELL_1]]
1287; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1288; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1289; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1290; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul reassoc double [[D2]], [[CELL_2]]
1291; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_1]], [[FMUL_2]]
1292; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_MUL:%.*]] = fmul reassoc double [[DELTA]], [[REASS_ADD]]
1293; LICM_AFTER_REASSOCIATE-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1294; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
1295; LICM_AFTER_REASSOCIATE:       for.end:
1296; LICM_AFTER_REASSOCIATE-NEXT:    ret void
1297;
1298; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nonsz_reassociated
1299; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1300; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
1301; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
1302; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
1303; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1304; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1305; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1306; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
1307; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1308; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1309; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1310; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1311; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul reassoc double [[D1]], [[CELL_1]]
1312; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1313; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1314; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1315; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul reassoc double [[D2]], [[CELL_2]]
1316; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_1]], [[FMUL_2]]
1317; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul reassoc double [[DELTA]], [[REASS_ADD]]
1318; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1319; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1320; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
1321; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
1322;
1323entry:
1324  br label %for.cond
1325
1326for.cond:
1327  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
1328  %cmp.not = icmp sgt i32 %j, %i
1329  br i1 %cmp.not, label %for.end, label %for.body
1330
1331for.body:
1332  %add.j.1 = add nuw nsw i32 %j, 1
1333  %idxprom.j.1 = zext i32 %add.j.1 to i64
1334  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
1335  %cell.1 = load double, ptr %arrayidx.j.1, align 8
1336  %fmul.1 = fmul reassoc double %cell.1, %d1
1337  %idxprom.j = zext i32 %j to i64
1338  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
1339  %cell.2 = load double, ptr %arrayidx.j, align 8
1340  %fmul.2 = fmul reassoc double %cell.2, %d2
1341  %reass.add = fadd reassoc double %fmul.2, %fmul.1
1342  %reass.mul = fmul reassoc double %reass.add, %delta
1343  store double %reass.mul, ptr %arrayidx.j, align 8
1344  br label %for.cond
1345
1346for.end:
1347  ret void
1348}
1349
1350;
1351; The following loop will not be modified by the LICM pass:
1352;
1353;  int j;
1354;
1355;  for (j = 0; j <= i; j++)
1356;    cells[j] = (d1 * cells[j + 1] + d2 * cells[j] +
1357;                cells[j] * cells[j + 1]) * delta;
1358;
1359; This case differs as one of the multiplications involves no invariants.
1360;
1361
1362define void @innermost_loop_3d_fast_reassociated_different(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
1363; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_3d_fast_reassociated_different
1364; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1365; REASSOCIATE_ONLY-NEXT:  entry:
1366; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND:%.*]]
1367; REASSOCIATE_ONLY:       for.cond:
1368; REASSOCIATE_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1369; REASSOCIATE_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1370; REASSOCIATE_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1371; REASSOCIATE_ONLY:       for.body:
1372; REASSOCIATE_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1373; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1374; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1375; REASSOCIATE_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1376; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
1377; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
1378; REASSOCIATE_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1379; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J_3:%.*]] = zext i32 [[ADD_J_1]] to i64
1380; REASSOCIATE_ONLY-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1381; REASSOCIATE_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1382; REASSOCIATE_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1383; REASSOCIATE_ONLY-NEXT:    [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1384; REASSOCIATE_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
1385; REASSOCIATE_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
1386; REASSOCIATE_ONLY-NEXT:    [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
1387; REASSOCIATE_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]
1388; REASSOCIATE_ONLY-NEXT:    [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]
1389; REASSOCIATE_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
1390; REASSOCIATE_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1391; REASSOCIATE_ONLY-NEXT:    br label [[FOR_COND]]
1392; REASSOCIATE_ONLY:       for.end:
1393; REASSOCIATE_ONLY-NEXT:    ret void
1394;
1395; LICM_ONLY-LABEL: define void @innermost_loop_3d_fast_reassociated_different
1396; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1397; LICM_ONLY-NEXT:  entry:
1398; LICM_ONLY-NEXT:    br label [[FOR_COND:%.*]]
1399; LICM_ONLY:       for.cond:
1400; LICM_ONLY-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1401; LICM_ONLY-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1402; LICM_ONLY-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1403; LICM_ONLY:       for.body:
1404; LICM_ONLY-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1405; LICM_ONLY-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1406; LICM_ONLY-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1407; LICM_ONLY-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1408; LICM_ONLY-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
1409; LICM_ONLY-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
1410; LICM_ONLY-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1411; LICM_ONLY-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1412; LICM_ONLY-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1413; LICM_ONLY-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1414; LICM_ONLY-NEXT:    [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1415; LICM_ONLY-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
1416; LICM_ONLY-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
1417; LICM_ONLY-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
1418; LICM_ONLY-NEXT:    [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
1419; LICM_ONLY-NEXT:    [[EXTRA_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[REASS_ADD]]
1420; LICM_ONLY-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
1421; LICM_ONLY-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1422; LICM_ONLY-NEXT:    br label [[FOR_COND]]
1423; LICM_ONLY:       for.end:
1424; LICM_ONLY-NEXT:    ret void
1425;
1426; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast_reassociated_different
1427; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1428; LICM_ONLY_CONSTRAINED-NEXT:  entry:
1429; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
1430; LICM_ONLY_CONSTRAINED:       for.cond:
1431; LICM_ONLY_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1432; LICM_ONLY_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1433; LICM_ONLY_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1434; LICM_ONLY_CONSTRAINED:       for.body:
1435; LICM_ONLY_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1436; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1437; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1438; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1439; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
1440; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
1441; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1442; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1443; LICM_ONLY_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1444; LICM_ONLY_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1445; LICM_ONLY_CONSTRAINED-NEXT:    [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1446; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
1447; LICM_ONLY_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
1448; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
1449; LICM_ONLY_CONSTRAINED-NEXT:    [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
1450; LICM_ONLY_CONSTRAINED-NEXT:    [[EXTRA_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[REASS_ADD]]
1451; LICM_ONLY_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
1452; LICM_ONLY_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1453; LICM_ONLY_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1454; LICM_ONLY_CONSTRAINED:       for.end:
1455; LICM_ONLY_CONSTRAINED-NEXT:    ret void
1456;
1457; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_3d_fast_reassociated_different
1458; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1459; LICM_AFTER_REASSOCIATE-NEXT:  entry:
1460; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND:%.*]]
1461; LICM_AFTER_REASSOCIATE:       for.cond:
1462; LICM_AFTER_REASSOCIATE-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1463; LICM_AFTER_REASSOCIATE-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1464; LICM_AFTER_REASSOCIATE-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1465; LICM_AFTER_REASSOCIATE:       for.body:
1466; LICM_AFTER_REASSOCIATE-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1467; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1468; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1469; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1470; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
1471; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
1472; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1473; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1474; LICM_AFTER_REASSOCIATE-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1475; LICM_AFTER_REASSOCIATE-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1476; LICM_AFTER_REASSOCIATE-NEXT:    [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1477; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
1478; LICM_AFTER_REASSOCIATE-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
1479; LICM_AFTER_REASSOCIATE-NEXT:    [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
1480; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]
1481; LICM_AFTER_REASSOCIATE-NEXT:    [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]
1482; LICM_AFTER_REASSOCIATE-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
1483; LICM_AFTER_REASSOCIATE-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1484; LICM_AFTER_REASSOCIATE-NEXT:    br label [[FOR_COND]]
1485; LICM_AFTER_REASSOCIATE:       for.end:
1486; LICM_AFTER_REASSOCIATE-NEXT:    ret void
1487;
1488; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast_reassociated_different
1489; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
1490; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:  entry:
1491; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND:%.*]]
1492; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.cond:
1493; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
1494; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
1495; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
1496; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.body:
1497; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
1498; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
1499; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
1500; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
1501; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
1502; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
1503; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1504; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
1505; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
1506; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
1507; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
1508; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
1509; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
1510; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
1511; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]
1512; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]
1513; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
1514; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
1515; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    br label [[FOR_COND]]
1516; LICM_AFTER_REASSOCIATE_CONSTRAINED:       for.end:
1517; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT:    ret void
1518;
1519entry:
1520  br label %for.cond
1521
1522for.cond:
1523  %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
1524  %cmp.not = icmp sgt i32 %j, %i
1525  br i1 %cmp.not, label %for.end, label %for.body
1526
1527for.body:
1528  %add.j.1 = add nuw nsw i32 %j, 1
1529  %idxprom.j.1 = zext i32 %add.j.1 to i64
1530  %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
1531  %cell.1 = load double, ptr %arrayidx.j.1, align 8
1532  %add.j.2 = add nuw nsw i32 %j, 2
1533  %idxprom.j.2 = zext i32 %add.j.1 to i64
1534  %arrayidx.j.2 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.2
1535  %cell.2 = load double, ptr %arrayidx.j.2, align 8
1536  %add.j.3 = add nuw nsw i32 %j, 3
1537  %idxprom.j.3 = zext i32 %add.j.1 to i64
1538  %arrayidx.j.3 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.3
1539  %cell.3 = load double, ptr %arrayidx.j.2, align 8
1540  %idxprom.j = zext i32 %j to i64
1541  %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
1542  %cell.4 = load double, ptr %arrayidx.j, align 8
1543  %fmul.1 = fmul fast double %cell.1, %d1
1544  %fmul.2 = fmul fast double %cell.4, %d2
1545  %reass.add = fadd fast double %fmul.2, %fmul.1
1546  %extra.mul = fmul fast double %cell.3, %cell.2
1547  %extra.add = fadd fast double %extra.mul, %reass.add
1548  %reass.mul = fmul fast double %extra.add, %delta
1549  store double %reass.mul, ptr %arrayidx.j, align 8
1550  br label %for.cond
1551
1552for.end:
1553  ret void
1554}
1555