LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 8862 - ashr, lshr, shl, udiv should have an 'isexact' bit indicating it is known to only shift out zeros
Summary: ashr, lshr, shl, udiv should have an 'isexact' bit indicating it is known to ...
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords: code-quality
Depends on:
Blocks: 8882 8942
  Show dependency tree
 
Reported: 2010-12-26 17:50 PST by Chris Lattner
Modified: 2011-02-09 23:39 PST (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lattner 2010-12-26 17:50:11 PST
Instcombine should compile this identity function to return X:


define i32 @test(i32 %X) {
  %A = sdiv exact i32 %X, 4
  %B = mul i32 %A, 4
  ret i32 %B
}

instead we get:


define i32 @test(i32 %X) {
  %A1 = and i32 %X, -4
  ret i32 %A1
}

This is because it simplifies the sdiv into an ashr instruction, which loses information.  This sort of thing comes up when handling array/pointer difference stuff.

To fix this, SDISel whould lower sdiv exact into ashr, instcombine should handle sdiv's as aggressively as ashr's, and then we should stop canonicalizing ashr to sdiv in instcombine.
Comment 1 Chris Lattner 2010-12-26 18:11:00 PST
Another, possibly better, solution is to add an "isexact" sort of bit to the ashr instruction.  This would indicate that no bits get shifted out, and would make just as much sense for left and right logical shifts.
Comment 2 Chris Lattner 2011-01-09 17:02:52 PST
*** Bug 8882 has been marked as a duplicate of this bug. ***
Comment 3 Chris Lattner 2011-01-09 17:04:07 PST
PR8882 is an example that shows the need for this bit for SHL.  SCEV has an example where it knows that udivs are exact (see r123139) and we'd like to be able to represent this too.
Comment 4 Chris Lattner 2011-02-09 12:12:29 PST
This is largely in now, I have a bunch of instcombine changes to detangle from each other and plan to submit them later this afternoon.
Comment 5 Chris Lattner 2011-02-09 23:39:33 PST
This is now implemented in a series of patches leading up to r125267.

We now have get:

$ opt -instcombine -S 
define i32 @test(i32 %X) {
  %A = sdiv exact i32 %X, 4
  %B = mul i32 %A, 4
  ret i32 %B
}
^D
; ModuleID = '<stdin>'

define i32 @test(i32 %X) {
  ret i32 %X
}