|
| 1 | +test compile precise-output |
| 2 | +set unwind_info=false |
| 3 | +target aarch64 |
| 4 | + |
| 5 | +;; Regression test: shift_masked_imm in amode_no_more_iconst must use the ishl |
| 6 | +;; type, not the load access type. When load.i8 has ishl.i64 by 56, the old code |
| 7 | +;; computed shift_masked_imm(I8, 56) = 56 & 7 = 0, incorrectly folding the |
| 8 | +;; shift into a RegScaled amode with LSL #0. The correct masking is |
| 9 | +;; shift_masked_imm(I64, 56) = 56 & 63 = 56, which does not match ty_bytes(I8) |
| 10 | +;; and prevents the fold. |
| 11 | + |
| 12 | +function %load_i8_ishl56_should_not_fold(i64, i64) -> i8 { |
| 13 | +block0(v0: i64, v1: i64): |
| 14 | + v2 = iconst.i64 56 |
| 15 | + v3 = ishl v1, v2 |
| 16 | + v4 = iadd v0, v3 |
| 17 | + v5 = load.i8 v4 |
| 18 | + return v5 |
| 19 | +} |
| 20 | + |
| 21 | +; VCode: |
| 22 | +; block0: |
| 23 | +; lsl x4, x1, #56 |
| 24 | +; ldrb w0, [x0, x4] |
| 25 | +; ret |
| 26 | +; |
| 27 | +; Disassembled: |
| 28 | +; block0: ; offset 0x0 |
| 29 | +; lsl x4, x1, #0x38 |
| 30 | +; ldrb w0, [x0, x4] ; trap: heap_oob |
| 31 | +; ret |
| 32 | + |
| 33 | +function %load_i16_ishl17_should_not_fold(i64, i64) -> i16 { |
| 34 | +block0(v0: i64, v1: i64): |
| 35 | + v2 = iconst.i64 17 |
| 36 | + v3 = ishl v1, v2 |
| 37 | + v4 = iadd v0, v3 |
| 38 | + v5 = load.i16 v4 |
| 39 | + return v5 |
| 40 | +} |
| 41 | + |
| 42 | +; VCode: |
| 43 | +; block0: |
| 44 | +; lsl x4, x1, #17 |
| 45 | +; ldrh w0, [x0, x4] |
| 46 | +; ret |
| 47 | +; |
| 48 | +; Disassembled: |
| 49 | +; block0: ; offset 0x0 |
| 50 | +; lsl x4, x1, #0x11 |
| 51 | +; ldrh w0, [x0, x4] ; trap: heap_oob |
| 52 | +; ret |
| 53 | + |
| 54 | +function %load_i32_ishl34_should_not_fold(i64, i64) -> i32 { |
| 55 | +block0(v0: i64, v1: i64): |
| 56 | + v2 = iconst.i64 34 |
| 57 | + v3 = ishl v1, v2 |
| 58 | + v4 = iadd v0, v3 |
| 59 | + v5 = load.i32 v4 |
| 60 | + return v5 |
| 61 | +} |
| 62 | + |
| 63 | +; VCode: |
| 64 | +; block0: |
| 65 | +; lsl x4, x1, #34 |
| 66 | +; ldr w0, [x0, x4] |
| 67 | +; ret |
| 68 | +; |
| 69 | +; Disassembled: |
| 70 | +; block0: ; offset 0x0 |
| 71 | +; lsl x4, x1, #0x22 |
| 72 | +; ldr w0, [x0, x4] ; trap: heap_oob |
| 73 | +; ret |
| 74 | + |
| 75 | +;; Same as the i8 case but with iadd operands swapped |
| 76 | +function %load_i8_ishl56_swapped_should_not_fold(i64, i64) -> i8 { |
| 77 | +block0(v0: i64, v1: i64): |
| 78 | + v2 = iconst.i64 56 |
| 79 | + v3 = ishl v1, v2 |
| 80 | + v4 = iadd v3, v0 |
| 81 | + v5 = load.i8 v4 |
| 82 | + return v5 |
| 83 | +} |
| 84 | + |
| 85 | +; VCode: |
| 86 | +; block0: |
| 87 | +; lsl x4, x1, #56 |
| 88 | +; ldrb w0, [x4, x0] |
| 89 | +; ret |
| 90 | +; |
| 91 | +; Disassembled: |
| 92 | +; block0: ; offset 0x0 |
| 93 | +; lsl x4, x1, #0x38 |
| 94 | +; ldrb w0, [x4, x0] ; trap: heap_oob |
| 95 | +; ret |
0 commit comments