@@ -1096,6 +1096,192 @@ bb4(%31 : $Builtin.Int32):
10961096 return %32 : $Int32
10971097}
10981098
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+
10991285sil public_external [_semantics "array.check_subscript"] @checkbounds_no_meth : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> _DependenceToken {
11001286 bb0(%0: $Int32, %1: $Bool, %2: $ArrayInt):
11011287 unreachable
0 commit comments