[PATCH] D156811: [InstCombine] Fold `select` of `srem` and conditional add
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 1 10:54:28 PDT 2023
goldstein.w.n added a comment.
A note about the proofs. You proved this when the remander is 8, not generically for any power of 2. Proofs with constants should generally look more like: https://alive2.llvm.org/ce/z/9_KG6c
i.e instead of declaring with the constant is, declare the constraints you have on it.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2604
+ // %cnd = icmp slt i32 %rem, 0
+ // %add = add nsw i32 %rem, %n
+ // %sel = select i1 %cnd, i32 %add, i32 %rem
----------------
Can you remove the NSW from the comment / all the alive2 links. It makes it seem like the `nsw` is necessary for correctness.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2608
+ if (!(match(TrueVal, m_Add(m_Value(Rem), m_Power2(I0))) &&
+ match(Rem, m_SRem(m_Value(Op), m_Power2(I1))) && FalseVal == Rem &&
+ I0 == I1))
----------------
This also works for `urem`, unless that already gets properly folded, can you also support that here?
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2609
+ match(Rem, m_SRem(m_Value(Op), m_Power2(I1))) && FalseVal == Rem &&
+ I0 == I1))
+ return nullptr;
----------------
Just use `m_SpecificInt(I0)` instead of `I1` and drop this equality comparison.
Although really, this doesn't need to be an integer at all, it could be:
```
if (!(match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) &&
match(RemRes, m_SRem(m_Value(Op), m_Specific(m_Value(Remainder))) && FalseVal == RemRes &&
&& isKnownToBeAPowerOfTwo(Remainder, ...)))
```
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2616
+ Pred == ICmpInst::ICMP_SLT && CmpCond == Rem))
+ return nullptr;
+
----------------
Can you move this check to before the other match. 1) think its clearer, 2) if you add the generic `isKnownToBeAPowerOfTwo` approach is good to exhaust all the cheap checks before the recursive call.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2618
+
+ Value *Mask = ConstantInt::get(Rem->getType(), I0->getZExtValue() - 1);
+ return BinaryOperator::CreateAnd(Op, Mask);
----------------
getZExtValue is really okay here, what if its an i128?
You can build a ConstantInt directly from an APInt, so just `*I0` should be okay here.
================
Comment at: llvm/test/Transforms/InstCombine/select-divrem.ll:239
+ ret i32 %sel
+}
----------------
The tests should be precommit,.
They are also insufficient. Can you add some negative cases for: incorrect sign test, add with different constant, wrong operand positions in select.
Can you also add a test that use vecs, and add one where the datatype is i128 (as your current code seems to be buggy there).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D156811/new/
https://reviews.llvm.org/D156811
More information about the llvm-commits
mailing list