## This test checks that BOLT correctly inlines memcpy calls on AArch64. # REQUIRES: system-linux, aarch64-registered-target # RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o # RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q # RUN: llvm-bolt %t.exe --inline-memcpy -o %t.bolt 2>&1 | FileCheck %s --check-prefix=CHECK-INLINE # RUN: llvm-objdump -d %t.bolt | FileCheck %s --check-prefix=CHECK-ASM # Verify BOLT reports that it inlined memcpy calls (11 successful inlines out of 17 total calls) # CHECK-INLINE: BOLT-INFO: inlined 11 memcpy() calls # Each function should use optimal size-specific instructions and NO memcpy calls # 1-byte copy should use single byte load/store (ldrb/strb) # CHECK-ASM-LABEL: : # CHECK-ASM: ldrb{{.*}}w9, [x1] # CHECK-ASM-NEXT: strb{{.*}}w9, [x0] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldrh{{.*}}w9, [x1] # CHECK-ASM-NEXT: strh{{.*}}w9, [x0] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldr{{.*}}w9, [x1] # CHECK-ASM-NEXT: str{{.*}}w9, [x0] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldr{{.*}}x9, [x1] # CHECK-ASM-NEXT: str{{.*}}x9, [x0] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldr{{.*}}q16, [x1] # CHECK-ASM-NEXT: str{{.*}}q16, [x0] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldr{{.*}}q16, [x1] # CHECK-ASM-NEXT: str{{.*}}q16, [x0] # CHECK-ASM-NEXT: ldr{{.*}}q17, [x1, #0x10] # CHECK-ASM-NEXT: str{{.*}}q17, [x0, #0x10] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldr{{.*}}q16, [x1] # CHECK-ASM-NEXT: str{{.*}}q16, [x0] # CHECK-ASM-NEXT: ldr{{.*}}q16, [x1, #0x10] # CHECK-ASM-NEXT: str{{.*}}q16, [x0, #0x10] # CHECK-ASM-NEXT: ldr{{.*}}w9, [x1, #0x20] # CHECK-ASM-NEXT: str{{.*}}w9, [x0, #0x20] # CHECK-ASM-NEXT: ldrb{{.*}}w9, [x1, #0x24] # CHECK-ASM-NEXT: strb{{.*}}w9, [x0, #0x24] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM-NOT: ldr # CHECK-ASM-NOT: str # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: bl{{.*}}: # CHECK-ASM: bl{{.*}}: # CHECK-ASM: bl{{.*}}: # CHECK-ASM: bl{{.*}}: # CHECK-ASM: bl{{.*}}: # CHECK-ASM: bl{{.*}}: # CHECK-ASM: ldr{{.*}}w9, [x1] # CHECK-ASM-NEXT: str{{.*}}w9, [x0] # CHECK-ASM-NEXT: add{{.*}}x0, x0, #0x4 # CHECK-ASM-NOT: bl{{.*}}<_memcpy8 # Complex function with caller-saved X9 should inline 8-byte memcpy using X9 as temp register # CHECK-ASM-LABEL: : # CHECK-ASM: ldr{{.*}}x9, [x1] # CHECK-ASM-NEXT: str{{.*}}x9, [x0] # CHECK-ASM-NOT: bl{{.*}}: # CHECK-ASM: ldr{{.*}}q16, [x1] # CHECK-ASM-NEXT: str{{.*}}q16, [x0] # CHECK-ASM-NEXT: ldr{{.*}}q16, [x1, #0x10] # CHECK-ASM-NEXT: str{{.*}}q16, [x0, #0x10] # CHECK-ASM-NEXT: ldr{{.*}}q16, [x1, #0x20] # CHECK-ASM-NEXT: str{{.*}}q16, [x0, #0x20] # CHECK-ASM-NEXT: ldr{{.*}}q16, [x1, #0x30] # CHECK-ASM-NEXT: str{{.*}}q16, [x0, #0x30] # CHECK-ASM-NOT: bl{{.*}}