diff options
author | csstormq <swust_xiaoqiangxu@163.com> | 2024-06-08 08:38:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-08 08:38:27 +0800 |
commit | 96af11494158c38dafb64ffeaec3f371f37f0eb4 (patch) | |
tree | d094cb1a539de7acd8d4053d17754d7ad4ce2ea4 /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | |
parent | dc3f8c2f587e9647d1ce86426c2cf317c98f453c (diff) | |
download | llvm-96af11494158c38dafb64ffeaec3f371f37f0eb4.zip llvm-96af11494158c38dafb64ffeaec3f371f37f0eb4.tar.gz llvm-96af11494158c38dafb64ffeaec3f371f37f0eb4.tar.bz2 |
[InstCombine] Preserve the nsw/nuw flags for (X | Op01C) + Op1C --> X + (Op01C + Op1C) (#94586)
This patch simplifies `sdiv` to `udiv` by preserving the `nsw` flag for
`(X | Op01C) + Op1C --> X + (Op01C + Op1C)` if the sum of `Op01C` and
`Op1C` will not overflow, and preserves the `nuw` flag unconditionally.
Alive2 Proofs (provided by @nikic): https://alive2.llvm.org/ce/z/nrdCZT,
https://alive2.llvm.org/ce/z/YnJHnH
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 8205b49..0a73c58 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -905,8 +905,14 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) { // (X | Op01C) + Op1C --> X + (Op01C + Op1C) iff the `or` is actually an `add` Constant *Op01C; - if (match(Op0, m_DisjointOr(m_Value(X), m_ImmConstant(Op01C)))) - return BinaryOperator::CreateAdd(X, ConstantExpr::getAdd(Op01C, Op1C)); + if (match(Op0, m_DisjointOr(m_Value(X), m_ImmConstant(Op01C)))) { + BinaryOperator *NewAdd = + BinaryOperator::CreateAdd(X, ConstantExpr::getAdd(Op01C, Op1C)); + NewAdd->setHasNoSignedWrap(Add.hasNoSignedWrap() && + willNotOverflowSignedAdd(Op01C, Op1C, Add)); + NewAdd->setHasNoUnsignedWrap(Add.hasNoUnsignedWrap()); + return NewAdd; + } // (X | C2) + C --> (X | C2) ^ C2 iff (C2 == -C) const APInt *C2; |