[InstCombine] propagate 'exact' when converting ashr to lshr
authorSanjay Patel <spatel@rotateright.com>
Fri, 7 Oct 2022 17:05:39 +0000 (13:05 -0400)
committerSanjay Patel <spatel@rotateright.com>
Fri, 7 Oct 2022 17:17:19 +0000 (13:17 -0400)
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
llvm/test/Transforms/InstCombine/ashr-lshr.ll
llvm/test/Transforms/InstCombine/inselt-binop-inseltpoison.ll
llvm/test/Transforms/InstCombine/inselt-binop.ll

index 83de1d5..9f5d147 100644 (file)
@@ -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))))) {
index 1ee5c9a..60fa5b2 100644 (file)
@@ -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
index 872a0ed..0945386 100644 (file)
@@ -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> <i8 5, i8 2>, [[INS]]
+; CHECK-NEXT:    [[BO:%.*]] = lshr exact <2 x i8> <i8 5, i8 2>, [[INS]]
 ; CHECK-NEXT:    ret <2 x i8> [[BO]]
 ;
   %ins = insertelement <2 x i8> poison, i8 %x, i32 1
index 6f0672a..6592a59 100644 (file)
@@ -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> <i8 5, i8 2>, [[INS]]
+; CHECK-NEXT:    [[BO:%.*]] = lshr exact <2 x i8> <i8 5, i8 2>, [[INS]]
 ; CHECK-NEXT:    ret <2 x i8> [[BO]]
 ;
   %ins = insertelement <2 x i8> undef, i8 %x, i32 1