xref: /llvm-project/llvm/test/Transforms/LoopInterchange/multilevel-partial-reduction.ll (revision 25a87862a02f900974b424a58ec92abac66ae843)
1; RUN: opt < %s -passes=loop-interchange -cache-line-size=4 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
2; RUN:     -verify-dom-info -verify-loop-info -verify-loop-lcssa
3; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
4
5@b = external global [512 x [4 x i32]]
6@c = global [2 x [4 x i32]] zeroinitializer, align 1
7
8; Check that the outermost and the middle loops are not interchanged since
9; the innermost loop has a reduction operation which is however not in a form
10; that loop interchange can handle. Interchanging the outermost and the
11; middle loops would intervene with the reduction and cause miscompile.
12
13; REMARKS: --- !Missed
14; REMARKS-NEXT: Pass:            loop-interchange
15; REMARKS-NEXT: Name:            UnsupportedPHIInner
16; REMARKS-NEXT: Function:        test7
17; REMARKS: --- !Missed
18; REMARKS-NEXT: Pass:            loop-interchange
19; REMARKS-NEXT: Name:            UnsupportedPHIInner
20; REMARKS-NEXT: Function:        test7
21
22define i32 @test7() {
23entry:
24  br label %for.cond1.preheader.i
25
26for.cond1.preheader.i:                            ; preds = %for.inc19.i, %entry
27  %i.011.i = phi i16 [ 0, %entry ], [ %inc20.i, %for.inc19.i ]
28  br label %for.cond4.preheader.i
29
30for.cond4.preheader.i:                            ; preds = %middle.block, %for.cond1.preheader.i
31  %j.010.i = phi i16 [ 0, %for.cond1.preheader.i ], [ %inc17.i, %middle.block ]
32  %arrayidx14.i = getelementptr inbounds [2 x [4 x i32]], ptr @c, i16 0, i16 %i.011.i, i16 %j.010.i
33  %arrayidx14.promoted.i = load i32, ptr %arrayidx14.i, align 1
34  %0 = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 %arrayidx14.promoted.i, i64 0
35  br label %vector.body
36
37vector.body:                                      ; preds = %vector.body, %for.cond4.preheader.i
38  %index = phi i16 [ 0, %for.cond4.preheader.i ], [ %index.next, %vector.body ]
39  %vec.phi = phi <4 x i32> [ %0, %for.cond4.preheader.i ], [ %16, %vector.body ]
40  %1 = or i16 %index, 1
41  %2 = or i16 %index, 2
42  %3 = or i16 %index, 3
43  %4 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %index, i16 %j.010.i
44  %5 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %1, i16 %j.010.i
45  %6 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %2, i16 %j.010.i
46  %7 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %3, i16 %j.010.i
47  %8 = load i32, ptr %4, align 1
48  %9 = load i32, ptr %5, align 1
49  %10 = load i32, ptr %6, align 1
50  %11 = load i32, ptr %7, align 1
51  %12 = insertelement <4 x i32> poison, i32 %8, i64 0
52  %13 = insertelement <4 x i32> %12, i32 %9, i64 1
53  %14 = insertelement <4 x i32> %13, i32 %10, i64 2
54  %15 = insertelement <4 x i32> %14, i32 %11, i64 3
55  %16 = add <4 x i32> %15, %vec.phi
56  %index.next = add nuw i16 %index, 4
57  %17 = icmp eq i16 %index.next, 512
58  br i1 %17, label %middle.block, label %vector.body
59
60middle.block:                                     ; preds = %vector.body
61  %18 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %16)
62  store i32 %18, ptr %arrayidx14.i, align 1
63  %inc17.i = add nuw nsw i16 %j.010.i, 1
64  %exitcond12.not.i = icmp eq i16 %inc17.i, 4
65  br i1 %exitcond12.not.i, label %for.inc19.i, label %for.cond4.preheader.i
66
67for.inc19.i:                                      ; preds = %middle.block
68  %inc20.i = add nuw nsw i16 %i.011.i, 1
69  %exitcond13.not.i = icmp eq i16 %inc20.i, 2
70  br i1 %exitcond13.not.i, label %test.exit, label %for.cond1.preheader.i
71
72test.exit:                                        ; preds = %for.inc19.i
73  %19 = load i32, ptr @c, align 1
74  ret i32 %19
75}
76
77declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)
78