lower: use Elem for all internal bounded pointer arithmetic

86e83bebc4bd71b7a3304cac65540bc6cca1dc2a9b8061fcce9f44001c1aa7b4
Convert remaining emitElem call sites to Elem where possible:
- Array fill loop: Elem with count as bound
- Byte copy loop: Elem with size as bound
- Slice append: Elem with capacity as bound
- Slice delete: already converted in previous commit

Two emitElem uses remain and cannot use Elem:
- Slice re-slicing: start == len is valid (empty trailing slice),
  but Elem requires idx < len (strict). Needs a future ElemRange
  instruction with idx <= len semantics.
- Constant-index array access: validated by resolver at compile
  time, verifier checks statically via allocation bounds.

Also: Elem now produces Ptr(stride) in the verifier, so subsequent
load/store at the element pointer is bounds-checked against the
element size.
Alexis Sellier committed ago 1 parent 0202a038
lib/std/lang/lower.rad +11 -6
5219 5219
    try emitJmpWithArg(self, header, il::Val::Imm(0));
5220 5220
    switchToBlock(self, header);
5221 5221
    try emitBrCmp(self, il::CmpOp::Ult, il::Type::W32, il::Val::Reg(iReg), count, body, done);
5222 5222
5223 5223
    try switchToAndSeal(self, body);
5224 -
    let dstElem = emitElem(self, elemSize, dst, il::Val::Reg(iReg));
5224 +
    let dstElem = nextReg(self);
5225 +
    emit(self, il::Instr::Elem { dst: dstElem, base: dst, idx: il::Val::Reg(iReg), len: count, stride: elemSize });
5225 5226
    try emitStore(self, dstElem, 0, elemType, value);
5226 5227
5227 5228
    let nextI = emitTypedBinOp(
5228 5229
        self, il::BinOp::Add, il::Type::W32, il::Val::Reg(iReg), il::Val::Imm(1)
5229 5230
    );
5345 5346
    }
5346 5347
    // Switch to loop body.
5347 5348
    try switchToAndSeal(self, bodyBlock);
5348 5349
5349 5350
    // Emit element binding, only for collections.
5350 -
    // Reads the element at the current index using a bounds-checked `elem`
5351 -
    // instruction so the verifier can validate the access locally.
5351 +
    // Uses bounds-checked Elem so the verifier can validate locally.
