[PATCH] D49229: [InstCombine] Fold redundant masking operations of shifted value
Roman Lebedev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 23 07:50:22 PDT 2018
lebedev.ri added inline comments.
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2024
return replaceInstUsesWith(I, V);
+ { // Fold redundant masking.
+ const APInt *AndC, *ShAndC, *ShftAmt;
----------------
labrinea wrote:
> samparker wrote:
> > labrinea wrote:
> > > You could add a more descriptive comment like:
> > > ```// Fold redundant masking.
> > > // Let C3 = C1 lsh C2
> > > // (X & C1) | ((X lsh C2) & C3) -> (X & C1) | ((X & C1) lsh C2)
> > > // Also handles the commutative cases.
> > > ```
> > Looks like the convention here is to perform more specific folding after the calls to SimplifyAssociativeOrCommutative, etc.. And there is already a case for '(A & C)|(B & D)'.
> Yeap, Sam is right. Line 2079 of the original source.
Just put this into a new function and call it from here.
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2026-2027
+ const APInt *AndC, *ShAndC, *ShftAmt;
+ Value *X1, *X2;
+ if (match(&I, m_Or(m_c_And(m_Value(X1), m_APInt(AndC)),
+ m_c_And(m_OneUse(m_Shift(m_Value(X2), m_APInt(ShftAmt))),
----------------
s/`X1`/`X`/
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2027
+ Value *X1, *X2;
+ if (match(&I, m_Or(m_c_And(m_Value(X1), m_APInt(AndC)),
+ m_c_And(m_OneUse(m_Shift(m_Value(X2), m_APInt(ShftAmt))),
----------------
samparker wrote:
> labrinea wrote:
> > You could change that into `m_c_Or` to cover the commutative case too. Then you can get rid of the code duplication.
> We already know I is an Or.
> if (match(&I, m_Or(m_c_And(m_Value(X1), m_APInt(AndC)),
@labrinea is correct.
This is backwards. `m_c_And` won't ever matter. Constant will be rhs, So it should be `m_And`.
But this isn't true about `m_Or`, that one will be missing some commutative cases. It should be m_c_Or.
(i thought i commented that already?)
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2028
+ if (match(&I, m_Or(m_c_And(m_Value(X1), m_APInt(AndC)),
+ m_c_And(m_OneUse(m_Shift(m_Value(X2), m_APInt(ShftAmt))),
+ m_APInt(ShAndC)))) &&
----------------
Same here, constant will always be RHS, no need for commutativity.
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2028
+ if (match(&I, m_Or(m_c_And(m_Value(X1), m_APInt(AndC)),
+ m_c_And(m_OneUse(m_Shift(m_Value(X2), m_APInt(ShftAmt))),
+ m_APInt(ShAndC)))) &&
----------------
lebedev.ri wrote:
> Same here, constant will always be RHS, no need for commutativity.
s/`m_Value(X2)`/`m_Deferred(X)`/
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2030
+ m_APInt(ShAndC)))) &&
+ (X1 == X2)) {
+ BinaryOperator *And = cast<BinaryOperator>(I.getOperand(0));
----------------
And this is no longer needed.
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2049-2052
+ if (match(&I, m_Or(m_c_And(m_OneUse(m_Shift(m_Value(X2), m_APInt(ShftAmt))),
+ m_APInt(ShAndC)),
+ m_c_And(m_Value(X1), m_APInt(AndC)))) &&
+ (X1 == X2)) {
----------------
This should be
```
if (match(&I, m_c_Or(m_And(m_OneUse(m_Shift(m_Value(X), m_APInt(ShftAmt))),
m_APInt(ShAndC)),
m_And(m_Deferred(X), m_APInt(AndC)))) {
```
================
Comment at: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2053-2058
+ BinaryOperator *And = cast<BinaryOperator>(I.getOperand(1));
+ BinaryOperator *ShtAnd = cast<BinaryOperator>(I.getOperand(0));
+ BinaryOperator *Shift = cast<BinaryOperator>(
+ isa<BinaryOperator>(ShtAnd->getOperand(0)) ? ShtAnd->getOperand(0)
+ : ShtAnd->getOperand(1));
+ const Instruction::BinaryOps Opcode = Shift->getOpcode();
----------------
Capture them in `match()`.
https://reviews.llvm.org/D49229
More information about the llvm-commits
mailing list