| OLD | NEW |
| 1 ; This tries to create variables with very large stack offsets. | 1 ; This tries to create variables with very large stack offsets. |
| 2 ; This requires a lot of variables/register pressure. To simplify this | 2 ; This requires a lot of variables/register pressure. To simplify this |
| 3 ; we assume poor register allocation from Om1, and a flag that forces | 3 ; we assume poor register allocation from Om1, and a flag that forces |
| 4 ; the frame to add K amount of unused stack for testing. | 4 ; the frame to add K amount of unused stack for testing. |
| 5 ; We only need to test ARM and other architectures which have limited space | 5 ; We only need to test ARM and other architectures which have limited space |
| 6 ; for specifying an offset within an instruction. | 6 ; for specifying an offset within an instruction. |
| 7 | 7 |
| 8 ; RUN: %if --need=target_ARM32 --need=allow_dump \ | 8 ; RUN: %if --need=target_ARM32 --need=allow_dump \ |
| 9 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ | 9 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ |
| 10 ; RUN: -i %s --args -Om1 --skip-unimplemented --test-stack-extra 4096 \ | 10 ; RUN: -i %s --args -Om1 --skip-unimplemented --test-stack-extra 4096 \ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 end: | 42 end: |
| 43 %x3 = phi i64 [ %x1, %br_1 ], [ %x2, %br_2 ] | 43 %x3 = phi i64 [ %x1, %br_1 ], [ %x2, %br_2 ] |
| 44 %z3 = phi i64 [ %z1, %br_1 ], [ %z2, %br_2 ] | 44 %z3 = phi i64 [ %z1, %br_1 ], [ %z2, %br_2 ] |
| 45 %r3 = and i64 %x3, %z3 | 45 %r3 = and i64 %x3, %z3 |
| 46 ret i64 %r3 | 46 ret i64 %r3 |
| 47 } | 47 } |
| 48 ; ARM32-LABEL: lotsOfStack | 48 ; ARM32-LABEL: lotsOfStack |
| 49 ; ARM32-NOT: mov fp, sp | 49 ; ARM32-NOT: mov fp, sp |
| 50 ; ARM32: movw ip, #4{{.*}} | 50 ; ARM32: movw ip, #4{{.*}} |
| 51 ; ARM32-NEXT: sub sp, sp, ip | 51 ; ARM32-NEXT: sub sp, sp, ip |
| 52 ; ARM32: movw ip, #4232 | 52 ; ARM32: movw ip, #4248 |
| 53 ; ARM32-NEXT: add ip, sp, ip | 53 ; ARM32-NEXT: add ip, sp, ip |
| 54 ; ARM32-NOT: movw ip | 54 ; ARM32-NOT: movw ip |
| 55 ; %t2 is the result of the "or", and %t2 will be passed via r1 to the call. | 55 ; %t2 is the result of the "or", and %t2 will be passed via r1 to the call. |
| 56 ; Use that to check the stack offset of %t2. The first offset and the | 56 ; Use that to check the stack offset of %t2. The first offset and the |
| 57 ; later offset right before the call should be 16 bytes apart, | 57 ; later offset right before the call should be 16 bytes apart, |
| 58 ; because of the sub sp, sp, #16. | 58 ; because of the sub sp, sp, #16. |
| 59 ; ARM32: orr [[REG:r.*]], {{.*}}, | 59 ; ARM32: orr [[REG:r.*]], {{.*}}, |
| 60 ; I.e., the slot for t2 is (sp0 + 4232 - 20) == sp0 + 4212. | 60 ; I.e., the slot for t2 is (sp0 + 4232 - 20) == sp0 + 4212. |
| 61 ; ARM32: str [[REG]], [ip, #-20] | 61 ; ARM32: str [[REG]], [ip, #-20] |
| 62 ; ARM32: b {{[a-f0-9]+}} | 62 ; ARM32: b {{[a-f0-9]+}} |
| 63 ; Now skip ahead to where the call in br_1 begins, to check how %t2 is used. | 63 ; Now skip ahead to where the call in br_1 begins, to check how %t2 is used. |
| 64 ; ARM32: movw ip, #4216 | 64 ; ARM32: movw ip, #4232 |
| 65 ; ARM32-NEXT: add ip, sp, ip | 65 ; ARM32-NEXT: add ip, sp, ip |
| 66 ; ARM32: sub sp, sp, #16 | |
| 67 ; Now sp1 = sp0 - 16, but ip is still in terms of sp0. | |
| 68 ; So, sp0 + 4212 == ip - 4. | |
| 69 ; ARM32: ldr r2, [ip, #-4] | 66 ; ARM32: ldr r2, [ip, #-4] |
| 70 ; ARM32: bl {{.*}} dummy | 67 ; ARM32: bl {{.*}} dummy |
| 71 ; ARM32: add sp, sp | |
| 72 ; The call clobbers ip, so we need to re-create the base register. | 68 ; The call clobbers ip, so we need to re-create the base register. |
| 73 ; ARM32: movw ip, #4{{.*}} | 69 ; ARM32: movw ip, #4{{.*}} |
| 74 ; ARM32: b {{[a-f0-9]+}} | 70 ; ARM32: b {{[a-f0-9]+}} |
| 75 ; ARM32: bl {{.*}} dummy | 71 ; ARM32: bl {{.*}} dummy |
| 76 | 72 |
| 77 ; Similar, but test a function that uses FP as the base register (originally). | 73 ; Similar, but test a function that uses FP as the base register (originally). |
| 78 define internal i64 @usesFrameReg(i32 %a, i32 %b, i32 %c, i32 %d) { | 74 define internal i64 @usesFrameReg(i32 %a, i32 %b, i32 %c, i32 %d) { |
| 79 entry: | 75 entry: |
| 80 %p = alloca i8, i32 %d, align 4 | 76 %p = alloca i8, i32 %d, align 4 |
| 81 %t1 = xor i32 %a, %b | 77 %t1 = xor i32 %a, %b |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 ; Use that to check the stack offset of %t2. It should be the same offset | 111 ; Use that to check the stack offset of %t2. It should be the same offset |
| 116 ; even after sub sp, sp, #16, because the base register was originally | 112 ; even after sub sp, sp, #16, because the base register was originally |
| 117 ; the FP and not the SP. | 113 ; the FP and not the SP. |
| 118 ; ARM32: orr [[REG:r.*]], {{.*}}, | 114 ; ARM32: orr [[REG:r.*]], {{.*}}, |
| 119 ; I.e., the slot for t2 is (fp0 - 4100 -24) == fp0 - 4124 | 115 ; I.e., the slot for t2 is (fp0 - 4100 -24) == fp0 - 4124 |
| 120 ; ARM32: str [[REG]], [ip, #-24] | 116 ; ARM32: str [[REG]], [ip, #-24] |
| 121 ; ARM32: b {{[a-f0-9]+}} | 117 ; ARM32: b {{[a-f0-9]+}} |
| 122 ; Now skip ahead to where the call in br_1 begins, to check how %t2 is used. | 118 ; Now skip ahead to where the call in br_1 begins, to check how %t2 is used. |
| 123 ; ARM32: movw ip, #4120 | 119 ; ARM32: movw ip, #4120 |
| 124 ; ARM32-NEXT: sub ip, fp, ip | 120 ; ARM32-NEXT: sub ip, fp, ip |
| 125 ; ARM32: sub sp, sp, #16 | |
| 126 ; Now sp1 = sp0 - 16, but ip is still in terms of fp0. | |
| 127 ; So, fp0 - 4124 == ip - 4. | |
| 128 ; ARM32: ldr r2, [ip, #-4] | 121 ; ARM32: ldr r2, [ip, #-4] |
| 129 ; ARM32: bl {{.*}} dummy | 122 ; ARM32: bl {{.*}} dummy |
| 130 ; ARM32: add sp, sp | |
| 131 ; The call clobbers ip, so we need to re-create the base register. | 123 ; The call clobbers ip, so we need to re-create the base register. |
| 132 ; ARM32: movw ip, #4{{.*}} | 124 ; ARM32: movw ip, #4{{.*}} |
| 133 ; ARM32: b {{[a-f0-9]+}} | 125 ; ARM32: b {{[a-f0-9]+}} |
| 134 ; ARM32: bl {{.*}} dummy | 126 ; ARM32: bl {{.*}} dummy |
| OLD | NEW |