5352 5352
    if let case ForIter::Collection { valVar, idxVar, dataReg, lengthVal, elemType } = *iter {
5353 5353
        if let v = valVar {
5354 5354
            let curIdx = try useVar(self, idxVar);
5355 5355
            let elemLayout = resolver::getTypeLayout(*elemType);
5356 5356
            let elemReg = nextReg(self);
6242 6242
    try emitBrCmp(self, il::CmpOp::Ult, il::Type::W32, il::Val::Reg(iReg), size, body, done);
6243 6243
6244 6244
    // Body: load byte from source, store to destination, increment counter.
6245 6245
    try switchToAndSeal(self, body);
6246 6246
6247 -
    let srcElem = emitElem(self, 1, src, il::Val::Reg(iReg));
6247 +
    let srcElem = nextReg(self);
6248 +
    emit(self, il::Instr::Elem { dst: srcElem, base: src, idx: il::Val::Reg(iReg), len: size, stride: 1 });
6248 6249
    let byteReg = nextReg(self);
6249 6250
    emit(self, il::Instr::Load { typ: il::Type::W8, dst: byteReg, src: srcElem, offset: 0 });
6250 6251
6251 -
    let dstElem = emitElem(self, 1, dst, il::Val::Reg(iReg));
6252 +
    let dstElem = nextReg(self);
6253 +
    emit(self, il::Instr::Elem { dst: dstElem, base: dst, idx: il::Val::Reg(iReg), len: size, stride: 1 });
6252 6254
    emit(self, il::Instr::Store { typ: il::Type::W8, src: il::Val::Reg(byteReg), dst: dstElem, offset: 0 });
6253 6255
6254 6256
    let nextI = emitTypedBinOp(self, il::BinOp::Add, il::Type::W32, il::Val::Reg(iReg), il::Val::Imm(1));
6255 6257
    // Jump back to header -- this adds body as a predecessor.
6256 6258
    try emitJmpWithArg(self, header, nextI);
6348 6350
    try switchToAndSeal(self, storeBlock);
6349 6351
6350 6352
    // -- @store block ---------------------------------------------------------
6351 6353
6352 6354
    // Store element at `ptr + len * stride`.
6355 +
    // Store element at `ptr + len * stride`. Use Elem with capacity as bound.
6353 6356
    let ptrReg = loadSlicePtr(self, sliceReg);
6354 -
    let elemDst = emitElem(self, stride, ptrReg, lenVal);
6357 +
    let storeCap = loadSliceCap(self, sliceReg);
6358 +
    let elemDst = nextReg(self);
6359 +
    emit(self, il::Instr::Elem { dst: elemDst, base: ptrReg, idx: lenVal, len: storeCap, stride });
6355 6360
    try emitStore(self, elemDst, 0, *elemType, elemVal);
6356 6361
6357 6362
    // Increment len.
6358 6363
    let newLen = emitTypedBinOp(self, il::BinOp::Add, il::Type::W32, lenVal, il::Val::Imm(1));
6359 6364
    emitStoreW32At(self, newLen, sliceReg, SLICE_LEN_OFFSET);
test/tests/slice.append.ril +236 -233
67 67
    load w32 %9 %8 8;
68 68
    load w32 %10 %8 12;
69 69
    br.ult w32 %9 %10 @append.store1 @append.grow2;
70 70
  @append.store1
71 71
    load ptr %24 %8 0;
72 -
    mul w64 %25 %9 4;
73 -
    add ptr %26 %24 %25;
72 +
    load w32 %25 %8 12;
73 +
    elem %26 %24 %9 %25 4;
74 74
    store w32 10 %26 0;
75 75
    add w32 %27 %9 1;
76 76
    store w32 %27 %8 8;
77 77
    load w32 %32 %8 8;
78 78
    load w32 %33 %8 12;
88 88
    mul w32 %18 %9 4;
89 89
    jmp @append3(0);
90 90
  @append3(w32 %19)
91 91
    br.ult w32 %19 %18 @append4 @append5;
92 92
  @append4
93 -
    add ptr %20 %17 %19;
93 +
    elem %20 %17 %19 %18 1;
94 94
    load w8 %21 %20 0;
95 -
    add ptr %22 %16 %19;
95 +
    elem %22 %16 %19 %18 1;
96 96
    store w8 %21 %22 0;
97 97
    add w32 %23 %19 1;
98 98
    jmp @append3(%23);
99 99
  @append5
100 100
    store ptr %16 %8 0;
101 101
    store w32 %12 %8 12;
102 102
    jmp @append.store1;
103 103
  @append.store6
104 104
    load ptr %47 %8 0;
105 -
    mul w64 %48 %32 4;
106 -
    add ptr %49 %47 %48;
105 +
    load w32 %48 %8 12;
106 +
    elem %49 %47 %32 %48 4;
107 107
    store w32 20 %49 0;
108 108
    add w32 %50 %32 1;
109 109
    store w32 %50 %8 8;
110 110
    load w32 %55 %8 8;
111 111
    load w32 %56 %8 12;
121 121
    mul w32 %41 %32 4;
122 122
    jmp @append8(0);
123 123
  @append8(w32 %42)
124 124
    br.ult w32 %42 %41 @append9 @append10;
125 125
  @append9
126 -
    add ptr %43 %40 %42;
126 +
    elem %43 %40 %42 %41 1;
127 127
    load w8 %44 %43 0;
128 -
    add ptr %45 %39 %42;
128 +
    elem %45 %39 %42 %41 1;
129 129
    store w8 %44 %45 0;
130 130
    add w32 %46 %42 1;
131 131
    jmp @append8(%46);
132 132
  @append10
133 133
    store ptr %39 %8 0;
134 134
    store w32 %35 %8 12;
135 135
    jmp @append.store6;
136 136
  @append.store11
137 137
    load ptr %70 %8 0;
138 -
    mul w64 %71 %55 4;
139 -
    add ptr %72 %70 %71;
138 +
    load w32 %71 %8 12;
139 +
    elem %72 %70 %55 %71 4;
140 140
    store w32 30 %72 0;
141 141
    add w32 %73 %55 1;
142 142
    store w32 %73 %8 8;
143 143
    load w32 %76 %8 8;
144 144
    br.ne w32 %76 3 @then16 @merge17;
153 153
    mul w32 %64 %55 4;
154 154
    jmp @append13(0);
155 155
  @append13(w32 %65)
156 156
    br.ult w32 %65 %64 @append14 @append15;
157 157
  @append14
158 -
    add ptr %66 %63 %65;
158 +
    elem %66 %63 %65 %64 1;
159 159
    load w8 %67 %66 0;
160 -
    add ptr %68 %62 %65;
160 +
    elem %68 %62 %65 %64 1;
161 161
    store w8 %67 %68 0;
162 162
    add w32 %69 %65 1;
163 163
    jmp @append13(%69);
164 164
  @append15
165 165
    store ptr %62 %8 0;
200 200
    load w32 %92 %8 8;
201 201
    load w32 %93 %8 12;
202 202
    br.ult w32 %92 %93 @append.store26 @append.grow27;
203 203
  @append.store26
204 204
    load ptr %107 %8 0;
205 -
    mul w64 %108 %92 4;
206 -
    add ptr %109 %107 %108;
205 +
    load w32 %108 %8 12;
206 +
    elem %109 %107 %92 %108 4;
207 207
    store w32 40 %109 0;
208 208
    add w32 %110 %92 1;
209 209
    store w32 %110 %8 8;
210 210
    load w32 %113 %8 8;
211 211
    br.ne w32 %113 4 @then31 @merge32;
220 220
    mul w32 %101 %92 4;
221 221
    jmp @append28(0);
222 222
  @append28(w32 %102)
223 223
    br.ult w32 %102 %101 @append29 @append30;
224 224
  @append29
225 -
    add ptr %103 %100 %102;
225 +
    elem %103 %100 %102 %101 1;
226 226
    load w8 %104 %103 0;
227 -
    add ptr %105 %99 %102;
227 +
    elem %105 %99 %102 %101 1;
228 228
    store w8 %104 %105 0;
229 229
    add w32 %106 %102 1;
230 230
    jmp @append28(%106);
231 231
  @append30
232 232
    store ptr %99 %8 0;
243 243
    load w32 %117 %8 8;
244 244
    load w32 %118 %8 12;
245 245
    br.ult w32 %117 %118 @append.store35 @append.grow36;
246 246
  @append.store35
247 247
    load ptr %132 %8 0;
248 -
    mul w64 %133 %117 4;
249 -
    add ptr %134 %132 %133;
248 +
    load w32 %133 %8 12;
249 +
    elem %134 %132 %117 %133 4;
250 250
    store w32 50 %134 0;
251 251
    add w32 %135 %117 1;
252 252
    store w32 %135 %8 8;
253 253
    load w32 %138 %8 8;
254 254
    br.ne w32 %138 5 @then40 @merge41;
263 263
    mul w32 %126 %117 4;
264 264
    jmp @append37(0);
265 265
  @append37(w32 %127)
266 266
    br.ult w32 %127 %126 @append38 @append39;
267 267
  @append38
268 -
    add ptr %128 %125 %127;
268 +
    elem %128 %125 %127 %126 1;
269 269
    load w8 %129 %128 0;
270 -
    add ptr %130 %124 %127;
270 +
    elem %130 %124 %127 %126 1;
271 271
    store w8 %129 %130 0;
272 272
    add w32 %131 %127 1;
273 273
    jmp @append37(%131);
274 274
  @append39
275 275
    store ptr %124 %8 0;
314 314
    load w32 %165 %162 8;
315 315
    load w32 %166 %162 12;
316 316
    br.ult w32 %165 %166 @append.store50 @append.grow51;
317 317
  @append.store50
318 318
    load ptr %180 %162 0;
319 -
    mul w64 %181 %165 4;
320 -
    add ptr %182 %180 %181;
319 +
    load w32 %181 %162 12;
320 +
    elem %182 %180 %165 %181 4;
321 321
    store w32 99 %182 0;
322 322
    add w32 %183 %165 1;
323 323
    store w32 %183 %162 8;
324 324
    load w32 %186 %162 8;
325 325
    br.ne w32 %186 1 @then55 @merge56;
334 334
    mul w32 %174 %165 4;
335 335
    jmp @append52(0);
336 336
  @append52(w32 %175)
337 337
    br.ult w32 %175 %174 @append53 @append54;
338 338
  @append53
339 -
    add ptr %176 %173 %175;
339 +
    elem %176 %173 %175 %174 1;
340 340
    load w8 %177 %176 0;
341 -
    add ptr %178 %172 %175;
341 +
    elem %178 %172 %175 %174 1;
342 342
    store w8 %177 %178 0;
343 343
    add w32 %179 %175 1;
344 344
    jmp @append52(%179);
345 345
  @append54
346 346
    store ptr %172 %162 0;
386 386
    load w32 %220 %216 8;
387 387
    load w32 %221 %216 12;
388 388
    br.ult w32 %220 %221 @append.store66 @append.grow67;
389 389
  @append.store66
390 390
    load ptr %235 %216 0;
391 -
    add ptr %236 %235 %220;
392 -
    store w8 171 %236 0;
393 -
    add w32 %237 %220 1;
394 -
    store w32 %237 %216 8;
395 -
    load w32 %242 %216 8;
396 -
    load w32 %243 %216 12;
397 -
    br.ult w32 %242 %243 @append.store71 @append.grow72;
391 +
    load w32 %236 %216 12;
392 +
    elem %237 %235 %220 %236 1;
393 +
    store w8 171 %237 0;
394 +
    add w32 %238 %220 1;
395 +
    store w32 %238 %216 8;
396 +
    load w32 %243 %216 8;
397 +
    load w32 %244 %216 12;
398 +
    br.ult w32 %243 %244 @append.store71 @append.grow72;
398 399
  @append.grow67
399 400
    shl w32 %222 %221 1;
400 401
    or w32 %223 %222 1;
401 402
    load ptr %224 %5 0;
402 403
    load ptr %225 %5 8;
406 407
    mul w32 %229 %220 1;
407 408
    jmp @append68(0);
408 409
  @append68(w32 %230)
409 410
    br.ult w32 %230 %229 @append69 @append70;
410 411
  @append69
411 -
    add ptr %231 %228 %230;
412 +
    elem %231 %228 %230 %229 1;
412 413
    load w8 %232 %231 0;
413 -
    add ptr %233 %227 %230;
414 +
    elem %233 %227 %230 %229 1;
414 415
    store w8 %232 %233 0;
415 416
    add w32 %234 %230 1;
416 417
    jmp @append68(%234);
417 418
  @append70
418 419
    store ptr %227 %216 0;
419 420
    store w32 %223 %216 12;
420 421
    jmp @append.store66;
421 422
  @append.store71
422 -
    load ptr %257 %216 0;
423 -
    add ptr %258 %257 %242;
424 -
    store w8 205 %258 0;
425 -
    add w32 %259 %242 1;
426 -
    store w32 %259 %216 8;
427 -
    load w32 %262 %216 8;
428 -
    br.ne w32 %262 2 @then76 @merge77;
423 +
    load ptr %258 %216 0;
424 +
    load w32 %259 %216 12;
425 +
    elem %260 %258 %243 %259 1;
426 +
    store w8 205 %260 0;
427 +
    add w32 %261 %243 1;
428 +
    store w32 %261 %216 8;
429 +
    load w32 %264 %216 8;
430 +
    br.ne w32 %264 2 @then76 @merge77;
429 431
  @append.grow72
430 -
    shl w32 %244 %243 1;
431 -
    or w32 %245 %244 1;
432 -
    load ptr %246 %5 0;
433 -
    load ptr %247 %5 8;
434 -
    mul w32 %248 %245 1;
435 -
    call ptr %249 %246(%247, %248, 1);
436 -
    load ptr %250 %216 0;
437 -
    mul w32 %251 %242 1;
432 +
    shl w32 %245 %244 1;
433 +
    or w32 %246 %245 1;
434 +
    load ptr %247 %5 0;
435 +
    load ptr %248 %5 8;
436 +
    mul w32 %249 %246 1;
437 +
    call ptr %250 %247(%248, %249, 1);
438 +
    load ptr %251 %216 0;
439 +
    mul w32 %252 %243 1;
438 440
    jmp @append73(0);
439 -
  @append73(w32 %252)
440 -
    br.ult w32 %252 %251 @append74 @append75;
441 +
  @append73(w32 %253)
442 +
    br.ult w32 %253 %252 @append74 @append75;
441 443
  @append74
442 -
    add ptr %253 %250 %252;
443 -
    load w8 %254 %253 0;
444 -
    add ptr %255 %249 %252;
445 -
    store w8 %254 %255 0;
446 -
    add w32 %256 %252 1;
447 -
    jmp @append73(%256);
444 +
    elem %254 %251 %253 %252 1;
445 +
    load w8 %255 %254 0;
446 +
    elem %256 %250 %253 %252 1;
447 +
    store w8 %255 %256 0;
448 +
    add w32 %257 %253 1;
449 +
    jmp @append73(%257);
448 450
  @append75
449 -
    store ptr %249 %216 0;
450 -
    store w32 %245 %216 12;
451 +
    store ptr %250 %216 0;
452 +
    store w32 %246 %216 12;
451 453
    jmp @append.store71;
452 454
  @then76
453 455
    ret 17;
454 456
  @merge77
455 -
    load w32 %263 %216 8;
456 -
    load ptr %264 %216 0;
457 -
    elem %265 %264 0 %263 1;
458 -
    load w8 %266 %265 0;
459 -
    br.ne w8 %266 171 @then78 @merge79;
457 +
    load w32 %265 %216 8;
458 +
    load ptr %266 %216 0;
459 +
    elem %267 %266 0 %265 1;
460 +
    load w8 %268 %267 0;
461 +
    br.ne w8 %268 171 @then78 @merge79;
460 462
  @then78
461 463
    ret 18;
462 464
  @merge79
463 -
    load w32 %267 %216 8;
464 -
    load ptr %268 %216 0;
465 -
    elem %269 %268 1 %267 1;
466 -
    load w8 %270 %269 0;
467 -
    br.ne w8 %270 205 @then80 @merge81;
465 +
    load w32 %269 %216 8;
466 +
    load ptr %270 %216 0;
467 +
    elem %271 %270 1 %269 1;
468 +
    load w8 %272 %271 0;
469 +
    br.ne w8 %272 205 @then80 @merge81;
468 470
  @then80
469 471
    ret 19;
470 472
  @merge81
471 -
    load w32 %273 %216 8;
472 -
    load w32 %274 %216 12;
473 -
    br.ult w32 %273 %274 @append.store82 @append.grow83;
473 +
    load w32 %275 %216 8;
474 +
    load w32 %276 %216 12;
475 +
    br.ult w32 %275 %276 @append.store82 @append.grow83;
474 476
  @append.store82
475 -
    load ptr %288 %216 0;
476 -
    add ptr %289 %288 %273;
477 -
    store w8 239 %289 0;
478 -
    add w32 %290 %273 1;
479 -
    store w32 %290 %216 8;
480 -
    load w32 %293 %216 8;
481 -
    br.ne w32 %293 3 @then87 @merge88;
477 +
    load ptr %290 %216 0;
478 +
    load w32 %291 %216 12;
479 +
    elem %292 %290 %275 %291 1;
480 +
    store w8 239 %292 0;
481 +
    add w32 %293 %275 1;
482 +
    store w32 %293 %216 8;
483 +
    load w32 %296 %216 8;
484 +
    br.ne w32 %296 3 @then87 @merge88;
482 485
  @append.grow83
483 -
    shl w32 %275 %274 1;
484 -
    or w32 %276 %275 1;
485 -
    load ptr %277 %5 0;
486 -
    load ptr %278 %5 8;
487 -
    mul w32 %279 %276 1;
488 -
    call ptr %280 %277(%278, %279, 1);
489 -
    load ptr %281 %216 0;
490 -
    mul w32 %282 %273 1;
486 +
    shl w32 %277 %276 1;
487 +
    or w32 %278 %277 1;
488 +
    load ptr %279 %5 0;
489 +
    load ptr %280 %5 8;
490 +
    mul w32 %281 %278 1;
491 +
    call ptr %282 %279(%280, %281, 1);
492 +
    load ptr %283 %216 0;
493 +
    mul w32 %284 %275 1;
491 494
    jmp @append84(0);
492 -
  @append84(w32 %283)
493 -
    br.ult w32 %283 %282 @append85 @append86;
495 +
  @append84(w32 %285)
496 +
    br.ult w32 %285 %284 @append85 @append86;
494 497
  @append85
495 -
    add ptr %284 %281 %283;
496 -
    load w8 %285 %284 0;
497 -
    add ptr %286 %280 %283;
498 -
    store w8 %285 %286 0;
499 -
    add w32 %287 %283 1;
500 -
    jmp @append84(%287);
498 +
    elem %286 %283 %285 %284 1;
499 +
    load w8 %287 %286 0;
500 +
    elem %288 %282 %285 %284 1;
501 +
    store w8 %287 %288 0;
502 +
    add w32 %289 %285 1;
503 +
    jmp @append84(%289);
501 504
  @append86
502 -
    store ptr %280 %216 0;
503 -
    store w32 %276 %216 12;
505 +
    store ptr %282 %216 0;
506 +
    store w32 %278 %216 12;
504 507
    jmp @append.store82;
505 508
  @then87
506 509
    ret 20;
507 510
  @merge88
508 -
    load w32 %294 %216 12;
509 -
    br.ne w32 %294 5 @then89 @merge90;
511 +
    load w32 %297 %216 12;
512 +
    br.ne w32 %297 5 @then89 @merge90;
510 513
  @then89
511 514
    ret 21;
512 515
  @merge90
513 -
    load w32 %295 %216 8;
514 -
    load ptr %296 %216 0;
515 -
    elem %297 %296 2 %295 1;
516 -
    load w8 %298 %297 0;
517 -
    br.ne w8 %298 239 @then91 @merge92;
516 +
    load w32 %298 %216 8;
517 +
    load ptr %299 %216 0;
518 +
    elem %300 %299 2 %298 1;
519 +
    load w8 %301 %300 0;
520 +
    br.ne w8 %301 239 @then91 @merge92;
518 521
  @then91
519 522
    ret 22;
520 523
  @merge92
521 -
    load w32 %299 %216 8;
522 -
    load ptr %300 %216 0;
523 -
    elem %301 %300 0 %299 1;
524 -
    load w8 %302 %301 0;
525 -
    br.ne w8 %302 171 @then93 @merge94;
524 +
    load w32 %302 %216 8;
525 +
    load ptr %303 %216 0;
526 +
    elem %304 %303 0 %302 1;
527 +
    load w8 %305 %304 0;
528 +
    br.ne w8 %305 171 @then93 @merge94;
526 529
  @then93
527 530
    ret 23;
528 531
  @merge94
529 -
    mul w32 %309 4 2;
530 -
    call ptr %310 $arenaAlloc(%3, %309, 4);
531 -
    reserve %311 16 8;
532 -
    store ptr %310 %311 0;
533 -
    store w32 0 %311 8;
534 -
    store w32 2 %311 12;
535 -
    load w32 %314 %311 8;
536 -
    load w32 %315 %311 12;
537 -
    br.ult w32 %314 %315 @append.store95 @append.grow96;
532 +
    mul w32 %312 4 2;
533 +
    call ptr %313 $arenaAlloc(%3, %312, 4);
534 +
    reserve %314 16 8;
535 +
    store ptr %313 %314 0;
536 +
    store w32 0 %314 8;
537 +
    store w32 2 %314 12;
538 +
    load w32 %317 %314 8;
539 +
    load w32 %318 %314 12;
540 +
    br.ult w32 %317 %318 @append.store95 @append.grow96;
538 541
  @append.store95
539 -
    load ptr %329 %311 0;
540 -
    mul w64 %330 %314 4;
541 -
    add ptr %331 %329 %330;
542 -
    store w32 42 %331 0;
543 -
    add w32 %332 %314 1;
544 -
    store w32 %332 %311 8;
545 -
    blit %311 %311 16;
546 -
    load w32 %335 %311 8;
547 -
    br.eq w32 %335 1 @assert.ok101 @assert.fail100;
542 +
    load ptr %332 %314 0;
543 +
    load w32 %333 %314 12;
544 +
    elem %334 %332 %317 %333 4;
545 +
    store w32 42 %334 0;
546 +
    add w32 %335 %317 1;
547 +
    store w32 %335 %314 8;
548 +
    blit %314 %314 16;
549 +
    load w32 %338 %314 8;
550 +
    br.eq w32 %338 1 @assert.ok101 @assert.fail100;
548 551
  @append.grow96
549 -
    shl w32 %316 %315 1;
550 -
    or w32 %317 %316 1;
551 -
    load ptr %318 %5 0;
552 -
    load ptr %319 %5 8;
553 -
    mul w32 %320 %317 4;
554 -
    call ptr %321 %318(%319, %320, 4);
555 -
    load ptr %322 %311 0;
556 -
    mul w32 %323 %314 4;
552 +
    shl w32 %319 %318 1;
553 +
    or w32 %320 %319 1;
554 +
    load ptr %321 %5 0;
555 +
    load ptr %322 %5 8;
556 +
    mul w32 %323 %320 4;
557 +
    call ptr %324 %321(%322, %323, 4);
558 +
    load ptr %325 %314 0;
559 +
    mul w32 %326 %317 4;
557 560
    jmp @append97(0);
558 -
  @append97(w32 %324)
559 -
    br.ult w32 %324 %323 @append98 @append99;
561 +
  @append97(w32 %327)
562 +
    br.ult w32 %327 %326 @append98 @append99;
560 563
  @append98
561 -
    add ptr %325 %322 %324;
562 -
    load w8 %326 %325 0;
563 -
    add ptr %327 %321 %324;
564 -
    store w8 %326 %327 0;
565 -
    add w32 %328 %324 1;
566 -
    jmp @append97(%328);
564 +
    elem %328 %325 %327 %326 1;
565 +
    load w8 %329 %328 0;
566 +
    elem %330 %324 %327 %326 1;
567 +
    store w8 %329 %330 0;
568 +
    add w32 %331 %327 1;
569 +
    jmp @append97(%331);
567 570
  @append99
568 -
    store ptr %321 %311 0;
569 -
    store w32 %317 %311 12;
571 +
    store ptr %324 %314 0;
572 +
    store w32 %320 %314 12;
570 573
    jmp @append.store95;
571 574
  @assert.fail100
572 575
    unreachable;
573 576
  @assert.ok101
574 -
    load w32 %336 %311 8;
575 -
    load ptr %337 %311 0;
576 -
    elem %338 %337 0 %336 4;
577 -
    sload w32 %339 %338 0;
578 -
    br.eq w32 %339 42 @assert.ok103 @assert.fail102;
577 +
    load w32 %339 %314 8;
578 +
    load ptr %340 %314 0;
579 +
    elem %341 %340 0 %339 4;
580 +
    sload w32 %342 %341 0;
581 +
    br.eq w32 %342 42 @assert.ok103 @assert.fail102;
579 582
  @assert.fail102
580 583
    unreachable;
581 584
  @assert.ok103
582 -
    load w32 %342 %311 8;
583 -
    load w32 %343 %311 12;
584 -
    br.ult w32 %342 %343 @append.store104 @append.grow105;
585 +
    load w32 %345 %314 8;
586 +
    load w32 %346 %314 12;
587 +
    br.ult w32 %345 %346 @append.store104 @append.grow105;
585 588
  @append.store104
586 -
    load ptr %357 %311 0;
587 -
    mul w64 %358 %342 4;
588 -
    add ptr %359 %357 %358;
589 -
    store w32 43 %359 0;
590 -
    add w32 %360 %342 1;
591 -
    store w32 %360 %311 8;
592 -
    blit %311 %311 16;
593 -
    load w32 %363 %311 8;
594 -
    br.eq w32 %363 2 @assert.ok110 @assert.fail109;
589 +
    load ptr %360 %314 0;
590 +
    load w32 %361 %314 12;
591 +
    elem %362 %360 %345 %361 4;
592 +
    store w32 43 %362 0;
593 +
    add w32 %363 %345 1;
594 +
    store w32 %363 %314 8;
595 +
    blit %314 %314 16;
596 +
    load w32 %366 %314 8;
597 +
    br.eq w32 %366 2 @assert.ok110 @assert.fail109;
595 598
  @append.grow105
596 -
    shl w32 %344 %343 1;
597 -
    or w32 %345 %344 1;
598 -
    load ptr %346 %5 0;
599 -
    load ptr %347 %5 8;
600 -
    mul w32 %348 %345 4;
601 -
    call ptr %349 %346(%347, %348, 4);
602 -
    load ptr %350 %311 0;
603 -
    mul w32 %351 %342 4;
599 +
    shl w32 %347 %346 1;
600 +
    or w32 %348 %347 1;
601 +
    load ptr %349 %5 0;
602 +
    load ptr %350 %5 8;
603 +
    mul w32 %351 %348 4;
604 +
    call ptr %352 %349(%350, %351, 4);
605 +
    load ptr %353 %314 0;
606 +
    mul w32 %354 %345 4;
604 607
    jmp @append106(0);
605 -
  @append106(w32 %352)
606 -
    br.ult w32 %352 %351 @append107 @append108;
608 +
  @append106(w32 %355)
609 +
    br.ult w32 %355 %354 @append107 @append108;
607 610
  @append107
608 -
    add ptr %353 %350 %352;
609 -
    load w8 %354 %353 0;
610 -
    add ptr %355 %349 %352;
611 -
    store w8 %354 %355 0;
612 -
    add w32 %356 %352 1;
613 -
    jmp @append106(%356);
611 +
    elem %356 %353 %355 %354 1;
612 +
    load w8 %357 %356 0;
613 +
    elem %358 %352 %355 %354 1;
614 +
    store w8 %357 %358 0;
615 +
    add w32 %359 %355 1;
616 +
    jmp @append106(%359);
614 617
  @append108
615 -
    store ptr %349 %311 0;
616 -
    store w32 %345 %311 12;
618 +
    store ptr %352 %314 0;
619 +
    store w32 %348 %314 12;
617 620
    jmp @append.store104;
618 621
  @assert.fail109
619 622
    unreachable;
620 623
  @assert.ok110
621 -
    load w32 %364 %311 8;
622 -
    load ptr %365 %311 0;
623 -
    elem %366 %365 0 %364 4;
624 -
    load w32 %369 %311 8;
625 -
    load w32 %370 %311 12;
626 -
    br.ult w32 %369 %370 @append.store111 @append.grow112;
624 +
    load w32 %367 %314 8;
625 +
    load ptr %368 %314 0;
626 +
    elem %369 %368 0 %367 4;
627 +
    load w32 %372 %314 8;
628 +
    load w32 %373 %314 12;
629 +
    br.ult w32 %372 %373 @append.store111 @append.grow112;
627 630
  @append.store111
628 -
    load ptr %384 %311 0;
629 -
    mul w64 %385 %369 4;
630 -
    add ptr %386 %384 %385;
631 -
    store w32 44 %386 0;
632 -
    add w32 %387 %369 1;
633 -
    store w32 %387 %311 8;
634 -
    blit %311 %311 16;
635 -
    load w32 %390 %311 8;
636 -
    br.eq w32 %390 3 @assert.ok117 @assert.fail116;
631 +
    load ptr %387 %314 0;
632 +
    load w32 %388 %314 12;
633 +
    elem %389 %387 %372 %388 4;
634 +
    store w32 44 %389 0;
635 +
    add w32 %390 %372 1;
636 +
    store w32 %390 %314 8;
637 +
    blit %314 %314 16;
638 +
    load w32 %393 %314 8;
639 +
    br.eq w32 %393 3 @assert.ok117 @assert.fail116;
637 640
  @append.grow112
638 -
    shl w32 %371 %370 1;
639 -
    or w32 %372 %371 1;
640 -
    load ptr %373 %5 0;
641 -
    load ptr %374 %5 8;
642 -
    mul w32 %375 %372 4;
643 -
    call ptr %376 %373(%374, %375, 4);
644 -
    load ptr %377 %311 0;
645 -
    mul w32 %378 %369 4;
641 +
    shl w32 %374 %373 1;
642 +
    or w32 %375 %374 1;
643 +
    load ptr %376 %5 0;
644 +
    load ptr %377 %5 8;
645 +
    mul w32 %378 %375 4;
646 +
    call ptr %379 %376(%377, %378, 4);
647 +
    load ptr %380 %314 0;
648 +
    mul w32 %381 %372 4;
646 649
    jmp @append113(0);
647 -
  @append113(w32 %379)
648 -
    br.ult w32 %379 %378 @append114 @append115;
650 +
  @append113(w32 %382)
651 +
    br.ult w32 %382 %381 @append114 @append115;
649 652
  @append114
650 -
    add ptr %380 %377 %379;
651 -
    load w8 %381 %380 0;
652 -
    add ptr %382 %376 %379;
653 -
    store w8 %381 %382 0;
654 -
    add w32 %383 %379 1;
655 -
    jmp @append113(%383);
653 +
    elem %383 %380 %382 %381 1;
654 +
    load w8 %384 %383 0;
655 +
    elem %385 %379 %382 %381 1;
656 +
    store w8 %384 %385 0;
657 +
    add w32 %386 %382 1;
658 +
    jmp @append113(%386);
656 659
  @append115
657 -
    store ptr %376 %311 0;
658 -
    store w32 %372 %311 12;
660 +
    store ptr %379 %314 0;
661 +
    store w32 %375 %314 12;
659 662
    jmp @append.store111;
660 663
  @assert.fail116
661 664
    unreachable;
662 665
  @assert.ok117
663 -
    load w32 %391 %311 12;
664 -
    br.eq w32 %391 5 @assert.ok119 @assert.fail118;
666 +
    load w32 %394 %314 12;
667 +
    br.eq w32 %394 5 @assert.ok119 @assert.fail118;
665 668
  @assert.fail118
666 669
    unreachable;
667 670
  @assert.ok119
668 -
    load w32 %392 %311 8;
669 -
    load ptr %393 %311 0;
670 -
    elem %394 %393 0 %392 4;
671 -
    br.ne ptr %366 %394 @assert.ok121 @assert.fail120;
671 +
    load w32 %395 %314 8;
672 +
    load ptr %396 %314 0;
673 +
    elem %397 %396 0 %395 4;
674 +
    br.ne ptr %369 %397 @assert.ok121 @assert.fail120;
672 675
  @assert.fail120
673 676
    unreachable;
674 677
  @assert.ok121
675 -
    load w32 %397 %311 8;
676 -
    load ptr %398 %311 0;
677 -
    elem %399 %398 0 %397 4;
678 -
    sload w32 %400 %399 0;
679 -
    br.eq w32 %400 42 @assert.ok123 @assert.fail122;
678 +
    load w32 %400 %314 8;
679 +
    load ptr %401 %314 0;
680 +
    elem %402 %401 0 %400 4;
681 +
    sload w32 %403 %402 0;
682 +
    br.eq w32 %403 42 @assert.ok123 @assert.fail122;
680 683
  @assert.fail122
681 684
    unreachable;
682 685
  @assert.ok123
683 -
    load w32 %401 %311 8;
684 -
    load ptr %402 %311 0;
685 -
    elem %403 %402 1 %401 4;
686 -
    sload w32 %404 %403 0;
687 -
    br.eq w32 %404 43 @assert.ok125 @assert.fail124;
686 +
    load w32 %404 %314 8;
687 +
    load ptr %405 %314 0;
688 +
    elem %406 %405 1 %404 4;
689 +
    sload w32 %407 %406 0;
690 +
    br.eq w32 %407 43 @assert.ok125 @assert.fail124;
688 691
  @assert.fail124
689 692
    unreachable;
690 693
  @assert.ok125
691 -
    load w32 %405 %311 8;
692 -
    load ptr %406 %311 0;
693 -
    elem %407 %406 2 %405 4;
694 -
    sload w32 %408 %407 0;
695 -
    br.eq w32 %408 44 @assert.ok127 @assert.fail126;
694 +
    load w32 %408 %314 8;
695 +
    load ptr %409 %314 0;
696 +
    elem %410 %409 2 %408 4;
697 +
    sload w32 %411 %410 0;
698 +
    br.eq w32 %411 44 @assert.ok127 @assert.fail126;
696 699
  @assert.fail126
697 700
    unreachable;
698 701
  @assert.ok127
699 702
    ret 0;
700 703
}
test/tests/slice.delete.ril +6 -6
19 19
    mul w32 %8 %7 4;
20 20
    jmp @delete1(0);
21 21
  @delete1(w32 %9)
22 22
    br.ult w32 %9 %8 @delete2 @delete3;
23 23
  @delete2
24 -
    add ptr %10 %5 %9;
24 +
    elem %10 %5 %9 %8 1;
25 25
    load w8 %11 %10 0;
26 -
    add ptr %12 %4 %9;
26 +
    elem %12 %4 %9 %8 1;
27 27
    store w8 %11 %12 0;
28 28
    add w32 %13 %9 1;
29 29
    jmp @delete1(%13);
30 30
  @delete3
31 31
    sub w32 %14 %2 1;
76 76
    mul w32 %39 %38 4;
77 77
    jmp @delete14(0);
78 78
  @delete14(w32 %40)
79 79
    br.ult w32 %40 %39 @delete15 @delete16;
80 80
  @delete15
81 -
    add ptr %41 %36 %40;
81 +
    elem %41 %36 %40 %39 1;
82 82
    load w8 %42 %41 0;
83 -
    add ptr %43 %35 %40;
83 +
    elem %43 %35 %40 %39 1;
84 84
    store w8 %42 %43 0;
85 85
    add w32 %44 %40 1;
86 86
    jmp @delete14(%44);
87 87
  @delete16
88 88
    sub w32 %45 %33 1;
125 125
    mul w32 %66 %65 4;
126 126
    jmp @delete25(0);
127 127
  @delete25(w32 %67)
128 128
    br.ult w32 %67 %66 @delete26 @delete27;
129 129
  @delete26
130 -
    add ptr %68 %63 %67;
130 +
    elem %68 %63 %67 %66 1;
131 131
    load w8 %69 %68 0;
132 -
    add ptr %70 %62 %67;
132 +
    elem %70 %62 %67 %66 1;
133 133
    store w8 %69 %70 0;
134 134
    add w32 %71 %67 1;
135 135
    jmp @delete25(%71);
136 136
  @delete27
137 137
    sub w32 %72 %60 1;