Skip to content

Commit 1206a18

Browse files
committed
[InstCombine] guard against splat-mul corner case
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.)
1 parent aafb428 commit 1206a18

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,11 +1165,11 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
11651165

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

llvm/test/Transforms/InstCombine/lshr.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,17 @@ define i32 @mul_splat_fold_no_nuw(i32 %x) {
399399
ret i32 %t
400400
}
401401

402+
; Negative test (but simplifies before we reach the mul_splat transform)- need more than 2 bits
403+
404+
define i2 @mul_splat_fold_too_narrow(i2 %x) {
405+
; CHECK-LABEL: @mul_splat_fold_too_narrow(
406+
; CHECK-NEXT: ret i2 [[X:%.*]]
407+
;
408+
%m = mul nuw i2 %x, 2
409+
%t = lshr i2 %m, 1
410+
ret i2 %t
411+
}
412+
402413
define i32 @negative_and_odd(i32 %x) {
403414
; CHECK-LABEL: @negative_and_odd(
404415
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31

0 commit comments

Comments
 (0)