1313// CHECK : %[[VAL_7 :.*]] = arith .constant 0 : index
1414// CHECK : %[[VAL_8 :.*]] = arith .constant 1 : index
1515// CHECK : scf .for %[[VAL_9 :.*]] = %[[VAL_7 ]] to %[[VAL_6 ]] step %[[VAL_8 ]] {
16- // CHECK : %[[VAL_10 :.*]] = arith .muli %[[VAL_9 ]], %[[VAL_0 ]] : index
17- // CHECK : %[[VAL_11 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_10 ]] : index
16+ // CHECK : %[[VAL_10 :.*]] = arith .muli %[[VAL_9 ]], %[[VAL_0 ]] overflow < nsw > : index
17+ // CHECK : %[[VAL_11 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_10 ]] overflow < nsw > : index
1818// CHECK : %[[VAL_12 :.*]] = fir .array_coor %[[ARG0 ]](%[[VAL_2 ]]) %[[VAL_11 ]] : (!fir .ref <!fir .array <100xi32 >>, !fir .shape <1 >, index ) -> !fir .ref <i32 >
1919// CHECK : fir .store %[[VAL_3 ]] to %[[VAL_12 ]] : !fir .ref <i32 >
2020// CHECK : }
@@ -34,6 +34,8 @@ func.func @simple_loop(%arg0: !fir.ref<!fir.array<100xi32>>) {
3434
3535// -----
3636
37+ // A typed induction variable is recomputed in closed form from the canonical
38+ // induction variable , so it adds neither an iter_arg nor a loop result .
3739// CHECK -LABEL : func .func @typed_loop (
3840// CHECK -SAME : %[[LB :.*]]: i32 , %[[UB :.*]]: i32 , %[[STEP :.*]]: i32 ,
3941// CHECK -SAME : %[[ADDR :.*]]: !fir .ref <i32 >) {
@@ -45,11 +47,13 @@ func.func @simple_loop(%arg0: !fir.ref<!fir.array<100xi32>>) {
4547// CHECK : %[[TRIP :.*]] = arith .divsi %[[DISTANCE ]], %[[STEP_IDX ]] : index
4648// CHECK : %[[C0 :.*]] = arith .constant 0 : index
4749// CHECK : %[[C1 :.*]] = arith .constant 1 : index
48- // CHECK : scf .for %{{.*}} = %[[C0 ]] to %[[TRIP ]] step %[[C1 ]] iter_args (%[[IV :.*]] = %[[LB ]]) -> (i32 ) {
49- // CHECK : %[[NEXT :.*]] = arith .addi %[[IV ]], %[[STEP ]] overflow <nsw > : i32
50+ // CHECK : scf .for %[[I :.*]] = %[[C0 ]] to %[[TRIP ]] step %[[C1 ]] {
51+ // CHECK : %[[I_TYPED :.*]] = fir .convert %[[I ]] : (index ) -> i32
52+ // CHECK : %[[SCALED :.*]] = arith .muli %[[I_TYPED ]], %[[STEP ]] overflow <nsw > : i32
53+ // CHECK : %[[IV :.*]] = arith .addi %[[LB ]], %[[SCALED ]] overflow <nsw > : i32
5054// CHECK : fir .store %[[IV ]] to %[[ADDR ]] : !fir .ref <i32 >
51- // CHECK : scf .yield %[[NEXT ]] : i32
5255// CHECK : }
56+ // CHECK -NOT : iter_args
5357func .func @typed_loop (%lb : i32 , %ub : i32 , %step : i32 ,
5458 %addr : !fir .ref <i32 >) {
5559 fir .do_loop %iv = %lb to %ub step %step : i32 {
@@ -60,6 +64,68 @@ func.func @typed_loop(%lb: i32, %ub: i32, %step: i32,
6064
6165// -----
6266
67+ // Only the loop 's own iter_args survive ; the typed IV does not add one.
68+ // CHECK -LABEL : func .func @typed_loop_iter_args (
69+ // CHECK : %[[C0 :.*]] = arith .constant 0 : i32
70+ // CHECK : %[[C1 :.*]] = arith .constant 1 : i32
71+ // CHECK : %[[TRIP :.*]] = arith .divsi
72+ // CHECK : %[[C0_IDX :.*]] = arith .constant 0 : index
73+ // CHECK : %[[C1_IDX :.*]] = arith .constant 1 : index
74+ // CHECK : %[[RES :.*]] = scf .for %[[I :.*]] = %[[C0_IDX ]] to %[[TRIP ]] step %[[C1_IDX ]] iter_args (%[[ACC :.*]] = %[[C0 ]]) -> (i32 ) {
75+ // CHECK : %[[I_TYPED :.*]] = fir .convert %[[I ]] : (index ) -> i32
76+ // CHECK : %[[SCALED :.*]] = arith .muli %[[I_TYPED ]], %[[C1 ]] overflow <nsw > : i32
77+ // CHECK : %[[IV :.*]] = arith .addi %[[C1 ]], %[[SCALED ]] overflow <nsw > : i32
78+ // CHECK : %[[SUM :.*]] = arith .addi %[[ACC ]], %[[IV ]] : i32
79+ // CHECK : scf .yield %[[SUM ]] : i32
80+ // CHECK : }
81+ // CHECK : return %[[RES ]] : i32
82+ func .func @typed_loop_iter_args (%addr : !fir .ref <i32 >) -> i32 {
83+ %c0_i32 = arith .constant 0 : i32
84+ %c1_i32 = arith .constant 1 : i32
85+ %c10_i32 = arith .constant 10 : i32
86+ %r = fir .do_loop %iv = %c1_i32 to %c10_i32 step %c1_i32 iter_args (%acc = %c0_i32 ) -> (i32 ) : i32 {
87+ %v = arith .addi %acc , %iv : i32
88+ fir .result %v : i32
89+ }
90+ return %r : i32
91+ }
92+
93+ // -----
94+
95+ // A negative step is handled by the same closed form , so it does not need an
96+ // iter_arg either .
97+ // CHECK -LABEL : func .func @typed_loop_negative_step (
98+ // CHECK -SAME : %[[ADDR :.*]]: !fir .ref <i32 >) {
99+ // CHECK : %[[C1 :.*]] = arith .constant 1 : i32
100+ // CHECK : %[[C10 :.*]] = arith .constant 10 : i32
101+ // CHECK : %[[CM1 :.*]] = arith .constant -1 : i32
102+ // CHECK : %[[LB_IDX :.*]] = fir .convert %[[C10 ]] : (i32 ) -> index
103+ // CHECK : %[[UB_IDX :.*]] = fir .convert %[[C1 ]] : (i32 ) -> index
104+ // CHECK : %[[STEP_IDX :.*]] = fir .convert %[[CM1 ]] : (i32 ) -> index
105+ // CHECK : %[[DIFF :.*]] = arith .subi %[[UB_IDX ]], %[[LB_IDX ]] : index
106+ // CHECK : %[[DISTANCE :.*]] = arith .addi %[[DIFF ]], %[[STEP_IDX ]] : index
107+ // CHECK : %[[TRIP :.*]] = arith .divsi %[[DISTANCE ]], %[[STEP_IDX ]] : index
108+ // CHECK : %[[C0 :.*]] = arith .constant 0 : index
109+ // CHECK : %[[C1_IDX :.*]] = arith .constant 1 : index
110+ // CHECK : scf .for %[[I :.*]] = %[[C0 ]] to %[[TRIP ]] step %[[C1_IDX ]] {
111+ // CHECK : %[[I_TYPED :.*]] = fir .convert %[[I ]] : (index ) -> i32
112+ // CHECK : %[[SCALED :.*]] = arith .muli %[[I_TYPED ]], %[[CM1 ]] overflow <nsw > : i32
113+ // CHECK : %[[IV :.*]] = arith .addi %[[C10 ]], %[[SCALED ]] overflow <nsw > : i32
114+ // CHECK : fir .store %[[IV ]] to %[[ADDR ]] : !fir .ref <i32 >
115+ // CHECK : }
116+ // CHECK -NOT : iter_args
117+ func .func @typed_loop_negative_step (%addr : !fir .ref <i32 >) {
118+ %c1_i32 = arith .constant 1 : i32
119+ %c10_i32 = arith .constant 10 : i32
120+ %cm1_i32 = arith .constant -1 : i32
121+ fir .do_loop %iv = %c10_i32 to %c1_i32 step %cm1_i32 : i32 {
122+ fir .store %iv to %addr : !fir .ref <i32 >
123+ }
124+ return
125+ }
126+
127+ // -----
128+
63129// CHECK -LABEL : func .func @loop_with_negtive_step (
64130// CHECK -SAME : %[[ARG0 :.*]]: !fir .ref <!fir .array <100xi32 >>) {
65131// CHECK : %[[VAL_0 :.*]] = arith .constant 100 : index
@@ -73,8 +139,8 @@ func.func @typed_loop(%lb: i32, %ub: i32, %step: i32,
73139// CHECK : %[[VAL_8 :.*]] = arith .constant 0 : index
74140// CHECK : %[[VAL_9 :.*]] = arith .constant 1 : index
75141// CHECK : scf .for %[[VAL_10 :.*]] = %[[VAL_8 ]] to %[[VAL_7 ]] step %[[VAL_9 ]] {
76- // CHECK : %[[VAL_11 :.*]] = arith .muli %[[VAL_10 ]], %[[VAL_2 ]] : index
77- // CHECK : %[[VAL_12 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_11 ]] : index
142+ // CHECK : %[[VAL_11 :.*]] = arith .muli %[[VAL_10 ]], %[[VAL_2 ]] overflow < nsw > : index
143+ // CHECK : %[[VAL_12 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_11 ]] overflow < nsw > : index
78144// CHECK : %[[VAL_13 :.*]] = fir .array_coor %[[ARG0 ]](%[[VAL_3 ]]) %[[VAL_12 ]] : (!fir .ref <!fir .array <100xi32 >>, !fir .shape <1 >, index ) -> !fir .ref <i32 >
79145// CHECK : fir .store %[[VAL_4 ]] to %[[VAL_13 ]] : !fir .ref <i32 >
80146// CHECK : }
@@ -108,8 +174,8 @@ func.func @loop_with_negtive_step(%arg0: !fir.ref<!fir.array<100xi32>>) {
108174// CHECK : %[[VAL_7 :.*]] = arith .constant 0 : index
109175// CHECK : %[[VAL_8 :.*]] = arith .constant 1 : index
110176// CHECK : %[[VAL_9 :.*]] = scf .for %[[VAL_10 :.*]] = %[[VAL_7 ]] to %[[VAL_6 ]] step %[[VAL_8 ]] iter_args (%[[VAL_11 :.*]] = %[[VAL_1 ]]) -> (i32 ) {
111- // CHECK : %[[VAL_12 :.*]] = arith .muli %[[VAL_10 ]], %[[VAL_0 ]] : index
112- // CHECK : %[[VAL_13 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_12 ]] : index
177+ // CHECK : %[[VAL_12 :.*]] = arith .muli %[[VAL_10 ]], %[[VAL_0 ]] overflow < nsw > : index
178+ // CHECK : %[[VAL_13 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_12 ]] overflow < nsw > : index
113179// CHECK : %[[VAL_14 :.*]] = fir .array_coor %[[ARG0 ]](%[[VAL_3 ]]) %[[VAL_13 ]] : (!fir .ref <!fir .array <100xi32 >>, !fir .shape <1 >, index ) -> !fir .ref <i32 >
114180// CHECK : %[[VAL_15 :.*]] = fir .load %[[VAL_14 ]] : !fir .ref <i32 >
115181// CHECK : %[[VAL_16 :.*]] = arith .addi %[[VAL_11 ]], %[[VAL_15 ]] : i32
@@ -149,8 +215,8 @@ func.func @loop_with_results(%arg0: !fir.ref<!fir.array<100xi32>>, %arg1: !fir.r
149215// CHECK : %[[VAL_8 :.*]] = arith .constant 0 : index
150216// CHECK : %[[VAL_9 :.*]] = arith .constant 1 : index
151217// CHECK : %[[VAL_10 :.*]]:2 = scf .for %[[VAL_11 :.*]] = %[[VAL_8 ]] to %[[VAL_7 ]] step %[[VAL_9 ]] iter_args (%[[VAL_12 :.*]] = %[[VAL_0 ]], %[[VAL_13 :.*]] = %[[VAL_1 ]]) -> (index , i32 ) {
152- // CHECK : %[[VAL_14 :.*]] = arith .muli %[[VAL_11 ]], %[[VAL_0 ]] : index
153- // CHECK : %[[VAL_15 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_14 ]] : index
218+ // CHECK : %[[VAL_14 :.*]] = arith .muli %[[VAL_11 ]], %[[VAL_0 ]] overflow < nsw > : index
219+ // CHECK : %[[VAL_15 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_14 ]] overflow < nsw > : index
154220// CHECK : %[[VAL_16 :.*]] = fir .array_coor %[[ARG0 ]](%[[VAL_4 ]]) %[[VAL_15 ]] : (!fir .ref <!fir .array <100xi32 >>, !fir .shape <1 >, index ) -> !fir .ref <i32 >
155221// CHECK : %[[VAL_17 :.*]] = fir .load %[[VAL_16 ]] : !fir .ref <i32 >
156222// CHECK : %[[VAL_18 :.*]] = arith .addi %[[VAL_15 ]], %[[VAL_0 ]] overflow <nsw > : index
@@ -244,8 +310,8 @@ func.func @loop_with_final_value_and_result() {
244310// CHECK : %[[CONSTANT_4 :.*]] = arith .constant 1 : index
245311// PARALLEL : scf .parallel (%[[VAL_0 :.*]]) = (%[[CONSTANT_3 ]]) to (%[[DIVSI_0 ]]) step (%[[CONSTANT_4 ]]) {
246312// NO -PARALLEL : scf .for %[[VAL_0 :.*]] = %[[CONSTANT_3 ]] to %[[DIVSI_0 ]] step %[[CONSTANT_4 ]] {
247- // CHECK : %[[MULI_0 :.*]] = arith .muli %[[VAL_0 ]], %[[CONSTANT_0 ]] : index
248- // CHECK : %[[ADDI_1 :.*]] = arith .addi %[[CONSTANT_0 ]], %[[MULI_0 ]] : index
313+ // CHECK : %[[MULI_0 :.*]] = arith .muli %[[VAL_0 ]], %[[CONSTANT_0 ]] overflow < nsw > : index
314+ // CHECK : %[[ADDI_1 :.*]] = arith .addi %[[CONSTANT_0 ]], %[[MULI_0 ]] overflow < nsw > : index
249315// CHECK : %[[ARRAY_COOR_0 :.*]] = fir .array_coor %[[ARG0 ]](%[[SHAPE_0 ]]) %[[ADDI_1 ]] : (!fir .ref <!fir .array <100xi32 >>, !fir .shape <1 >, index ) -> !fir .ref <i32 >
250316// CHECK : fir .store %[[CONSTANT_2 ]] to %[[ARRAY_COOR_0 ]] : !fir .ref <i32 >
251317// PARALLEL : scf .reduce
@@ -282,8 +348,8 @@ func.func @loop_with_unordered_attr(%arg0: !fir.ref<!fir.array<100xi32>>) {
282348// CHECK : %[[VAL_8 :.*]] = arith .constant 0 : index
283349// CHECK : %[[VAL_9 :.*]] = arith .constant 1 : index
284350// CHECK : scf .for %[[VAL_10 :.*]] = %[[VAL_8 ]] to %[[VAL_7 ]] step %[[VAL_9 ]] {
285- // CHECK : %[[VAL_11 :.*]] = arith .muli %[[VAL_10 ]], %[[VAL_0 ]] : index
286- // CHECK : %[[VAL_12 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_11 ]] : index
351+ // CHECK : %[[VAL_11 :.*]] = arith .muli %[[VAL_10 ]], %[[VAL_0 ]] overflow < nsw > : index
352+ // CHECK : %[[VAL_12 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_11 ]] overflow < nsw > : index
287353// CHECK : %[[VAL_13 :.*]] = fir .array_coor %[[ARG0 ]](%[[VAL_4 ]]) %[[VAL_12 ]] : (!fir .ref <!fir .array <100xi32 >>, !fir .shape <1 >, index ) -> !fir .ref <i32 >
288354// CHECK : %[[VAL_14 :.*]] = fir .load %[[VAL_13 ]] : !fir .ref <i32 >
289355// CHECK : %[[VAL_15 :.*]] = fir .load %[[VAL_3 ]] : !fir .ref <i32 >
@@ -326,16 +392,16 @@ func.func @loop_with_attribute(%arg0: !fir.ref<!fir.array<100xi32>>, %arg1: !fir
326392// CHECK : %[[VAL_7 :.*]] = arith .constant 0 : index
327393// CHECK : %[[VAL_8 :.*]] = arith .constant 1 : index
328394// CHECK : scf .for %[[VAL_9 :.*]] = %[[VAL_7 ]] to %[[VAL_6 ]] step %[[VAL_8 ]] {
329- // CHECK : %[[VAL_10 :.*]] = arith .muli %[[VAL_9 ]], %[[VAL_0 ]] : index
330- // CHECK : %[[VAL_11 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_10 ]] : index
395+ // CHECK : %[[VAL_10 :.*]] = arith .muli %[[VAL_9 ]], %[[VAL_0 ]] overflow < nsw > : index
396+ // CHECK : %[[VAL_11 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_10 ]] overflow < nsw > : index
331397// CHECK : %[[VAL_12 :.*]] = arith .subi %[[VAL_2 ]], %[[VAL_0 ]] : index
332398// CHECK : %[[VAL_13 :.*]] = arith .addi %[[VAL_12 ]], %[[VAL_0 ]] : index
333399// CHECK : %[[VAL_14 :.*]] = arith .divsi %[[VAL_13 ]], %[[VAL_0 ]] : index
334400// CHECK : %[[VAL_15 :.*]] = arith .constant 0 : index
335401// CHECK : %[[VAL_16 :.*]] = arith .constant 1 : index
336402// CHECK : scf .for %[[VAL_17 :.*]] = %[[VAL_15 ]] to %[[VAL_14 ]] step %[[VAL_16 ]] {
337- // CHECK : %[[VAL_18 :.*]] = arith .muli %[[VAL_17 ]], %[[VAL_0 ]] : index
338- // CHECK : %[[VAL_19 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_18 ]] : index
403+ // CHECK : %[[VAL_18 :.*]] = arith .muli %[[VAL_17 ]], %[[VAL_0 ]] overflow < nsw > : index
404+ // CHECK : %[[VAL_19 :.*]] = arith .addi %[[VAL_0 ]], %[[VAL_18 ]] overflow < nsw > : index
339405// CHECK : %[[VAL_20 :.*]] = fir .array_coor %[[ARG0 ]](%[[VAL_3 ]]) %[[VAL_19 ]], %[[VAL_11 ]] : (!fir .ref <!fir .array <100x100xi32 >>, !fir .shape <2 >, index , index ) -> !fir .ref <i32 >
340406// CHECK : fir .store %[[VAL_1 ]] to %[[VAL_20 ]] : !fir .ref <i32 >
341407// CHECK : }
0 commit comments