[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / pr39673.ll
blob7fb90a90071ac254b407bd9c8d9db0d38564c926
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -indvars -indvars-predicate-loops=0  < %s | FileCheck %s
4 define i16 @constant() {
5 ; CHECK-LABEL: @constant(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    br label [[LOOP1:%.*]]
8 ; CHECK:       loop1:
9 ; CHECK-NEXT:    [[L1:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[L1_ADD:%.*]], [[LOOP1]] ]
10 ; CHECK-NEXT:    [[L1_ADD]] = add nuw nsw i16 [[L1]], 1
11 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i16 [[L1_ADD]], 2
12 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP1]], label [[LOOP2_PREHEADER:%.*]]
13 ; CHECK:       loop2.preheader:
14 ; CHECK-NEXT:    br label [[LOOP2:%.*]]
15 ; CHECK:       loop2:
16 ; CHECK-NEXT:    [[K2:%.*]] = phi i16 [ [[K2_ADD:%.*]], [[LOOP2]] ], [ 182, [[LOOP2_PREHEADER]] ]
17 ; CHECK-NEXT:    [[L2:%.*]] = phi i16 [ [[L2_ADD:%.*]], [[LOOP2]] ], [ 0, [[LOOP2_PREHEADER]] ]
18 ; CHECK-NEXT:    [[L2_ADD]] = add nuw nsw i16 [[L2]], 1
19 ; CHECK-NEXT:    tail call void @foo(i16 [[K2]])
20 ; CHECK-NEXT:    [[K2_ADD]] = add nuw nsw i16 [[K2]], 1
21 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
22 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
23 ; CHECK:       loop2.end:
24 ; CHECK-NEXT:    ret i16 184
26 entry:
27   br label %loop1
29 loop1:                                           ; preds = %entry, %loop1
30   %k1 = phi i16 [ 180, %entry ], [ %k1.add, %loop1 ]
31   %l1 = phi i16 [ 0, %entry ], [ %l1.add, %loop1 ]
32   %k1.add = add nuw nsw i16 %k1, 1
33   %l1.add = add nuw nsw i16 %l1, 1
34   %cmp1 = icmp ult i16 %l1.add, 2
35   br i1 %cmp1, label %loop1, label %loop2.preheader
37 loop2.preheader:                                 ; preds = %loop1
38   %k1.add.lcssa = phi i16 [ %k1.add, %loop1 ]
39   br label %loop2
41 loop2:                                           ; preds = %loop2.preheader, %loop2
42   %k2 = phi i16 [ %k2.add, %loop2 ], [ %k1.add.lcssa, %loop2.preheader ]
43   %l2 = phi i16 [ %l2.add, %loop2 ], [ 0, %loop2.preheader ]
44   %l2.add = add nuw i16 %l2, 1
45   tail call void @foo(i16 %k2)
46   %k2.add = add nuw nsw i16 %k2, 1
47   %cmp2 = icmp ult i16 %l2.add, 2
48   br i1 %cmp2, label %loop2, label %loop2.end
50 loop2.end:                                       ; preds = %loop2
51   %k2.add.lcssa = phi i16 [ %k2.add, %loop2 ]
52   ret i16 %k2.add.lcssa
55 define i16 @dom_argument(i16 %arg1, i16 %arg2) {
56 ; CHECK-LABEL: @dom_argument(
57 ; CHECK-NEXT:  entry:
58 ; CHECK-NEXT:    br label [[LOOP1:%.*]]
59 ; CHECK:       loop1:
60 ; CHECK-NEXT:    [[L1:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[L1_ADD:%.*]], [[LOOP1]] ]
61 ; CHECK-NEXT:    [[L1_ADD]] = add nuw nsw i16 [[L1]], 1
62 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i16 [[L1_ADD]], 2
63 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP1]], label [[LOOP2_PREHEADER:%.*]]
64 ; CHECK:       loop2.preheader:
65 ; CHECK-NEXT:    br label [[LOOP2:%.*]]
66 ; CHECK:       loop2:
67 ; CHECK-NEXT:    [[K2:%.*]] = phi i16 [ [[K2_ADD:%.*]], [[LOOP2]] ], [ [[ARG2:%.*]], [[LOOP2_PREHEADER]] ]
68 ; CHECK-NEXT:    [[L2:%.*]] = phi i16 [ [[L2_ADD:%.*]], [[LOOP2]] ], [ 0, [[LOOP2_PREHEADER]] ]
69 ; CHECK-NEXT:    [[L2_ADD]] = add nuw nsw i16 [[L2]], 1
70 ; CHECK-NEXT:    tail call void @foo(i16 [[K2]])
71 ; CHECK-NEXT:    [[K2_ADD]] = add nuw nsw i16 [[K2]], 1
72 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
73 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
74 ; CHECK:       loop2.end:
75 ; CHECK-NEXT:    [[K2_ADD_LCSSA:%.*]] = phi i16 [ [[K2_ADD]], [[LOOP2]] ]
76 ; CHECK-NEXT:    ret i16 [[K2_ADD_LCSSA]]
78 entry:
79   br label %loop1
81 loop1:                                           ; preds = %entry, %loop1
82   %k1 = phi i16 [ 100, %entry ], [ %k1.add, %loop1 ]
83   %l1 = phi i16 [ 0, %entry ], [ %l1.add, %loop1 ]
84   %selector = phi i16 [ %arg1, %entry ], [ %arg2, %loop1 ]
85   %k1.add = add nuw nsw i16 %k1, 1
86   %l1.add = add nuw nsw i16 %l1, 1
87   %cmp1 = icmp ult i16 %l1.add, 2
88   br i1 %cmp1, label %loop1, label %loop2.preheader
90 loop2.preheader:                                 ; preds = %loop1
91   %k1.add.lcssa = phi i16 [ %selector, %loop1 ]
92   br label %loop2
94 loop2:                                           ; preds = %loop2.preheader, %loop2
95   %k2 = phi i16 [ %k2.add, %loop2 ], [ %k1.add.lcssa, %loop2.preheader ]
96   %l2 = phi i16 [ %l2.add, %loop2 ], [ 0, %loop2.preheader ]
97   %l2.add = add nuw i16 %l2, 1
98   tail call void @foo(i16 %k2)
99   %k2.add = add nuw nsw i16 %k2, 1
100   %cmp2 = icmp ult i16 %l2.add, 2
101   br i1 %cmp2, label %loop2, label %loop2.end
103 loop2.end:                                       ; preds = %loop2
104   %k2.add.lcssa = phi i16 [ %k2.add, %loop2 ]
105   ret i16 %k2.add.lcssa
108 define i16 @dummy_phi_outside_loop(i16 %arg) {
109 ; CHECK-LABEL: @dummy_phi_outside_loop(
110 ; CHECK-NEXT:  entry:
111 ; CHECK-NEXT:    br label [[LOOP2_PREHEADER:%.*]]
112 ; CHECK:       loop2.preheader:
113 ; CHECK-NEXT:    [[DUMMY:%.*]] = phi i16 [ [[ARG:%.*]], [[ENTRY:%.*]] ]
114 ; CHECK-NEXT:    br label [[LOOP2:%.*]]
115 ; CHECK:       loop2:
116 ; CHECK-NEXT:    [[K2:%.*]] = phi i16 [ [[K2_ADD:%.*]], [[LOOP2]] ], [ [[DUMMY]], [[LOOP2_PREHEADER]] ]
117 ; CHECK-NEXT:    [[L2:%.*]] = phi i16 [ [[L2_ADD:%.*]], [[LOOP2]] ], [ 0, [[LOOP2_PREHEADER]] ]
118 ; CHECK-NEXT:    [[L2_ADD]] = add nuw nsw i16 [[L2]], 1
119 ; CHECK-NEXT:    tail call void @foo(i16 [[K2]])
120 ; CHECK-NEXT:    [[K2_ADD]] = add nuw nsw i16 [[K2]], 1
121 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
122 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
123 ; CHECK:       loop2.end:
124 ; CHECK-NEXT:    [[K2_ADD_LCSSA:%.*]] = phi i16 [ [[K2_ADD]], [[LOOP2]] ]
125 ; CHECK-NEXT:    ret i16 [[K2_ADD_LCSSA]]
127 entry:
128   br label %loop2.preheader
130 loop2.preheader:                                 ; preds = %loop1
131   %dummy = phi i16 [ %arg, %entry ]
132   br label %loop2
134 loop2:                                           ; preds = %loop2.preheader, %loop2
135   %k2 = phi i16 [ %k2.add, %loop2 ], [ %dummy, %loop2.preheader ]
136   %l2 = phi i16 [ %l2.add, %loop2 ], [ 0, %loop2.preheader ]
137   %l2.add = add nuw i16 %l2, 1
138   tail call void @foo(i16 %k2)
139   %k2.add = add nuw nsw i16 %k2, 1
140   %cmp2 = icmp ult i16 %l2.add, 2
141   br i1 %cmp2, label %loop2, label %loop2.end
143 loop2.end:                                       ; preds = %loop2
144   %k2.add.lcssa = phi i16 [ %k2.add, %loop2 ]
145   ret i16 %k2.add.lcssa
148 define i16 @neg_loop_carried(i16 %arg) {
149 ; CHECK-LABEL: @neg_loop_carried(
150 ; CHECK-NEXT:  entry:
151 ; CHECK-NEXT:    br label [[LOOP1:%.*]]
152 ; CHECK:       loop1:
153 ; CHECK-NEXT:    [[L1:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[L1_ADD:%.*]], [[LOOP1]] ]
154 ; CHECK-NEXT:    [[L1_ADD]] = add nuw nsw i16 [[L1]], 1
155 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i16 [[L1_ADD]], 2
156 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP1]], label [[LOOP2_PREHEADER:%.*]]
157 ; CHECK:       loop2.preheader:
158 ; CHECK-NEXT:    [[TMP0:%.*]] = add i16 [[ARG:%.*]], 2
159 ; CHECK-NEXT:    br label [[LOOP2:%.*]]
160 ; CHECK:       loop2:
161 ; CHECK-NEXT:    [[K2:%.*]] = phi i16 [ [[K2_ADD:%.*]], [[LOOP2]] ], [ [[TMP0]], [[LOOP2_PREHEADER]] ]
162 ; CHECK-NEXT:    [[L2:%.*]] = phi i16 [ [[L2_ADD:%.*]], [[LOOP2]] ], [ 0, [[LOOP2_PREHEADER]] ]
163 ; CHECK-NEXT:    [[L2_ADD]] = add nuw nsw i16 [[L2]], 1
164 ; CHECK-NEXT:    tail call void @foo(i16 [[K2]])
165 ; CHECK-NEXT:    [[K2_ADD]] = add nuw nsw i16 [[K2]], 1
166 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
167 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
168 ; CHECK:       loop2.end:
169 ; CHECK-NEXT:    [[K2_ADD_LCSSA:%.*]] = phi i16 [ [[K2_ADD]], [[LOOP2]] ]
170 ; CHECK-NEXT:    ret i16 [[K2_ADD_LCSSA]]
172 entry:
173   br label %loop1
175 loop1:                                           ; preds = %entry, %loop1
176   %k1 = phi i16 [ %arg, %entry ], [ %k1.add, %loop1 ]
177   %l1 = phi i16 [ 0, %entry ], [ %l1.add, %loop1 ]
178   %k1.add = add nuw nsw i16 %k1, 1
179   %l1.add = add nuw nsw i16 %l1, 1
180   %cmp1 = icmp ult i16 %l1.add, 2
181   br i1 %cmp1, label %loop1, label %loop2.preheader
183 loop2.preheader:                                 ; preds = %loop1
184   %k1.add.lcssa = phi i16 [ %k1.add, %loop1 ]
185   br label %loop2
187 loop2:                                           ; preds = %loop2.preheader, %loop2
188   %k2 = phi i16 [ %k2.add, %loop2 ], [ %k1.add.lcssa, %loop2.preheader ]
189   %l2 = phi i16 [ %l2.add, %loop2 ], [ 0, %loop2.preheader ]
190   %l2.add = add nuw i16 %l2, 1
191   tail call void @foo(i16 %k2)
192   %k2.add = add nuw nsw i16 %k2, 1
193   %cmp2 = icmp ult i16 %l2.add, 2
194   br i1 %cmp2, label %loop2, label %loop2.end
196 loop2.end:                                       ; preds = %loop2
197   %k2.add.lcssa = phi i16 [ %k2.add, %loop2 ]
198   ret i16 %k2.add.lcssa
202 declare void @foo(i16)