Skip to content

Commit

Permalink
[InstCombine] relax constraint on udiv fold
Browse files Browse the repository at this point in the history
The pair of div folds was just added with:
4966d8e

But as noted in the post-commit review, we don't actually need
the no-remainder requirement for an unsigned division (still
need the no-unsigned-wrap though):
https://alive2.llvm.org/ce/z/qHjK3Q
  • Loading branch information
rotateright committed Feb 20, 2023
1 parent 997dc7e commit 703423c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
12 changes: 8 additions & 4 deletions llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1027,16 +1027,20 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {

// Distribute div over add to eliminate a matching div/mul pair:
// ((X * C2) + C1) / C2 --> X + C1/C2
// We need a multiple of the divisor for a signed add constant, but
// unsigned is fine with any constant pair.
if (IsSigned &&
match(Op0, m_NSWAdd(m_NSWMul(m_Value(X), m_SpecificInt(*C2)),
m_APInt(C1))) &&
isMultiple(*C1, *C2, Quotient, IsSigned))
isMultiple(*C1, *C2, Quotient, IsSigned)) {
return BinaryOperator::CreateNSWAdd(X, ConstantInt::get(Ty, Quotient));
}
if (!IsSigned &&
match(Op0, m_NUWAdd(m_NUWMul(m_Value(X), m_SpecificInt(*C2)),
m_APInt(C1))) &&
isMultiple(*C1, *C2, Quotient, IsSigned))
return BinaryOperator::CreateNUWAdd(X, ConstantInt::get(Ty, Quotient));
m_APInt(C1)))) {
return BinaryOperator::CreateNUWAdd(X,
ConstantInt::get(Ty, C1->udiv(*C2)));
}

if (!C2->isZero()) // avoid X udiv 0
if (Instruction *FoldedDiv = foldBinOpIntoSelectOrPhi(I))
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/Transforms/InstCombine/div.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1552,13 +1552,11 @@ define i6 @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset(i6 %x) {
ret i6 %div
}

; negative test - constants must be evenly divisible
; constants do not have to be evenly divisible with unsigned division

define i6 @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(i6 %x) {
; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i6 [[X:%.*]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nuw i6 [[MUL]], 7
; CHECK-NEXT: [[DIV:%.*]] = udiv i6 [[ADD]], 3
; CHECK-NEXT: [[DIV:%.*]] = add nuw i6 [[X:%.*]], 2
; CHECK-NEXT: ret i6 [[DIV]]
;
%mul = mul nuw i6 %x, 3
Expand Down

0 comments on commit 703423c

Please sign in to comment.