[PATCH] D91364: [InstCombine] fold low-bit mask of sext-in-reg
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 12 09:35:28 PST 2020
spatel created this revision.
spatel added reviewers: lebedev.ri, craig.topper, Bhramar.vatsa.
Herald added subscribers: hiraditya, mcrosier.
Herald added a project: LLVM.
spatel requested review of this revision.
This is an alternative to D91343 <https://reviews.llvm.org/D91343>. I do not have stats for how often the shl+ashr pattern (sext-in-reg) occurs, but we have an SDAG node for that operation, so it seems common enough to warrant a dedicated fold for this pattern:
https://rise4fun.com/Alive/vI9
https://reviews.llvm.org/D91364
Files:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/and.ll
Index: llvm/test/Transforms/InstCombine/and.ll
===================================================================
--- llvm/test/Transforms/InstCombine/and.ll
+++ llvm/test/Transforms/InstCombine/and.ll
@@ -979,7 +979,7 @@
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 20
; CHECK-NEXT: [[R:%.*]] = ashr exact i32 [[L]], 20
; CHECK-NEXT: call void @use32(i32 [[R]])
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[R]], 4095
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 4095
; CHECK-NEXT: ret i32 [[AND]]
;
%l = shl i32 %x, 20
@@ -989,6 +989,8 @@
ret i32 %and
}
+; Negative test - mismatched shift amounts
+
define i32 @lowmask_not_sext_in_reg(i32 %x) {
; CHECK-LABEL: @lowmask_not_sext_in_reg(
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 19
@@ -1004,6 +1006,8 @@
ret i32 %and
}
+; Negative test - too much shift for mask
+
define i32 @not_lowmask_sext_in_reg(i32 %x) {
; CHECK-LABEL: @not_lowmask_sext_in_reg(
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 20
@@ -1019,6 +1023,8 @@
ret i32 %and
}
+; Negative test - too much shift for mask
+
define i32 @not_lowmask_sext_in_reg2(i32 %x) {
; CHECK-LABEL: @not_lowmask_sext_in_reg2(
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 21
@@ -1039,7 +1045,7 @@
; CHECK-NEXT: [[L:%.*]] = shl <2 x i32> [[X:%.*]], <i32 20, i32 20>
; CHECK-NEXT: [[R:%.*]] = ashr exact <2 x i32> [[L]], <i32 20, i32 20>
; CHECK-NEXT: store <2 x i32> [[R]], <2 x i32>* [[P:%.*]], align 8
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[R]], <i32 4095, i32 4095>
+; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], <i32 4095, i32 4095>
; CHECK-NEXT: ret <2 x i32> [[AND]]
;
%l = shl <2 x i32> %x, <i32 20, i32 20>
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1817,9 +1817,9 @@
return BinaryOperator::Create(BinOp, NewLHS, Y);
}
}
- const APInt *ShiftC;
+ const APInt *ShiftC, *ShiftC2;
+ unsigned Width = Ty->getScalarSizeInBits();
if (match(Op0, m_OneUse(m_SExt(m_AShr(m_Value(X), m_APInt(ShiftC)))))) {
- unsigned Width = Ty->getScalarSizeInBits();
if (*C == APInt::getLowBitsSet(Width, Width - ShiftC->getZExtValue())) {
// We are clearing high bits that were potentially set by sext+ashr:
// and (sext (ashr X, ShiftC)), C --> lshr (sext X), ShiftC
@@ -1828,6 +1828,12 @@
return BinaryOperator::CreateLShr(Sext, ShAmtC);
}
}
+ // Peek through masking off the low bits of a sign-extend-in-register:
+ // and (ashr (shl X, ShiftC), ShiftC), C --> and X, C
+ if (match(Op0,
+ m_AShr(m_Shl(m_Value(X), m_APInt(ShiftC)), m_APInt(ShiftC2))) &&
+ ShiftC == ShiftC2 && (Width - ShiftC->getZExtValue()) > C->logBase2())
+ return BinaryOperator::CreateAnd(X, Op1);
}
ConstantInt *AndRHS;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91364.304870.patch
Type: text/x-patch
Size: 3008 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201112/20aa9ee3/attachment.bin>
More information about the llvm-commits
mailing list