[AArch64] Match FI+offset in STNP addressing mode.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 10 Sep 2015 01:54:43 +0000 (01:54 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 10 Sep 2015 01:54:43 +0000 (01:54 +0000)
First, we need to teach isFrameOffsetLegal about STNP.
It already knew about the STP/LDP variants, but those were probably
never exercised, because it's only the load/store optimizer that
generates STP/LDP, and the only user of the method is frame lowering,
which runs earlier.
The STP/LDP cases were wrong: they didn't take into account the fact
that they return two results, not one, so the immediate offset will be
the 4th operand, not the 3rd.

Follow-up to r247234.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247236 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
lib/Target/AArch64/AArch64InstrInfo.cpp
test/CodeGen/AArch64/nontemporal.ll

index 367bbc3a482e2ee3b1e718df105e3c9c55ee4137..ada3e85289168814dc6e05eb6bfedb0a97d9c3c7 100644 (file)
@@ -630,6 +630,15 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexed7S(SDValue N, unsigned Size,
                                                   SDValue &Base,
                                                   SDValue &OffImm) {
   SDLoc dl(N);
+  const DataLayout &DL = CurDAG->getDataLayout();
+  const TargetLowering *TLI = getTargetLowering();
+  if (N.getOpcode() == ISD::FrameIndex) {
+    int FI = cast<FrameIndexSDNode>(N)->getIndex();
+    Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
+    OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
+    return true;
+  }
+
   // As opposed to the (12-bit) Indexed addressing mode below, the 7-bit signed
   // selected here doesn't support labels/immediates, only base+offset.
 
@@ -640,6 +649,10 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexed7S(SDValue N, unsigned Size,
       if ((RHSC & (Size - 1)) == 0 && RHSC >= (-0x40 << Scale) &&
           RHSC < (0x40 << Scale)) {
         Base = N.getOperand(0);
+        if (Base.getOpcode() == ISD::FrameIndex) {
+          int FI = cast<FrameIndexSDNode>(Base)->getIndex();
+          Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
+        }
         OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
         return true;
       }
index 2013f8beace09f2dd9b4d3452c1fd38bb1a526f6..a41007cab5c1f9692e4f1875c0e105893848bd86 100644 (file)
@@ -2260,11 +2260,19 @@ int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
   case AArch64::LDPDi:
   case AArch64::STPXi:
   case AArch64::STPDi:
+  case AArch64::LDNPXi:
+  case AArch64::LDNPDi:
+  case AArch64::STNPXi:
+  case AArch64::STNPDi:
+    ImmIdx = 3;
     IsSigned = true;
     Scale = 8;
     break;
   case AArch64::LDPQi:
   case AArch64::STPQi:
+  case AArch64::LDNPQi:
+  case AArch64::STNPQi:
+    ImmIdx = 3;
     IsSigned = true;
     Scale = 16;
     break;
@@ -2272,6 +2280,11 @@ int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
   case AArch64::LDPSi:
   case AArch64::STPWi:
   case AArch64::STPSi:
+  case AArch64::LDNPWi:
+  case AArch64::LDNPSi:
+  case AArch64::STNPWi:
+  case AArch64::STNPSi:
+    ImmIdx = 3;
     IsSigned = true;
     Scale = 4;
     break;
index af553be92c535f97f513306ab7a3599432ca2a28..e1d82ae5777b48adc84435676637a352737732e1 100644 (file)
@@ -313,9 +313,7 @@ declare void @dummy(<4 x float>*)
 
 define void @test_stnp_v4f32_offset_alloca(<4 x float> %v) #0 {
 ; CHECK-LABEL: test_stnp_v4f32_offset_alloca:
-; CHECK:       mov x29, sp
-; CHECK:       mov x[[PTR:[0-9]+]], sp
-; CHECK-NEXT:  stnp d0, d{{.*}}, [x[[PTR]]]
+; CHECK:       stnp d0, d{{.*}}, [sp]
 ; CHECK-NEXT:  mov x0, sp
 ; CHECK-NEXT:  bl _dummy
   %tmp0 = alloca <4 x float>
@@ -326,9 +324,7 @@ define void @test_stnp_v4f32_offset_alloca(<4 x float> %v) #0 {
 
 define void @test_stnp_v4f32_offset_alloca_2(<4 x float> %v) #0 {
 ; CHECK-LABEL: test_stnp_v4f32_offset_alloca_2:
-; CHECK:       mov x29, sp
-; CHECK:       mov x[[PTR:[0-9]+]], sp
-; CHECK-NEXT:  stnp d0, d{{.*}}, [x[[PTR]], #16]
+; CHECK:       stnp d0, d{{.*}}, [sp, #16]
 ; CHECK-NEXT:  mov x0, sp
 ; CHECK-NEXT:  bl _dummy
   %tmp0 = alloca <4 x float>, i32 2