[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