Enhance the "compare with shift" and "compare with div"
authorChris Lattner <sabre@nondot.org>
Thu, 10 Feb 2011 05:23:05 +0000 (05:23 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 10 Feb 2011 05:23:05 +0000 (05:23 +0000)
commitb20c0b5092f11ff349855ec1e732590160aeba23
treea5c04b770a04d837eec981577a95a7963c82b504
parent44cc997d42f896c42a0d37fd8b98d9ec0cb28501
Enhance the "compare with shift" and "compare with div"
optimizations to be much more aggressive in the face of
exact/nsw/nuw div and shifts.  For example, these (which
are the same except the first is 'exact' sdiv:

define i1 @sdiv_icmp4_exact(i64 %X) nounwind {
  %A = sdiv exact i64 %X, -5   ; X/-5 == 0 --> x == 0
  %B = icmp eq i64 %A, 0
  ret i1 %B
}

define i1 @sdiv_icmp4(i64 %X) nounwind {
  %A = sdiv i64 %X, -5   ; X/-5 == 0 --> x == 0
  %B = icmp eq i64 %A, 0
  ret i1 %B
}

compile down to:

define i1 @sdiv_icmp4_exact(i64 %X) nounwind {
  %1 = icmp eq i64 %X, 0
  ret i1 %1
}

define i1 @sdiv_icmp4(i64 %X) nounwind {
  %X.off = add i64 %X, 4
  %1 = icmp ult i64 %X.off, 9
  ret i1 %1
}

This happens when you do something like:
  (ptr1-ptr2) == 42

where the pointers are pointers to non-unit types.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125266 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/exact.ll
test/Transforms/InstCombine/nsw.ll