[PATCH] D45976: [InstCombine] Simplify Add with remainder expressions as operands.

Sanjoy Das via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 24 12:02:13 PDT 2018


sanjoy requested changes to this revision.
sanjoy added a comment.
This revision now requires changes to proceed.

Mostly nits except for the comment with the Alive proofs (didn't get to the meat of the patch yet).



================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1035
 
+// Simplifies X % C0 + (( X / C0 ) % C1) * C0 to X % (C0 * C1).
+Instruction *InstCombiner::SimplifyAddWithRemainder(BinaryOperator &I) {
----------------
Are these correct interpretations of this transform:

https://rise4fun.com/Alive/j4G (signed)
https://rise4fun.com/Alive/RQB (unsigned)

?  If so, Alive seems to think they're incorrect.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1037
+Instruction *InstCombiner::SimplifyAddWithRemainder(BinaryOperator &I) {
+  if (I.getOpcode() != Instruction::Add)
+    return nullptr;
----------------
Can this condition ever be false?  You're calling this only from `visitAdd` right?


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1045
+    ConstantInt *CI;
+    if (match(E, m_Mul(m_Value(Op), m_ConstantInt(CI)))) {
+      C = CI->getValue();
----------------
Use `m_APInt` instead of manually calling `CI->getValue()`.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1049
+    } else if (match(E, m_Shl(m_Value(Op), m_ConstantInt(CI)))) {
+      C = APInt(CI->getBitWidth(), 1);
+      C <<= CI->getValue();
----------------
Is this lifetime of this `APInt` correct?  Won't it go out of scope once `MatchMul` returns?


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1064
+        match(E, m_URem(m_Value(Op), m_ConstantInt(CI))) ||
+        (match(E, m_And(m_Value(Op), m_ConstantInt(CI))) &&
+         (CI->getValue() + 1).isPowerOf2())) {
----------------
Use `m_APInt` here too.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1070
+        C++;
+      IsSigned = (Opcode == Instruction::SRem);
+      return true;
----------------
Braces around `Opcode == Instruction::SRem` are not necessary.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1087
+                match(E, m_LShr(m_Value(Op), m_ConstantInt(CI))))) {
+      C = CI->getValue();
+      if (cast<Instruction>(E)->getOpcode() == Instruction::LShr) {
----------------
Probably better to do this as a separate change, but it might be nice to push all of this logic (division as `udiv` or as an `lshr`) into a matcher.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1098
+  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
+  Value *X, *MulOpv;
+  APInt C0, MulOpc;
----------------
LLVM style would be `MulOpV` and `MulOpC`, but you can also say `MulLHS` and `MulRHS` -- you can tell which is constant and which isn't by the C++ type.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1101
+  bool IsSigned;
+  if (((MatchRem(LHS, X, C0, IsSigned) && MatchMul(RHS, MulOpv, MulOpc)) ||
+       (MatchRem(RHS, X, C0, IsSigned) && MatchMul(LHS, MulOpv, MulOpc))) &&
----------------
I don't think you need the `(` around the call to `MatchRem`.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1101
+  bool IsSigned;
+  if (((MatchRem(LHS, X, C0, IsSigned) && MatchMul(RHS, MulOpv, MulOpc)) ||
+       (MatchRem(RHS, X, C0, IsSigned) && MatchMul(LHS, MulOpv, MulOpc))) &&
----------------
sanjoy wrote:
> I don't think you need the `(` around the call to `MatchRem`.
I think this sort of thing will be more readable if you give examples of what you're matching using the C++ names right before the `if`:

```
// Match I = (X  % C0) + (MulOpv * MulOpc)
```

etc.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1107
+    bool Rem2_IsSigned;
+    if (MatchRem(MulOpv, RemOpv, C1, Rem2_IsSigned) &&
+        IsSigned == Rem2_IsSigned) {
----------------
Same here:

```
// Match MulOpv = RemOpv % C1
```

though here the benefit is less because the code is simpler.


================
Comment at: lib/Transforms/InstCombine/InstCombineAddSub.cpp:1120
+        Instruction *NewInst = cast<Instruction>(NewVal);
+        return replaceInstUsesWith(I, NewInst);
+      }
----------------
Can just be `replaceInstUsesWith(I, cast<Instruction>(NewVal))`.  However, please state why `NewVal` can not be a constant.


Repository:
  rL LLVM

https://reviews.llvm.org/D45976





More information about the llvm-commits mailing list