Skip to content

Commit

Permalink
[InstCombine] guard against splat-mul corner case
Browse files Browse the repository at this point in the history
The test is already simplified, and I'm not sure how
to write a test to exercise the new clause. But it
protects the 2-bit pattern from miscompiling as noted
in D123453.

https://alive2.llvm.org/ce/z/QPyVfv
(If we managed to fall into the mul transform, it
would wrongly create a zero on this pattern.)
  • Loading branch information
rotateright committed Apr 11, 2022
1 parent aafb428 commit 1206a18
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1165,11 +1165,11 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {

// Look for a "splat" mul pattern - it replicates bits across each half of
// a value, so a right shift is just a mask of the low bits:
// lshr i32 (mul nuw X, Pow2+1), 16 --> and X, Pow2-1
// lshr i[2N] (mul nuw X, (2^N)+1), N --> and iN X, (2^N)-1
// TODO: Generalize to allow more than just half-width shifts?
const APInt *MulC;
if (match(Op0, m_NUWMul(m_Value(X), m_APInt(MulC))) &&
ShAmtC * 2 == BitWidth && (*MulC - 1).isPowerOf2() &&
BitWidth > 2 && ShAmtC * 2 == BitWidth && (*MulC - 1).isPowerOf2() &&
MulC->logBase2() == ShAmtC)
return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, *MulC - 2));

Expand Down
11 changes: 11 additions & 0 deletions llvm/test/Transforms/InstCombine/lshr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,17 @@ define i32 @mul_splat_fold_no_nuw(i32 %x) {
ret i32 %t
}

; Negative test (but simplifies before we reach the mul_splat transform)- need more than 2 bits

define i2 @mul_splat_fold_too_narrow(i2 %x) {
; CHECK-LABEL: @mul_splat_fold_too_narrow(
; CHECK-NEXT: ret i2 [[X:%.*]]
;
%m = mul nuw i2 %x, 2
%t = lshr i2 %m, 1
ret i2 %t
}

define i32 @negative_and_odd(i32 %x) {
; CHECK-LABEL: @negative_and_odd(
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
Expand Down

0 comments on commit 1206a18

Please sign in to comment.