From 46b3076cd0b1e57e16cfe4ecaa517eb78863a92a Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 10 Jun 2014 09:52:44 +0000 Subject: [PATCH] AArch64: teach FastISel how to handle offset FrameIndices Previously we were abandonning the attempt, leading to some combination of extra work (when selection of a load/store fails completely) and inferior code (when this leads to a real memcpy call instead of inlining). rdar://problem/17187463 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210520 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 15 +++++++++++---- test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll | 8 ++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index f3beef4ecb6..cc2a70ee8a2 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -463,11 +463,18 @@ bool AArch64FastISel::SimplifyAddress(Address &Addr, MVT VT, break; } - // FIXME: If this is a stack pointer and the offset needs to be simplified - // then put the alloca address into a register, set the base type back to - // register and continue. This should almost never happen. + //If this is a stack pointer and the offset needs to be simplified then put + // the alloca address into a register, set the base type back to register and + // continue. This should almost never happen. if (needsLowering && Addr.getKind() == Address::FrameIndexBase) { - return false; + unsigned ResultReg = createResultReg(&AArch64::GPR64RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri), + ResultReg) + .addFrameIndex(Addr.getFI()) + .addImm(0) + .addImm(0); + Addr.setKind(Address::RegBase); + Addr.setReg(ResultReg); } // Since the offset is too large for the load/store instruction get the diff --git a/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll b/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll index 7c85ea5b9f7..115298805ac 100644 --- a/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll +++ b/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll @@ -136,9 +136,13 @@ define void @t8() { define void @test_distant_memcpy(i8* %dst) { ; ARM64-LABEL: test_distant_memcpy: -; ARM64: bl _memcpy +; ARM64: mov [[ARRAY:x[0-9]+]], sp +; ARM64: movz [[OFFSET:x[0-9]+]], #0x1f40 +; ARM64: add x[[ADDR:[0-9]+]], [[ARRAY]], [[OFFSET]] +; ARM64: ldrb [[BYTE:w[0-9]+]], [x[[ADDR]]] +; ARM64: strb [[BYTE]], [x0] %array = alloca i8, i32 8192 %elem = getelementptr i8* %array, i32 8000 - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %elem, i64 4, i32 1, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %elem, i64 1, i32 1, i1 false) ret void }