Pass the right sign to TLI->isLegalICmpImmediate.

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>

llvm-svn: 154079
This commit is contained in:
Jakob Stoklund Olesen 2012-04-05 03:10:56 +00:00
parent 8382e4547f
commit f2390e8303
2 changed files with 15 additions and 2 deletions

View 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:

View File

@ -17,7 +17,11 @@
; 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: