From: Chad Rosier Date: Tue, 29 Sep 2015 20:39:55 +0000 (+0000) Subject: [AArch64] Add support for pre- and post-index LDPSWs. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=091da33963209a7cd056d339402c7a0a44e7cdf8;p=oota-llvm.git [AArch64] Add support for pre- and post-index LDPSWs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248825 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp index b3ff11d86c1..87e6d0fffb1 100644 --- a/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ b/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -186,6 +186,7 @@ static int getMemScale(MachineInstr *MI) { case AArch64::STRWui: case AArch64::STURWi: case AArch64::LDPSi: + case AArch64::LDPSWi: case AArch64::LDPWi: case AArch64::STPSi: case AArch64::STPWi: @@ -326,6 +327,8 @@ static unsigned getPreIndexedOpcode(unsigned Opc) { return AArch64::LDRSWpre; case AArch64::LDPSi: return AArch64::LDPSpre; + case AArch64::LDPSWi: + return AArch64::LDPSWpre; case AArch64::LDPDi: return AArch64::LDPDpre; case AArch64::LDPQi: @@ -383,6 +386,8 @@ static unsigned getPostIndexedOpcode(unsigned Opc) { return AArch64::LDRSWpost; case AArch64::LDPSi: return AArch64::LDPSpost; + case AArch64::LDPSWi: + return AArch64::LDPSWpost; case AArch64::LDPDi: return AArch64::LDPDpost; case AArch64::LDPQi: @@ -409,6 +414,7 @@ static bool isPairedLdSt(const MachineInstr *MI) { default: return false; case AArch64::LDPSi: + case AArch64::LDPSWi: case AArch64::LDPDi: case AArch64::LDPQi: case AArch64::LDPWi: @@ -1127,6 +1133,7 @@ bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) { case AArch64::LDURXi: // Paired instructions. case AArch64::LDPSi: + case AArch64::LDPSWi: case AArch64::LDPDi: case AArch64::LDPQi: case AArch64::LDPWi: @@ -1181,11 +1188,6 @@ bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) { int Value = MI->getOperand(isPairedLdSt(MI) ? 3 : 2).getImm() * getMemScale(MI); - // FIXME: The immediate in the load/store should be scaled by the size of - // the memory operation, not the size of the register being loaded/stored. - // This works in general, but does not work for the LDPSW instruction, - // which defines two 64-bit registers, but loads 32-bit values. - // Look forward to try to find a post-index instruction. For example, // ldr x1, [x0, #64] // add x0, x0, #64 diff --git a/test/CodeGen/AArch64/arm64-ldp.ll b/test/CodeGen/AArch64/arm64-ldp.ll index a192eab112f..1ad021032c1 100644 --- a/test/CodeGen/AArch64/arm64-ldp.ll +++ b/test/CodeGen/AArch64/arm64-ldp.ll @@ -326,3 +326,34 @@ define i64 @pairUpNotAlignedSext(i32* %a) nounwind ssp { %tmp3 = add i64 %sexttmp1, %sexttmp2 ret i64 %tmp3 } + +declare void @use-ptr(i32*) + +; CHECK: ldp_sext_int_pre +; CHECK: ldpsw x{{[0-9]+}}, x{{[0-9]+}}, [x0, #8] +define i64 @ldp_sext_int_pre(i32* %p) nounwind { + %ptr = getelementptr inbounds i32, i32* %p, i64 2 + call void @use-ptr(i32* %ptr) + %add.ptr = getelementptr inbounds i32, i32* %ptr, i64 0 + %tmp = load i32, i32* %add.ptr, align 4 + %add.ptr1 = getelementptr inbounds i32, i32* %ptr, i64 1 + %tmp1 = load i32, i32* %add.ptr1, align 4 + %sexttmp = sext i32 %tmp to i64 + %sexttmp1 = sext i32 %tmp1 to i64 + %add = add nsw i64 %sexttmp1, %sexttmp + ret i64 %add +} + +; CHECK: ldp_sext_int_post +; CHECK: ldpsw x{{[0-9]+}}, x{{[0-9]+}}, [x0], #8 +define i64 @ldp_sext_int_post(i32* %p) nounwind { + %tmp = load i32, i32* %p, align 4 + %add.ptr = getelementptr inbounds i32, i32* %p, i64 1 + %tmp1 = load i32, i32* %add.ptr, align 4 + %sexttmp = sext i32 %tmp to i64 + %sexttmp1 = sext i32 %tmp1 to i64 + %ptr = getelementptr inbounds i32, i32* %add.ptr, i64 1 + call void @use-ptr(i32* %ptr) + %add = add nsw i64 %sexttmp1, %sexttmp + ret i64 %add +}