From 3e6767ed5f6d65300f0a7299a9d87944cb64eeb4 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 7 Oct 2022 13:05:39 -0400 Subject: [PATCH] [InstCombine] propagate 'exact' when converting ashr to lshr The shift amount is not changing, so if we guaranteed shifting out zeros before, those bits are still zeros. https://alive2.llvm.org/ce/z/sokQca --- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 7 +++++-- llvm/test/Transforms/InstCombine/ashr-lshr.ll | 4 ++-- llvm/test/Transforms/InstCombine/inselt-binop-inseltpoison.ll | 2 +- llvm/test/Transforms/InstCombine/inselt-binop.ll | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 83de1d5..9f5d147 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1482,8 +1482,11 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) { return R; // See if we can turn a signed shr into an unsigned shr. - if (MaskedValueIsZero(Op0, APInt::getSignMask(BitWidth), 0, &I)) - return BinaryOperator::CreateLShr(Op0, Op1); + if (MaskedValueIsZero(Op0, APInt::getSignMask(BitWidth), 0, &I)) { + Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1); + Lshr->setIsExact(I.isExact()); + return Lshr; + } // ashr (xor %x, -1), %y --> xor (ashr %x, %y), -1 if (match(Op0, m_OneUse(m_Not(m_Value(X))))) { diff --git a/llvm/test/Transforms/InstCombine/ashr-lshr.ll b/llvm/test/Transforms/InstCombine/ashr-lshr.ll index 1ee5c9a..60fa5b2 100644 --- a/llvm/test/Transforms/InstCombine/ashr-lshr.ll +++ b/llvm/test/Transforms/InstCombine/ashr-lshr.ll @@ -586,7 +586,7 @@ define <3 x i43> @ashr_sub_nsw_splat_undef(<3 x i43> %x, <3 x i43> %y) { define i8 @ashr_known_pos_exact(i8 %x, i8 %y) { ; CHECK-LABEL: @ashr_known_pos_exact( ; CHECK-NEXT: [[P:%.*]] = and i8 [[X:%.*]], 127 -; CHECK-NEXT: [[R:%.*]] = lshr i8 [[P]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = lshr exact i8 [[P]], [[Y:%.*]] ; CHECK-NEXT: ret i8 [[R]] ; %p = and i8 %x, 127 @@ -597,7 +597,7 @@ define i8 @ashr_known_pos_exact(i8 %x, i8 %y) { define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @ashr_known_pos_exact_vec( ; CHECK-NEXT: [[P:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[X]] -; CHECK-NEXT: [[R:%.*]] = lshr <2 x i8> [[P]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i8> [[P]], [[Y:%.*]] ; CHECK-NEXT: ret <2 x i8> [[R]] ; %p = mul nsw <2 x i8> %x, %x diff --git a/llvm/test/Transforms/InstCombine/inselt-binop-inseltpoison.ll b/llvm/test/Transforms/InstCombine/inselt-binop-inseltpoison.ll index 872a0ed..0945386 100644 --- a/llvm/test/Transforms/InstCombine/inselt-binop-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/inselt-binop-inseltpoison.ll @@ -149,7 +149,7 @@ define <2 x i8> @ashr_constant_op0(i8 %x) { define <2 x i8> @ashr_constant_op0_not_undef_lane(i8 %x) { ; CHECK-LABEL: @ashr_constant_op0_not_undef_lane( ; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> poison, i8 [[X:%.*]], i64 1 -; CHECK-NEXT: [[BO:%.*]] = lshr <2 x i8> , [[INS]] +; CHECK-NEXT: [[BO:%.*]] = lshr exact <2 x i8> , [[INS]] ; CHECK-NEXT: ret <2 x i8> [[BO]] ; %ins = insertelement <2 x i8> poison, i8 %x, i32 1 diff --git a/llvm/test/Transforms/InstCombine/inselt-binop.ll b/llvm/test/Transforms/InstCombine/inselt-binop.ll index 6f0672a..6592a59 100644 --- a/llvm/test/Transforms/InstCombine/inselt-binop.ll +++ b/llvm/test/Transforms/InstCombine/inselt-binop.ll @@ -149,7 +149,7 @@ define <2 x i8> @ashr_constant_op0(i8 %x) { define <2 x i8> @ashr_constant_op0_not_undef_lane(i8 %x) { ; CHECK-LABEL: @ashr_constant_op0_not_undef_lane( ; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> undef, i8 [[X:%.*]], i64 1 -; CHECK-NEXT: [[BO:%.*]] = lshr <2 x i8> , [[INS]] +; CHECK-NEXT: [[BO:%.*]] = lshr exact <2 x i8> , [[INS]] ; CHECK-NEXT: ret <2 x i8> [[BO]] ; %ins = insertelement <2 x i8> undef, i8 %x, i32 1 -- 2.7.4