[AArch64] Add support for pre- and post-index LDPSWs.
authorChad Rosier <mcrosier@codeaurora.org>
Tue, 29 Sep 2015 20:39:55 +0000 (20:39 +0000)
committerChad Rosier <mcrosier@codeaurora.org>
Tue, 29 Sep 2015 20:39:55 +0000 (20:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248825 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
test/CodeGen/AArch64/arm64-ldp.ll

index b3ff11d86c1633f69673d72f2166569306fe2e8f..87e6d0fffb122e511f068c512d0243c8bf559cb4 100644 (file)
@@ -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
index a192eab112faf99f557a8b73373b7d94b79205d2..1ad021032c1df3aa774fc55ebc2ff529bd8afe4e 100644 (file)
@@ -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
+}