diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 8832ccecb3668..ed6425fad15b5 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1429,9 +1429,11 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, MaxRecurse)) return V; - // all ones >>a X -> -1 + // -1 >>a X --> -1 + // (-1 << X) a>> X --> -1 // Do not return Op0 because it may contain undef elements if it's a vector. - if (match(Op0, m_AllOnes())) + if (match(Op0, m_AllOnes()) || + match(Op0, m_Shl(m_AllOnes(), m_Specific(Op1)))) return Constant::getAllOnesValue(Op0->getType()); // (X << A) >> A -> X diff --git a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll index efc2323c9dd29..147192c02262f 100644 --- a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll +++ b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll @@ -246,17 +246,12 @@ define i32 @n6_extrause2(i64 %x, i32 %nbits) { ret i32 %t6 } -; TODO: shl+ashr of -1 should be reducecd. ; This is a miscompile if it ends by masking off the high bit of the result. define i32 @PR51351(i64 %x, i32 %nbits) { ; CHECK-LABEL: @PR51351( -; CHECK-NEXT: [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64 -; CHECK-NEXT: [[T1:%.*]] = shl i64 -1, [[T0]] -; CHECK-NEXT: [[T2:%.*]] = ashr i64 [[T1]], [[T0]] -; CHECK-NEXT: [[T3:%.*]] = add i32 [[NBITS]], -33 -; CHECK-NEXT: [[T4:%.*]] = and i64 [[T2]], [[X:%.*]] -; CHECK-NEXT: [[T5:%.*]] = trunc i64 [[T4]] to i32 +; CHECK-NEXT: [[T3:%.*]] = add i32 [[NBITS:%.*]], -33 +; CHECK-NEXT: [[T5:%.*]] = trunc i64 [[X:%.*]] to i32 ; CHECK-NEXT: [[T6:%.*]] = shl i32 [[T5]], [[T3]] ; CHECK-NEXT: ret i32 [[T6]] ; diff --git a/llvm/test/Transforms/InstSimplify/shift.ll b/llvm/test/Transforms/InstSimplify/shift.ll index fa144f6bddf87..c6b7a1406d650 100644 --- a/llvm/test/Transforms/InstSimplify/shift.ll +++ b/llvm/test/Transforms/InstSimplify/shift.ll @@ -288,9 +288,7 @@ define i32 @poison6(i32 %x) { define i32 @all_ones_left_right(i32 %x) { ; CHECK-LABEL: @all_ones_left_right( -; CHECK-NEXT: [[LEFT:%.*]] = shl i32 -1, [[X:%.*]] -; CHECK-NEXT: [[RIGHT:%.*]] = ashr i32 [[LEFT]], [[X]] -; CHECK-NEXT: ret i32 [[RIGHT]] +; CHECK-NEXT: ret i32 -1 ; %left = shl i32 -1, %x %right = ashr i32 %left, %x @@ -299,26 +297,26 @@ define i32 @all_ones_left_right(i32 %x) { define <2 x i7> @all_ones_left_right_splat(<2 x i7> %x) { ; CHECK-LABEL: @all_ones_left_right_splat( -; CHECK-NEXT: [[LEFT:%.*]] = shl <2 x i7> , [[X:%.*]] -; CHECK-NEXT: [[RIGHT:%.*]] = ashr <2 x i7> [[LEFT]], [[X]] -; CHECK-NEXT: ret <2 x i7> [[RIGHT]] +; CHECK-NEXT: ret <2 x i7> ; %left = shl <2 x i7> , %x %right = ashr <2 x i7> %left, %x ret <2 x i7> %right } +; Poison could propagate, but undef must not. + define <3 x i7> @all_ones_left_right_splat_poison_undef_elt(<3 x i7> %x) { ; CHECK-LABEL: @all_ones_left_right_splat_poison_undef_elt( -; CHECK-NEXT: [[LEFT:%.*]] = shl <3 x i7> , [[X:%.*]] -; CHECK-NEXT: [[RIGHT:%.*]] = ashr <3 x i7> [[LEFT]], [[X]] -; CHECK-NEXT: ret <3 x i7> [[RIGHT]] +; CHECK-NEXT: ret <3 x i7> ; %left = shl <3 x i7> , %x %right = ashr <3 x i7> %left, %x ret <3 x i7> %right } +; negative test - must have -1 + define i32 @almost_all_ones_left_right(i32 %x) { ; CHECK-LABEL: @almost_all_ones_left_right( ; CHECK-NEXT: [[LEFT:%.*]] = shl i32 -2, [[X:%.*]] @@ -330,6 +328,8 @@ define i32 @almost_all_ones_left_right(i32 %x) { ret i32 %right } +; negative test - must have same shift amount + define i32 @all_ones_left_right_not_same_shift(i32 %x, i32 %y) { ; CHECK-LABEL: @all_ones_left_right_not_same_shift( ; CHECK-NEXT: [[LEFT:%.*]] = shl i32 -1, [[X:%.*]]