[llvm] r278559 - [AArch64LoadStoreOpt] Handle offsets correctly for post-indexed paired loads.

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 12 13:55:11 PDT 2016


Hans/Tim,
Here's another one I'd like to see included in the 3.9 release.  Again, 
straightforward fix (Thanks, Eli).

Okay to merge Tim?

  Chad

On 2016-08-12 16:28, Eli Friedman via llvm-commits wrote:
> Author: efriedma
> Date: Fri Aug 12 15:28:02 2016
> New Revision: 278559
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=278559&view=rev
> Log:
> [AArch64LoadStoreOpt] Handle offsets correctly for post-indexed paired 
> loads.
> 
> Trunk would try to create something like "stp x9, x8, [x0], #512",
> which isn't actually a valid instruction.
> 
> Differential revision: https://reviews.llvm.org/D23368
> 
> 
> Modified:
>     llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
>     llvm/trunk/test/CodeGen/AArch64/ldst-opt.ll
> 
> Modified: llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp?rev=278559&r1=278558&r2=278559&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp 
> (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp Fri
> Aug 12 15:28:02 2016
> @@ -1419,9 +1419,6 @@ bool AArch64LoadStoreOpt::isMatchingUpda
>    default:
>      break;
>    case AArch64::SUBXri:
> -    // Negate the offset for a SUB instruction.
> -    Offset *= -1;
> -  // FALLTHROUGH
>    case AArch64::ADDXri:
>      // Make sure it's a vanilla immediate operand, not a relocation or
>      // anything else we can't handle.
> @@ -1439,6 +1436,9 @@ bool AArch64LoadStoreOpt::isMatchingUpda
> 
>      bool IsPairedInsn = isPairedLdSt(MemMI);
>      int UpdateOffset = MI.getOperand(2).getImm();
> +    if (MI.getOpcode() == AArch64::SUBXri)
> +      UpdateOffset = -UpdateOffset;
> +
>      // For non-paired load/store instructions, the immediate must fit 
> in a
>      // signed 9-bit integer.
>      if (!IsPairedInsn && (UpdateOffset > 255 || UpdateOffset < -256))
> @@ -1453,13 +1453,13 @@ bool AArch64LoadStoreOpt::isMatchingUpda
>          break;
> 
>        int ScaledOffset = UpdateOffset / Scale;
> -      if (ScaledOffset > 64 || ScaledOffset < -64)
> +      if (ScaledOffset > 63 || ScaledOffset < -64)
>          break;
>      }
> 
>      // If we have a non-zero Offset, we check that it matches the 
> amount
>      // we're adding to the register.
> -    if (!Offset || Offset == MI.getOperand(2).getImm())
> +    if (!Offset || Offset == UpdateOffset)
>        return true;
>      break;
>    }
> 
> Modified: llvm/trunk/test/CodeGen/AArch64/ldst-opt.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/ldst-opt.ll?rev=278559&r1=278558&r2=278559&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/ldst-opt.ll (original)
> +++ llvm/trunk/test/CodeGen/AArch64/ldst-opt.ll Fri Aug 12 15:28:02 
> 2016
> @@ -1,4 +1,4 @@
> -; RUN: llc -mtriple=aarch64-linux-gnu
> -aarch64-enable-atomic-cfg-tidy=0 -verify-machineinstrs -o - %s |
> FileCheck %s
> +; RUN: llc -mtriple=aarch64-linux-gnu
> -aarch64-enable-atomic-cfg-tidy=0 -disable-lsr -verify-machineinstrs
> -o - %s | FileCheck %s
> 
>  ; This file contains tests for the AArch64 load/store optimizer.
> 
> @@ -1230,5 +1230,106 @@ for.body:
>    %cond = icmp sgt i64 %dec.i, 0
>    br i1 %cond, label %for.body, label %end
>  end:
> +  ret void
> +}
> +
> +define void @post-indexed-sub-doubleword-offset-min(i64* %a, i64* %b,
> i64 %count) nounwind {
> +; CHECK-LABEL: post-indexed-sub-doubleword-offset-min
> +; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #-256
> +; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #-256
> +  br label %for.body
> +for.body:
> +  %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
> +  %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
> +  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
> +  %gep1 = getelementptr i64, i64* %phi1, i64 1
> +  %load1 = load i64, i64* %gep1
> +  %gep2 = getelementptr i64, i64* %phi2, i64 1
> +  store i64 %load1, i64* %gep2
> +  %load2 = load i64, i64* %phi1
> +  store i64 %load2, i64* %phi2
> +  %dec.i = add nsw i64 %i, -1
> +  %gep3 = getelementptr i64, i64* %phi2, i64 -32
> +  %gep4 = getelementptr i64, i64* %phi1, i64 -32
> +  %cond = icmp sgt i64 %dec.i, 0
> +  br i1 %cond, label %for.body, label %end
> +end:
> +  ret void
> +}
> +
> +define void @post-indexed-doubleword-offset-out-of-range(i64* %a,
> i64* %b, i64 %count) nounwind {
> +; CHECK-LABEL: post-indexed-doubleword-offset-out-of-range
> +; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}]
> +; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #256
> +; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}]
> +; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #256
> +
> +  br label %for.body
> +for.body:
> +  %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
> +  %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
> +  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
> +  %gep1 = getelementptr i64, i64* %phi1, i64 1
> +  %load1 = load i64, i64* %gep1
> +  %gep2 = getelementptr i64, i64* %phi2, i64 1
> +  store i64 %load1, i64* %gep2
> +  %load2 = load i64, i64* %phi1
> +  store i64 %load2, i64* %phi2
> +  %dec.i = add nsw i64 %i, -1
> +  %gep3 = getelementptr i64, i64* %phi2, i64 32
> +  %gep4 = getelementptr i64, i64* %phi1, i64 32
> +  %cond = icmp sgt i64 %dec.i, 0
> +  br i1 %cond, label %for.body, label %end
> +end:
> +  ret void
> +}
> +
> +define void @post-indexed-paired-min-offset(i64* %a, i64* %b, i64
> %count) nounwind {
> +; CHECK-LABEL: post-indexed-paired-min-offset
> +; CHECK: ldp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}], #-512
> +; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}], #-512
> +  br label %for.body
> +for.body:
> +  %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
> +  %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
> +  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
> +  %gep1 = getelementptr i64, i64* %phi1, i64 1
> +  %load1 = load i64, i64* %gep1
> +  %gep2 = getelementptr i64, i64* %phi2, i64 1
> +  %load2 = load i64, i64* %phi1
> +  store i64 %load1, i64* %gep2
> +  store i64 %load2, i64* %phi2
> +  %dec.i = add nsw i64 %i, -1
> +  %gep3 = getelementptr i64, i64* %phi2, i64 -64
> +  %gep4 = getelementptr i64, i64* %phi1, i64 -64
> +  %cond = icmp sgt i64 %dec.i, 0
> +  br i1 %cond, label %for.body, label %end
> +end:
> +  ret void
> +}
> +
> +define void @post-indexed-paired-offset-out-of-range(i64* %a, i64*
> %b, i64 %count) nounwind {
> +; CHECK-LABEL: post-indexed-paired-offset-out-of-range
> +; CHECK: ldp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]
> +; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #512
> +; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]
> +; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #512
> +  br label %for.body
> +for.body:
> +  %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
> +  %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
> +  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
> +  %gep1 = getelementptr i64, i64* %phi1, i64 1
> +  %load1 = load i64, i64* %phi1
> +  %gep2 = getelementptr i64, i64* %phi2, i64 1
> +  %load2 = load i64, i64* %gep1
> +  store i64 %load1, i64* %gep2
> +  store i64 %load2, i64* %phi2
> +  %dec.i = add nsw i64 %i, -1
> +  %gep3 = getelementptr i64, i64* %phi2, i64 64
> +  %gep4 = getelementptr i64, i64* %phi1, i64 64
> +  %cond = icmp sgt i64 %dec.i, 0
> +  br i1 %cond, label %for.body, label %end
> +end:
>    ret void
>  }
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list