[PATCH] D124369: [InstCombine] C0 >>{ashr, exact} (X - C1) --> (C0 << C1) >>{ashr} X

Nicolas Abram via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 02:52:44 PDT 2022


nico-abram created this revision.
nico-abram added a reviewer: spatel.
Herald added a subscriber: hiraditya.
Herald added a project: All.
nico-abram requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

As described in https://github.com/llvm/llvm-project/issues/55016
alive2.llvm.org/ce/z/qzh4oK

Also includes C0 >> (X - C1 <https://reviews.llvm.org/C1>) --> (C0 << C1 <https://reviews.llvm.org/C1>) >> X for positive C0 , which was mentioned in the gh issue as the more common case
https://alive2.llvm.org/ce/z/tHtIh2


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124369

Files:
  llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
  llvm/test/Transforms/InstCombine/shift-add.ll


Index: llvm/test/Transforms/InstCombine/shift-add.ll
===================================================================
--- llvm/test/Transforms/InstCombine/shift-add.ll
+++ llvm/test/Transforms/InstCombine/shift-add.ll
@@ -170,6 +170,26 @@
   ret i32 %r
 }
 
+define i32 @lshr_add_negative(i32 %x) {
+; CHECK-LABEL: @lshr_add_positive(
+; CHECK-NEXT:    [[R:%.*]] = lshr i32 4, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %a = add i32 %x, -1
+  %r = lshr i32 2, %a
+  ret i32 %r
+}
+
+define i32 @ashr_exact_add_negative(i32 %x) {
+; CHECK-LABEL: @ashr_exact_add_negative(
+; CHECK-NEXT:    [[R:%.*]] = ashr i32 -4, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %a = add i32 %x, -1
+  %r = ashr exact i32 -2, %a
+  ret i32 %r
+}
+
 ; PR54890
 
 define i32 @shl_nsw_add_negative(i32 %x) {
Index: llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1239,6 +1239,22 @@
     return BinaryOperator::CreateAnd(Mask, X);
   }
 
+  // Try to pre-shift a constant shifted by a variable amount:
+  // C >> (X - AddC) --> (C << AddC) >> X
+  // This requires a negative offset constant.
+  const APInt *AddC;
+  unsigned BitWidth = Ty->getScalarSizeInBits();
+  if (match(Op0, m_APInt(C)) && match(Op1, m_Add(m_Value(X), m_APInt(AddC))) &&
+      AddC->isNegative() && (-*AddC).ult(BitWidth)) {
+    assert(!C->isZero() && "Expected simplify of shifted zero");
+    unsigned PosOffset = (-*AddC).getZExtValue();
+    if (C->eq(C->shl(PosOffset).lshr(PosOffset))) {
+      Constant *NewC = ConstantInt::get(Ty, C->shl(PosOffset));
+      Instruction *NewLShr = BinaryOperator::CreateLShr(NewC, X);
+      return NewLShr;
+    }
+  }
+
   return nullptr;
 }
 
@@ -1427,5 +1443,22 @@
     return BinaryOperator::CreateNot(NewAShr);
   }
 
+  // Try to pre-shift a constant shifted by a variable amount:
+  // C >> (X - AddC) --> (C << AddC) >> X
+  // This requires the exact flag and a negative offset constant.
+  const APInt *AddC;
+  const APInt *C;
+  if (I.isExact() && match(Op0, m_APInt(C)) &&
+      match(Op1, m_Add(m_Value(X), m_APInt(AddC))) && AddC->isNegative() &&
+      (-*AddC).ult(BitWidth)) {
+    assert(!C->isZero() && "Expected simplify of shifted zero");
+    unsigned PosOffset = (-*AddC).getZExtValue();
+    if (C->eq(C->shl(PosOffset).ashr(PosOffset))) {
+      Constant *NewC = ConstantInt::get(Ty, C->shl(PosOffset));
+      Instruction *NewAShr = BinaryOperator::CreateAShr(NewC, X);
+      return NewAShr;
+    }
+  }
+
   return nullptr;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124369.424850.patch
Type: text/x-patch
Size: 2657 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220425/968246a0/attachment.bin>


More information about the llvm-commits mailing list