xref: /llvm-project/llvm/test/Transforms/LoopUnroll/unroll-header-exiting-with-phis.ll (revision b9808e5660f5fe9e7414c0c0b93acd899235471c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -passes=loop-unroll -unroll-allow-partial | FileCheck %s
3
4; The phi which acts as input to func should not be undef. It should
5; have its loop-carried value (the load in for.cond) replaced accordingly
6; after unrolling the loop.
7
8define i16 @full_unroll(ptr %A) {
9; CHECK-LABEL: @full_unroll(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    br label [[FOR_COND:%.*]]
12; CHECK:       for.cond:
13; CHECK-NEXT:    br label [[FOR_COND_CLEANUP3:%.*]]
14; CHECK:       for.cond.cleanup:
15; CHECK-NEXT:    [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2_2:%.*]], [[FOR_COND_CLEANUP3_2:%.*]] ]
16; CHECK-NEXT:    [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]])
17; CHECK-NEXT:    ret i16 0
18; CHECK:       for.cond.cleanup3:
19; CHECK-NEXT:    br label [[FOR_COND_CLEANUP3_1:%.*]]
20; CHECK:       for.cond.cleanup3.1:
21; CHECK-NEXT:    [[PTR_2:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 2
22; CHECK-NEXT:    [[TMP2_2]] = load i16, ptr [[PTR_2]], align 2
23; CHECK-NEXT:    br label [[FOR_COND_CLEANUP3_2]]
24; CHECK:       for.cond.cleanup3.2:
25; CHECK-NEXT:    br i1 false, label [[FOR_COND_CLEANUP3_3:%.*]], label [[FOR_COND_CLEANUP:%.*]]
26; CHECK:       for.cond.cleanup3.3:
27; CHECK-NEXT:    unreachable
28;
29entry:
30  br label %for.cond
31
32for.cond:                                         ; preds = %for.cond.cleanup3, %entry
33  %.lcssa10 = phi i16 [ 123, %entry ], [ %.lcssa, %for.cond.cleanup3 ]
34  %i.0 = phi i64 [ 0, %entry ], [ %inc9, %for.cond.cleanup3 ]
35  %ptr = getelementptr inbounds i16, ptr %A, i64 %i.0
36  %tmp2 = load i16, ptr %ptr
37  %cmp = icmp ult i64 %i.0, 3
38  br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup
39
40for.cond.cleanup:                                 ; preds = %for.cond
41  %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ]
42  %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa)
43  ret i16 0
44
45for.cond.cleanup3:                                ; preds = %for.cond
46  %.lcssa = phi i16 [ %tmp2, %for.cond ]
47  %inc9 = add i64 %i.0, 1
48  br label %for.cond
49}
50
51define i16 @partial_unroll(ptr %A) {
52; CHECK-LABEL: @partial_unroll(
53; CHECK-NEXT:  entry:
54; CHECK-NEXT:    br label [[FOR_COND:%.*]]
55; CHECK:       for.cond:
56; CHECK-NEXT:    [[I_0:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC9_2:%.*]], [[FOR_COND_CLEANUP3_2:%.*]] ]
57; CHECK-NEXT:    br label [[FOR_COND_CLEANUP3:%.*]]
58; CHECK:       for.cond.cleanup:
59; CHECK-NEXT:    [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2_1:%.*]], [[FOR_COND_CLEANUP3_1:%.*]] ]
60; CHECK-NEXT:    [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]])
61; CHECK-NEXT:    ret i16 0
62; CHECK:       for.cond.cleanup3:
63; CHECK-NEXT:    [[INC9:%.*]] = add nuw nsw i64 [[I_0]], 1
64; CHECK-NEXT:    [[PTR_1:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[INC9]]
65; CHECK-NEXT:    [[TMP2_1]] = load i16, ptr [[PTR_1]], align 2
66; CHECK-NEXT:    br label [[FOR_COND_CLEANUP3_1]]
67; CHECK:       for.cond.cleanup3.1:
68; CHECK-NEXT:    [[INC9_1:%.*]] = add nuw nsw i64 [[I_0]], 2
69; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult i64 [[INC9_1]], 200
70; CHECK-NEXT:    br i1 [[CMP_2]], label [[FOR_COND_CLEANUP3_2]], label [[FOR_COND_CLEANUP:%.*]]
71; CHECK:       for.cond.cleanup3.2:
72; CHECK-NEXT:    [[INC9_2]] = add nuw nsw i64 [[I_0]], 3
73; CHECK-NEXT:    br label [[FOR_COND]]
74;
75entry:
76  br label %for.cond
77
78for.cond:                                         ; preds = %for.cond.cleanup3, %entry
79  %.lcssa10 = phi i16 [ 123, %entry ], [ %.lcssa, %for.cond.cleanup3 ]
80  %i.0 = phi i64 [ 0, %entry ], [ %inc9, %for.cond.cleanup3 ]
81  %ptr = getelementptr inbounds i16, ptr %A, i64 %i.0
82  %tmp2 = load i16, ptr %ptr
83  %cmp = icmp ult i64 %i.0, 200
84  br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup
85
86for.cond.cleanup:                                 ; preds = %for.cond
87  %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ]
88  %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa)
89  ret i16 0
90
91for.cond.cleanup3:                                ; preds = %for.cond
92  %.lcssa = phi i16 [ %tmp2, %for.cond ]
93  %inc9 = add i64 %i.0, 1
94  br label %for.cond
95}
96
97declare i16 @func(i16)
98
99