[llvm] 080e6bc - [InstCombine] allow vector splats for add+and with high-mask
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 9 07:44:21 PDT 2020
Author: Sanjay Patel
Date: 2020-10-09T10:39:11-04:00
New Revision: 080e6bc2050e28ae198d82f0e934ca7b4548c3b7
URL: https://github.com/llvm/llvm-project/commit/080e6bc2050e28ae198d82f0e934ca7b4548c3b7
DIFF: https://github.com/llvm/llvm-project/commit/080e6bc2050e28ae198d82f0e934ca7b4548c3b7.diff
LOG: [InstCombine] allow vector splats for add+and with high-mask
There might be a better way to specify the pre-conditions,
but this is hopefully clearer than the way it was written:
https://rise4fun.com/Alive/Jhk3
Pre: C2 < 0 && isShiftedMask(C2) && (C1 == C1 & C2)
%a = and %x, C2
%r = add %a, C1
=>
%a2 = add %x, C1
%r = and %a2, C2
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/add.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 446085a3bdb3..7fc472de5790 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -958,6 +958,15 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
}
}
+ // If all bits affected by the add are included in a high-bit-mask, do the
+ // add before the mask op:
+ // (X & 0xFF00) + xx00 --> (X + xx00) & 0xFF00
+ if (match(Op0, m_OneUse(m_And(m_Value(X), m_APInt(C2)))) &&
+ C2->isNegative() && C2->isShiftedMask() && *C == (*C & *C2)) {
+ Value *NewAdd = Builder.CreateAdd(X, ConstantInt::get(Ty, *C));
+ return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *C2));
+ }
+
return nullptr;
}
@@ -1370,34 +1379,6 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT))
return BinaryOperator::CreateOr(LHS, RHS);
- // FIXME: We already did a check for ConstantInt RHS above this.
- // FIXME: Is this pattern covered by another fold? No regression tests fail on
- // removal.
- if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
- // (X & FF00) + xx00 -> (X+xx00) & FF00
- Value *X;
- ConstantInt *C2;
- if (LHS->hasOneUse() &&
- match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) &&
- CRHS->getValue() == (CRHS->getValue() & C2->getValue())) {
- // See if all bits from the first bit set in the Add RHS up are included
- // in the mask. First, get the rightmost bit.
- const APInt &AddRHSV = CRHS->getValue();
-
- // Form a mask of all bits from the lowest bit added through the top.
- APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));
-
- // See if the and mask includes all of these bits.
- APInt AddRHSHighBitsAnd(AddRHSHighBits & C2->getValue());
-
- if (AddRHSHighBits == AddRHSHighBitsAnd) {
- // Okay, the xform is safe. Insert the new add pronto.
- Value *NewAdd = Builder.CreateAdd(X, CRHS, LHS->getName());
- return BinaryOperator::CreateAnd(NewAdd, C2);
- }
- }
- }
-
// add (select X 0 (sub n A)) A --> select X A n
{
SelectInst *SI = dyn_cast<SelectInst>(LHS);
diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 0363cfe3a0d0..282d819e46dd 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -740,8 +740,8 @@ define i8 @test34(i8 %A) {
define i8 @masked_add(i8 %x) {
; CHECK-LABEL: @masked_add(
-; CHECK-NEXT: [[AND1:%.*]] = add i8 [[X:%.*]], 96
-; CHECK-NEXT: [[R:%.*]] = and i8 [[AND1]], -16
+; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 96
+; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP1]], -16
; CHECK-NEXT: ret i8 [[R]]
;
%and = and i8 %x, 240 ; 0xf0
@@ -751,8 +751,8 @@ define i8 @masked_add(i8 %x) {
define <2 x i8> @masked_add_splat(<2 x i8> %x) {
; CHECK-LABEL: @masked_add_splat(
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
-; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[AND]], <i8 64, i8 64>
+; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 64, i8 64>
+; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[TMP1]], <i8 -64, i8 -64>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0
More information about the llvm-commits
mailing list