Pass the right sign to TLI->isLegalICmpImmediate.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 5 Apr 2012 03:10:56 +0000 (03:10 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 5 Apr 2012 03:10:56 +0000 (03:10 +0000)
LSR can fold three addressing modes into its ICmpZero node:

  ICmpZero BaseReg + Offset      => ICmp BaseReg, -Offset
  ICmpZero -1*ScaleReg + Offset  => ICmp ScaleReg, Offset
  ICmpZero BaseReg + -1*ScaleReg => ICmp BaseReg, ScaleReg

The first two cases are only used if TLI->isLegalICmpImmediate() likes
the offset.

Make sure the right Offset sign is passed to this method in the second
case. The ARM version is not symmetric.

<rdar://problem/11184260>

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

lib/Transforms/Scalar/LoopStrengthReduce.cpp
test/CodeGen/ARM/commute-movcc.ll

index 7e71683dc1a4aae77285cd71b749b2479d765558..d57ec22f44ab512746a3e16d094ab4eeb67e135a 100644 (file)
@@ -1282,10 +1282,19 @@ static bool isLegalUse(const TargetLowering::AddrMode &AM,
     // If we have low-level target information, ask the target if it can fold an
     // integer immediate on an icmp.
     if (AM.BaseOffs != 0) {
-      if (TLI) return TLI->isLegalICmpImmediate(-(uint64_t)AM.BaseOffs);
-      return false;
+      if (!TLI)
+        return false;
+      // We have one of:
+      // ICmpZero     BaseReg + Offset => ICmp BaseReg, -Offset
+      // ICmpZero -1*ScaleReg + Offset => ICmp ScaleReg, Offset
+      // Offs is the ICmp immediate.
+      int64_t Offs = AM.BaseOffs;
+      if (AM.Scale == 0)
+        Offs = -(uint64_t)Offs; // The cast does the right thing with INT64_MIN.
+      return TLI->isLegalICmpImmediate(Offs);
     }
 
+    // ICmpZero BaseReg + -1*ScaleReg => ICmp BaseReg, ScaleReg
     return true;
 
   case LSRUse::Basic:
index f53ac17876f26f3ee3a19554a1c90e8f2dd5ed09..7316452cd617abfb3a026dc87aba4dfc1027479d 100644 (file)
 ; CHECK: movls
 ; CHECK-NOT: mov
 
+; This is really an LSR test: Make sure that cmp is using the incremented
+; induction variable.
 ; CHECK: %if.end8
+; CHECK: add{{(s|\.w)?}} [[IV:r[0-9]+]], {{.*}}#1
+; CHECK: cmp [[IV]], #
 
 define i32 @f(i32* nocapture %a, i32 %Pref) nounwind ssp {
 entry: