@@ -1096,6 +1096,192 @@ bb4(%31 : $Builtin.Int32):
1096
1096
return %32 : $Int32
1097
1097
}
1098
1098
1099
+ // SIL pattern for :
1100
+ // func hoist_new_ind_pattern1(_ a : [Int]) {
1101
+ // for i in 0...4 {
1102
+ // ...a[i]...
1103
+ // }
1104
+ // }
1105
+ // Bounds check for the array should be hoisted out of the loop
1106
+ //
1107
+ // RANGECHECK-LABEL: sil @hoist_new_ind_pattern1 :
1108
+ // RANGECHECK: [[CB:%.*]] = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1109
+ // RANGECHECK: [[MINUS1:%.*]] = integer_literal $Builtin.Int1, -1
1110
+ // RANGECHECK: [[TRUE:%.*]] = struct $Bool ([[MINUS1]] : $Builtin.Int1)
1111
+ // RANGECHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
1112
+ // RANGECHECK: [[INTZERO:%.*]] = struct $Int32 ([[ZERO]] : $Builtin.Int32)
1113
+ // RANGECHECK: [[FOUR:%.*]] = integer_literal $Builtin.Int32, 4
1114
+ // RANGECHECK: [[ONE:%.*]] = integer_literal $Builtin.Int32, 1
1115
+ // RANGECHECK: [[ANOTHERTRUE:%.*]] = integer_literal $Builtin.Int1, -1
1116
+ // RANGECHECK: [[INTONEADD:%.*]] = builtin "sadd_with_overflow_Int32"([[ZERO]] : $Builtin.Int32, [[ONE]] : $Builtin.Int32, [[ANOTHERTRUE]] : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1117
+ // RANGECHECK: [[INTONEEX:%.*]] = tuple_extract [[INTONEADD]] : $(Builtin.Int32, Builtin.Int1), 0
1118
+ // RANGECHECK: [[INTONE:%.*]] = struct $Int32 ([[INTONEEX]] : $Builtin.Int32)
1119
+ // RANGECHECK: [[A1:%.*]] = apply [[CB]]([[INTONE]], [[TRUE]], %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1120
+ // RANGECHECK: [[INTFOUR:%.*]] = struct $Int32 ([[FOUR]] : $Builtin.Int32)
1121
+ // RANGECHECK: [[A2:%.*]] = apply [[CB]]([[INTFOUR]], [[TRUE]], %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1122
+ // RANGECHECK: bb1
1123
+ // RANGECHECK-NOT: apply [[CB]]
1124
+ // RANGECHECK-LABEL: } // end sil function 'hoist_new_ind_pattern1'
1125
+ sil @hoist_new_ind_pattern1 : $@convention(thin) (@owned ArrayInt) -> () {
1126
+ bb0(%0 : $ArrayInt):
1127
+ %minus1 = integer_literal $Builtin.Int1, -1
1128
+ %true = struct $Bool(%minus1 : $Builtin.Int1)
1129
+ %zero = integer_literal $Builtin.Int32, 0
1130
+ %int0 = struct $Int32 (%zero : $Builtin.Int32)
1131
+ %one = integer_literal $Builtin.Int32, 1
1132
+ %four = integer_literal $Builtin.Int32, 4
1133
+ %intfour = struct $Int32 (%four : $Builtin.Int32)
1134
+ %cb = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1135
+ apply %cb(%int0, %true, %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1136
+ br bb1(%zero : $Builtin.Int32)
1137
+
1138
+ bb1(%4 : $Builtin.Int32):
1139
+ %5 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %one : $Builtin.Int32, %minus1 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1140
+ %6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0
1141
+ %7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1
1142
+ %8 = struct $Int32 (%6 : $Builtin.Int32)
1143
+ %9 = builtin "cmp_eq_Int32"(%6 : $Builtin.Int32, %four : $Builtin.Int32) : $Builtin.Int1
1144
+ apply %cb(%8, %true, %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1145
+ cond_br %9, bb3, bb2
1146
+
1147
+ bb2:
1148
+ br bb1(%6 : $Builtin.Int32)
1149
+
1150
+ bb3:
1151
+ %t = tuple ()
1152
+ return %t : $()
1153
+ }
1154
+
1155
+ // Currently this is not optimized because the induction var increment is 2
1156
+ // Support for this can be added by updating induction variable analysis
1157
+ // RANGECHECK-LABEL: sil @hoist_new_ind_pattern2 :
1158
+ // RANGECHECK: [[CB:%.*]] = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1159
+ // RANGECHECK: bb1
1160
+ // RANGECHECK: apply [[CB]]
1161
+ // RANGECHECK-LABEL: } // end sil function 'hoist_new_ind_pattern2'
1162
+ sil @hoist_new_ind_pattern2 : $@convention(thin) (@owned ArrayInt) -> () {
1163
+ bb0(%0 : $ArrayInt):
1164
+ %minus1 = integer_literal $Builtin.Int1, -1
1165
+ %true = struct $Bool(%minus1 : $Builtin.Int1)
1166
+ %zero = integer_literal $Builtin.Int32, 0
1167
+ %int0 = struct $Int32 (%zero : $Builtin.Int32)
1168
+ %two = integer_literal $Builtin.Int32, 2
1169
+ %four = integer_literal $Builtin.Int32, 4
1170
+ %intfour = struct $Int32 (%four : $Builtin.Int32)
1171
+ %cb = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1172
+ apply %cb(%int0, %true, %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1173
+ br bb1(%zero : $Builtin.Int32)
1174
+
1175
+ bb1(%4 : $Builtin.Int32):
1176
+ %5 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %two : $Builtin.Int32, %minus1 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1177
+ %6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0
1178
+ %7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1
1179
+ cond_fail %7 : $Builtin.Int1
1180
+ %8 = struct $Int32 (%6 : $Builtin.Int32)
1181
+ %9 = builtin "cmp_eq_Int32"(%6 : $Builtin.Int32, %four : $Builtin.Int32) : $Builtin.Int1
1182
+ apply %cb(%8, %true, %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1183
+ cond_br %9, bb3, bb2
1184
+
1185
+ bb2:
1186
+ br bb1(%6 : $Builtin.Int32)
1187
+
1188
+ bb3:
1189
+ %t = tuple ()
1190
+ return %t : $()
1191
+ }
1192
+
1193
+ // This is currently not optimized because access function is not recognized
1194
+ // SIL pattern for :
1195
+ // for var index in 0...24
1196
+ // {
1197
+ // ...a[index + index]...
1198
+ // }
1199
+ //
1200
+ // RANGECHECK-LABEL: sil @hoist_new_ind_pattern3 :
1201
+ // RANGECHECK: [[CB:%.*]] = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1202
+ // RANGECHECK: bb1
1203
+ // RANGECHECK: apply [[CB]]
1204
+ // RANGECHECK-LABEL: } // end sil function 'hoist_new_ind_pattern3'
1205
+ sil @hoist_new_ind_pattern3 : $@convention(thin) (@owned ArrayInt) -> () {
1206
+ bb0(%0 : $ArrayInt):
1207
+ %minus1 = integer_literal $Builtin.Int1, -1
1208
+ %true = struct $Bool(%minus1 : $Builtin.Int1)
1209
+ %zero = integer_literal $Builtin.Int32, 0
1210
+ %int0 = struct $Int32 (%zero : $Builtin.Int32)
1211
+ %one = integer_literal $Builtin.Int32, 1
1212
+ %four = integer_literal $Builtin.Int32, 4
1213
+ %intfour = struct $Int32 (%four : $Builtin.Int32)
1214
+ %cb = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1215
+ apply %cb(%int0, %true, %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1216
+ br bb1(%zero : $Builtin.Int32)
1217
+
1218
+ bb1(%4 : $Builtin.Int32):
1219
+ %5 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %one : $Builtin.Int32, %minus1 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1220
+ %6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0
1221
+ %7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1
1222
+ %8 = struct $Int32 (%6 : $Builtin.Int32)
1223
+ %9 = builtin "cmp_eq_Int32"(%6 : $Builtin.Int32, %four : $Builtin.Int32) : $Builtin.Int1
1224
+ %10 = builtin "sadd_with_overflow_Int32"(%6 : $Builtin.Int32, %6 : $Builtin.Int32, %minus1 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1225
+ %11 = tuple_extract %10 : $(Builtin.Int32, Builtin.Int1), 0
1226
+ %12 = tuple_extract %10 : $(Builtin.Int32, Builtin.Int1), 1
1227
+ %13 = struct $Int32 (%11 : $Builtin.Int32)
1228
+ apply %cb(%13, %true, %0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1229
+ cond_br %9, bb3, bb2
1230
+
1231
+ bb2:
1232
+ br bb1(%6 : $Builtin.Int32)
1233
+
1234
+ bb3:
1235
+ %t = tuple ()
1236
+ return %t : $()
1237
+ }
1238
+
1239
+
1240
+ // RANGECHECK-LABEL: sil @hoist_new_ind_pattern4 :
1241
+ // RANGECHECK: [[MINUS1:%.*]] = integer_literal $Builtin.Int1, -1
1242
+ // RANGECHECK: [[TRUE:%.*]] = struct $Bool ([[MINUS1]] : $Builtin.Int1)
1243
+ // RANGECHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
1244
+ // RANGECHECK: [[INTZERO:%.*]] = struct $Int32 ([[ZERO]] : $Builtin.Int32)
1245
+ // RANGECHECK: [[CB:%.*]] = function_ref @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array<Int>) -> _DependenceToken
1246
+ // RANGECHECK: apply [[CB]]([[INTZERO]], [[TRUE]], %0) : $@convention(method) (Int32, Bool, @owned Array<Int>) -> _DependenceToken
1247
+ // RANGECHECK-NOT: apply [[CB]]
1248
+ // RANGECHECK-LABEL: } // end sil function 'hoist_new_ind_pattern4'
1249
+ // for i in 0..<a.count
1250
+ // {
1251
+ // ...a[i]...
1252
+ // }
1253
+ sil @hoist_new_ind_pattern4 : $@convention(thin) (@owned Array<Int>) -> () {
1254
+ bb0(%0 : $Array<Int>):
1255
+ %minus1 = integer_literal $Builtin.Int1, -1
1256
+ %true = struct $Bool(%minus1 : $Builtin.Int1)
1257
+ %zero = integer_literal $Builtin.Int32, 0
1258
+ %int0 = struct $Int32 (%zero : $Builtin.Int32)
1259
+ %one = integer_literal $Builtin.Int32, 1
1260
+ %f1 = function_ref @getCount2 : $@convention(method) (@owned Array<Int>) -> Int32
1261
+ %t1 = apply %f1(%0) : $@convention(method) (@owned Array<Int>) -> Int32
1262
+ %count = struct_extract %t1 : $Int32, #Int32._value
1263
+ %cb = function_ref @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array<Int>) -> _DependenceToken
1264
+ apply %cb(%int0, %true, %0) : $@convention(method) (Int32, Bool, @owned Array<Int>) -> _DependenceToken
1265
+ br bb1(%zero : $Builtin.Int32)
1266
+
1267
+ bb1(%4 : $Builtin.Int32):
1268
+ %5 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %one : $Builtin.Int32, %minus1 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1269
+ %6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0
1270
+ %7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1
1271
+ cond_fail %7 : $Builtin.Int1
1272
+ %8 = struct $Int32 (%6 : $Builtin.Int32)
1273
+ apply %cb(%8, %true, %0) : $@convention(method) (Int32, Bool, @owned Array<Int>) -> _DependenceToken
1274
+ %9 = builtin "cmp_eq_Int32"(%6 : $Builtin.Int32, %count : $Builtin.Int32) : $Builtin.Int1
1275
+ cond_br %9, bb3, bb2
1276
+
1277
+ bb2:
1278
+ br bb1(%6 : $Builtin.Int32)
1279
+
1280
+ bb3:
1281
+ %t = tuple ()
1282
+ return %t : $()
1283
+ }
1284
+
1099
1285
sil public_external [_semantics "array.check_subscript"] @checkbounds_no_meth : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> _DependenceToken {
1100
1286
bb0(%0: $Int32, %1: $Bool, %2: $ArrayInt):
1101
1287
unreachable
0 commit comments