This is an archive of the discontinued LLVM Phabricator instance.

Bug fix and a proposed improvement in integer division expansion
AbandonedPublic

Authored by dshtilman on Nov 17 2016, 3:21 PM.

Details

Reviewers
None
Summary

The special case code in udiv expansion is currently broken, namely the check for divisor==1 :

` // ; special-cases:

// ;   %ret0_1      = icmp eq i32 %divisor, 0
// ;   %ret0_2      = icmp eq i32 %dividend, 0
// ;   %ret0_3      = or i1 %ret0_1, %ret0_2
// ;   %tmp0        = tail call i32 @llvm.ctlz.i32(i32 %divisor, i1 true)
// ;   %tmp1        = tail call i32 @llvm.ctlz.i32(i32 %dividend, i1 true)
// ;   %sr          = sub nsw i32 %tmp0, %tmp1
// ;   %ret0_4      = icmp ugt i32 %sr, 31
// ;   %ret0        = or i1 %ret0_3, %ret0_4
// ;   %retDividend = icmp eq i32 **%sr**, 31
// ;   %retVal      = select i1 %ret0, i32 0, i32 %dividend
// ;   %earlyRet    = or i1 %ret0, %retDividend
// ;   br i1 %earlyRet, label %end, label %bb1

`
The intention must have been to use %tmp0, not %sr.

The following patch fixes this special case and also extends it to cover divisions by a power of 2 which will be routed through a simple shift right instead of going through the huge loop. Division by 1 will also go through the shift right yielding the dividend (shifted by zero).

Diff Detail

Repository
rL LLVM

Event Timeline

dshtilman updated this revision to Diff 78423.Nov 17 2016, 3:21 PM
dshtilman retitled this revision from to Bug fix and a proposed improvement in integer division expansion.
dshtilman updated this object.
dshtilman set the repository for this revision to rL LLVM.
dshtilman added a subscriber: qcolombet.
dshtilman updated this revision to Diff 78429.Nov 17 2016, 4:07 PM
dshtilman removed rL LLVM as the repository for this revision.
dshtilman updated this revision to Diff 78432.Nov 17 2016, 4:18 PM
dshtilman set the repository for this revision to rL LLVM.
dshtilman abandoned this revision.Nov 29 2016, 7:07 PM