[PATCH] D156811: [InstCombine] Fold `select` of `srem` and conditional add
Antonio Frighetto via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 1 14:34:48 PDT 2023
antoniofrighetto added a comment.
Thanks for reviewing it, and for the note! Updated proofs & changes, and rebased.
================
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
----------------
goldstein.w.n wrote:
> Can you remove the NSW from the comment / all the alive2 links. It makes it seem like the `nsw` is necessary for correctness.
Dropped, thanks.
================
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))
----------------
goldstein.w.n wrote:
> goldstein.w.n wrote:
> > This also works for `urem`, unless that already gets properly folded, can you also support that here?
> If `urem` already gets properly folded, then if its in some clear place can you just update that codes to work for the srem case as well (instead of adding an entirely new sequence for srem).
`urem` is directly folded into an `and` upon entering `visitURem` as it can only take positive values. `srem` requires dedicated handling instead.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2616
+ Pred == ICmpInst::ICMP_SLT && CmpCond == Rem))
+ return nullptr;
+
----------------
goldstein.w.n wrote:
> 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.
Moved above, and moved from using `m_Power2` to the generic `isKnownToBeAPowerOfTwo`.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2618
+
+ Value *Mask = ConstantInt::get(Rem->getType(), I0->getZExtValue() - 1);
+ return BinaryOperator::CreateAnd(Op, Mask);
----------------
goldstein.w.n wrote:
> 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.
Right, `getZExtValue` does not really look good when handling `i128`. Moved to using `getAllOnesValue`, thanks.
================
Comment at: llvm/test/Transforms/InstCombine/select-divrem.ll:239
+ ret i32 %sel
+}
----------------
goldstein.w.n wrote:
> 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).
Tests updated, I'll be pre-comitting them should they look OK.
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