Skip to content

Commit

Permalink
[InstSimplify] (-1 << x) s>> x --> -1
Browse files Browse the repository at this point in the history
  • Loading branch information
rotateright committed Sep 29, 2021
1 parent 7f1cb43 commit 4414e2a
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 18 deletions.
6 changes: 4 additions & 2 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
;
Expand Down
18 changes: 9 additions & 9 deletions llvm/test/Transforms/InstSimplify/shift.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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> <i7 -1, i7 -1>, [[X:%.*]]
; CHECK-NEXT: [[RIGHT:%.*]] = ashr <2 x i7> [[LEFT]], [[X]]
; CHECK-NEXT: ret <2 x i7> [[RIGHT]]
; CHECK-NEXT: ret <2 x i7> <i7 -1, i7 -1>
;
%left = shl <2 x i7> <i7 -1, i7 -1>, %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> <i7 poison, i7 -1, i7 undef>, [[X:%.*]]
; CHECK-NEXT: [[RIGHT:%.*]] = ashr <3 x i7> [[LEFT]], [[X]]
; CHECK-NEXT: ret <3 x i7> [[RIGHT]]
; CHECK-NEXT: ret <3 x i7> <i7 -1, i7 -1, i7 -1>
;
%left = shl <3 x i7> <i7 poison, i7 -1, i7 undef>, %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:%.*]]
Expand All @@ -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:%.*]]
Expand Down

0 comments on commit 4414e2a

Please sign in to comment.