diff options
| author | Sjoerd Meijer <sjoerd.meijer@arm.com> | 2019-04-30 10:28:50 +0000 |
|---|---|---|
| committer | Sjoerd Meijer <sjoerd.meijer@arm.com> | 2019-04-30 10:28:50 +0000 |
| commit | ea31ddb36ffdaf631934241af5f9ee0f95a3e1cd (patch) | |
| tree | 47556fb096dba46d4a8d8454c2f67d33a57b244f /llvm/test | |
| parent | 9a7ccd01b6f6cac2900af3393abb4ca1fb8cda50 (diff) | |
| download | bcm5719-llvm-ea31ddb36ffdaf631934241af5f9ee0f95a3e1cd.tar.gz bcm5719-llvm-ea31ddb36ffdaf631934241af5f9ee0f95a3e1cd.zip | |
[ARM] Implement TTI::getMemcpyCost
This implements TargetTransformInfo method getMemcpyCost, which estimates the
number of instructions to which a memcpy instruction expands to.
Differential Revision: https://reviews.llvm.org/D59787
llvm-svn: 359547
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/Analysis/CostModel/ARM/memcpy.ll | 666 |
1 files changed, 662 insertions, 4 deletions
diff --git a/llvm/test/Analysis/CostModel/ARM/memcpy.ll b/llvm/test/Analysis/CostModel/ARM/memcpy.ll index aa0bee633ff..4e8717ef0b9 100644 --- a/llvm/test/Analysis/CostModel/ARM/memcpy.ll +++ b/llvm/test/Analysis/CostModel/ARM/memcpy.ll @@ -1,12 +1,670 @@ -; RUN: opt < %s -cost-model -analyze -cost-kind=code-size | FileCheck %s +; RUN: opt < %s -cost-model -analyze -cost-kind=code-size | \ +; RUN: FileCheck %s --check-prefixes=COMMON,CHECK-NO-SA +; RUN: opt < %s -cost-model -analyze -cost-kind=code-size -mattr=+strict-align | \ +; RUN: FileCheck %s --check-prefixes=COMMON,CHECK-SA target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv7m-arm-unknown-eabi" -define void @memcpy(i8* %d, i8* %s, i32 %N) { +;;;;;;;;;;;; +; Align 1, 1 +;;;;;;;;;;;; + +define void @memcpy_1(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r1, [r1] +; strb r1, [r0] +; +; COMMON: function 'memcpy_1' +; CHECK-NO-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 1, i1 false) + ret void +} + +define void @memcpy_2(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldrh r1, [r1] +; strh r1, [r0] +; +; strict-align: +; +; ldrb r2, [r1] +; ldrb r1, [r1, #1] +; strb r1, [r0, #1] +; strb r2, [r0] +; +; COMMON: function 'memcpy_2' +; CHECK-NO-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 2, i1 false) + ret void +} + +define void @memcpy_3(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldrb r2, [r1, #2] +; strb r2, [r0, #2] +; ldrh r1, [r1] +; strh r1, [r0] +; +; strict-align: +; +; ldrb r2, [r1] +; ldrb r3, [r1, #1] +; ldrb r1, [r1, #2] +; strb r1, [r0, #2] +; strb r3, [r0, #1] +; strb r2, [r0] +; +; COMMON: function 'memcpy_3' +; CHECK-NO-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 6 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 3, i1 false) + ret void +} + +define void @memcpy_4(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr r1, [r1] +; str r1, [r0] +; +; strict-align: +; +; ldrb.w r12, [r1] +; ldrb r3, [r1, #1] +; ldrb r2, [r1, #2] +; ldrb r1, [r1, #3] +; strb r1, [r0, #3] +; strb r2, [r0, #2] +; strb r3, [r0, #1] +; strb.w r12, [r0] +; +; COMMON: function 'memcpy_4' +; CHECK-NO-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 4, i1 false) + ret void +} + +define void @memcpy_8(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr r2, [r1] +; ldr r1, [r1, #4] +; str r1, [r0, #4] +; str r2, [r0] +; +; strict-align: +; +; push {r7, lr} +; movs r2, #8 +; bl __aeabi_memcpy +; pop {r7, pc} +; +; COMMON: function 'memcpy_8' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 8, i1 false) + ret void +} + +define void @memcpy_16(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr.w r12, [r1] +; ldr r3, [r1, #4] +; ldr r2, [r1, #8] +; ldr r1, [r1, #12] +; str r1, [r0, #12] +; str r2, [r0, #8] +; str r3, [r0, #4] +; str.w r12, [r0] +; +; strict-align: +; +; push {r7, lr} +; movs r2, #8 +; bl __aeabi_memcpy +; pop {r7, pc} +; +; COMMON: function 'memcpy_16' +; CHECK-NO-SA-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 16, i1 false) + ret void +} + +define void @memcpy_32(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; movs r2, #32 +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_32' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 32, i1 false) + ret void +} + +define void @memcpy_N(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_N' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 %N, i1 false) + ret void +} + +;;;;;;;;;;;;; +; Align 2, 2 +;;;;;;;;;;;;; + +define void @memcpy_1_al2(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r1, [r1] +; strb r1, [r0] +; +; COMMON: function 'memcpy_1_al2' +; COMMON-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 1, i1 false) + ret void +} + +define void @memcpy_2_al2(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrh r1, [r1] +; strh r1, [r0] +; +; COMMON: function 'memcpy_2_al2' +; COMMON-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 2, i1 false) + ret void +} + +define void @memcpy_3_al2(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r2, [r1, #2] +; strb r2, [r0, #2] +; ldrh r1, [r1] +; strh r1, [r0] +; +; COMMON: function 'memcpy_3_al2' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 3, i1 false) + ret void +} + +define void @memcpy_4_al2(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr r1, [r1] +; str r1, [r0] +; +; strict-align: +; +; ldrh r2, [r1, #2] +; strh r2, [r0, #2] +; ldrh r1, [r1] +; strh r1, [r0] +; +; COMMON: function 'memcpy_4_al2' +; CHECK-NO-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 4, i1 false) + ret void +} + +define void @memcpy_8_al2(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr r2, [r1] +; ldr r1, [r1, #4] +; str r1, [r0, #4] +; str r2, [r0] +; +; strict-align: +; +; ldrh r2, [r1, #6] +; strh r2, [r0, #6] +; ldrh r2, [r1, #4] +; strh r2, [r0, #4] +; ldrh r2, [r1, #2] +; strh r2, [r0, #2] +; ldrh r1, [r1] +; strh r1, [r0] +; +; COMMON: function 'memcpy_8_al2' +; CHECK-NO-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 8, i1 false) + ret void +} + +define void @memcpy_16_al2(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr.w r12, [r1] +; ldr r3, [r1, #4] +; ldr r2, [r1, #8] +; ldr r1, [r1, #12] +; str r1, [r0, #12] +; str r2, [r0, #8] +; str r3, [r0, #4] +; str.w r12, [r0] +; +; strict-align: +; +; movs r2, #16 +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_16_al2' +; CHECK-NO-SA-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 16, i1 false) + ret void +} + +define void @memcpy_32_al2(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; movs r2, #32 +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_32_al2' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 32, i1 false) + ret void +} + +define void @memcpy_N_al2(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_N_al2' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 %N, i1 false) + ret void +} + +;;;;;;;;;;;;; +; Align 4, 4 +;;;;;;;;;;;;; + +define void @memcpy_1_al4(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r1, [r1] +; strb r1, [r0] +; +; COMMON: function 'memcpy_1_al4' +; COMMON-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 1, i1 false) + ret void +} + +define void @memcpy_2_al4(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrh r1, [r1] +; strh r1, [r0] +; +; COMMON: function 'memcpy_2_al4' +; COMMON-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 2, i1 false) + ret void +} + +define void @memcpy_3_al4(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r2, [r1, #2] +; strb r2, [r0, #2] +; ldrh r1, [r1] +; strh r1, [r0] +; +; COMMON: function 'memcpy_3_al4' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 3, i1 false) + ret void +} + +define void @memcpy_4_al4(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldr r1, [r1] +; str r1, [r0] +; +; COMMON: function 'memcpy_4_al4' +; COMMON-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 4, i1 false) + ret void +} + +define void @memcpy_8_al4(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrd r2, r1, [r1] +; strd r2, r1, [r0] +; +; COMMON: function 'memcpy_8_al4' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 8, i1 false) + ret void +} + +define void @memcpy_16_al4(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldm.w r1, {r2, r3, r12} +; ldr r1, [r1, #12] +; stm.w r0, {r2, r3, r12} +; str r1, [r0, #12] +; +; COMMON: function 'memcpy_16_al4' +; COMMON-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 16, i1 false) + ret void +} + +define void @memcpy_32_al4(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; ldm.w r1!, {r2, r3, r12, lr} +; stm.w r0!, {r2, r3, r12, lr} +; ldm.w r1, {r2, r3, r12, lr} +; stm.w r0, {r2, r3, r12, lr} +; +; COMMON: function 'memcpy_32_al4' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 32, i1 false) + ret void +} + +define void @memcpy_N_al4(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; bl __aeabi_memcpy4 +; +; COMMON: function 'memcpy_N_al4' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 %N, i1 false) + ret void +} + +;;;;;;;;;;;;; +; Align 1, 4 +;;;;;;;;;;;;; + +define void @memcpy_1_al14(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r1, [r1] +; strb r1, [r0] +; +; COMMON: function 'memcpy_1_al14' +; COMMON-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 1, i1 false) + ret void +} + +define void @memcpy_2_al14(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldrh r1, [r1] +; strh r1, [r0] +; +; strict-align: +; +; ldrb r2, [r1] +; ldrb r1, [r1, #1] +; strb r1, [r0, #1] +; strb r2, [r0] +; +; COMMON: function 'memcpy_2_al14' +; CHECK-NO-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 2, i1 false) + ret void +} + +define void @memcpy_3_al14(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldrb r2, [r1, #2] +; strb r2, [r0, #2] +; ldrh r1, [r1] +; strh r1, [r0] +; +; strict-align: +; +; ldrb r2, [r1] +; ldrb r3, [r1, #1] +; ldrb r1, [r1, #2] +; strb r1, [r0, #2] +; strb r3, [r0, #1] +; strb r2, [r0] +; +; COMMON: function 'memcpy_3_al14' +; CHECK-NO-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 6 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 3, i1 false) + ret void +} + +define void @memcpy_4_al14(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr r1, [r1] +; str r1, [r0] +; +; strict-align: +; +; ldrb.w r12, [r1] +; ldrb r3, [r1, #1] +; ldrb r2, [r1, #2] +; ldrb r1, [r1, #3] +; strb r1, [r0, #3] +; strb r2, [r0, #2] +; strb r3, [r0, #1] +; strb.w r12, [r0] +; +; COMMON: function 'memcpy_4_al14' +; CHECK-NO-SA-NEXT: cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 4, i1 false) + ret void +} + +define void @memcpy_8_al14(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr r2, [r1] +; ldr r1, [r1, #4] +; str r1, [r0, #4] +; str r2, [r0] +; +; strict-align: +; +; push {r7, lr} +; movs r2, #8 +; bl __aeabi_memcpy +; pop {r7, pc} +; +; COMMON: function 'memcpy_8_al14' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 8, i1 false) + ret void +} + +define void @memcpy_16_al14(i8* %d, i8* %s) { +; +; no strict-align: +; +; ldr.w r12, [r1] +; ldr r3, [r1, #4] +; ldr r2, [r1, #8] +; ldr r1, [r1, #12] +; str r1, [r0, #12] +; str r2, [r0, #8] +; str r3, [r0, #4] +; str.w r12, [r0] +; +; strict-align: +; +; movs r2, #16 +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_16_al14' +; CHECK-NO-SA-NEXT: cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; CHECK-SA-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 16, i1 false) + ret void +} + +define void @memcpy_32_al14(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; movs r2, #32 +; bl __aeabi_memcpy +; +; COMMON: function 'memcpy_32_al14' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 32, i1 false) + ret void +} + +define void @memcpy_N_al14(i8* %d, i8* %s, i32 %N) { +; +; with/without strict-align: +; +; bl __aeabi_memcpy4 +; +; COMMON: function 'memcpy_N_al14' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; +entry: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 %N, i1 false) + ret void +} + +;;;;;;;;;;;;; +; Align 4, 1 +;;;;;;;;;;;;; + +define void @memcpy_1_al41(i8* %d, i8* %s) { +; +; with/without strict-align: +; +; ldrb r1, [r1] +; strb r1, [r0] +; +; COMMON: function 'memcpy_1_al41' +; COMMON-NEXT: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 +; entry: -; CHECK: cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32 - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 36, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 1 %s, i32 1, i1 false) ret void } |

