diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-04-09 18:32:28 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-04-09 18:32:28 +0000 |
commit | eda3b9326e1f68cab38a5ae7923a4a20ff020d77 (patch) | |
tree | 400f8ca20c946a0209951f6a44af77875a8a1679 /llvm/lib/Transforms | |
parent | 202c9b99e00b37b8658c9e32708a84406a40c818 (diff) | |
download | bcm5719-llvm-eda3b9326e1f68cab38a5ae7923a4a20ff020d77.tar.gz bcm5719-llvm-eda3b9326e1f68cab38a5ae7923a4a20ff020d77.zip |
[InstCombine] Restructure OptimizeOverflowCheck; NFC
Change the code to always handle the unsigned+signed cases together
with the same basic structure for add/sub/mul. The simple folds are
always handled first and then the ValueTracking overflow checks are
used.
llvm-svn: 358025
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 59 |
1 files changed, 28 insertions, 31 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 7b589280593..3c0ef7e44bf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3961,29 +3961,25 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, case OCF_INVALID: llvm_unreachable("bad overflow check kind!"); - case OCF_UNSIGNED_ADD: { - OverflowResult OR = computeOverflowForUnsignedAdd(LHS, RHS, &OrigI); - if (OR == OverflowResult::NeverOverflows) - return SetResult(Builder.CreateNUWAdd(LHS, RHS), Builder.getFalse(), - true); - - if (OR == OverflowResult::AlwaysOverflows) - return SetResult(Builder.CreateAdd(LHS, RHS), Builder.getTrue(), true); - - // Fall through uadd into sadd - LLVM_FALLTHROUGH; - } + case OCF_UNSIGNED_ADD: case OCF_SIGNED_ADD: { // X + 0 -> {X, false} if (match(RHS, m_Zero())) return SetResult(LHS, Builder.getFalse(), false); - // We can strength reduce this signed add into a regular add if we can prove - // that it will never overflow. - if (OCF == OCF_SIGNED_ADD) + if (OCF == OCF_UNSIGNED_ADD) { + OverflowResult OR = computeOverflowForUnsignedAdd(LHS, RHS, &OrigI); + if (OR == OverflowResult::NeverOverflows) + return SetResult(Builder.CreateNUWAdd(LHS, RHS), Builder.getFalse(), + true); + + if (OR == OverflowResult::AlwaysOverflows) + return SetResult(Builder.CreateAdd(LHS, RHS), Builder.getTrue(), true); + } else { if (willNotOverflowSignedAdd(LHS, RHS, OrigI)) return SetResult(Builder.CreateNSWAdd(LHS, RHS), Builder.getFalse(), true); + } break; } @@ -3993,28 +3989,20 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, if (match(RHS, m_Zero())) return SetResult(LHS, Builder.getFalse(), false); - if (OCF == OCF_SIGNED_SUB) { - if (willNotOverflowSignedSub(LHS, RHS, OrigI)) - return SetResult(Builder.CreateNSWSub(LHS, RHS), Builder.getFalse(), - true); - } else { + if (OCF == OCF_UNSIGNED_SUB) { if (willNotOverflowUnsignedSub(LHS, RHS, OrigI)) return SetResult(Builder.CreateNUWSub(LHS, RHS), Builder.getFalse(), true); + } else { + if (willNotOverflowSignedSub(LHS, RHS, OrigI)) + return SetResult(Builder.CreateNSWSub(LHS, RHS), Builder.getFalse(), + true); } break; } - case OCF_UNSIGNED_MUL: { - OverflowResult OR = computeOverflowForUnsignedMul(LHS, RHS, &OrigI); - if (OR == OverflowResult::NeverOverflows) - return SetResult(Builder.CreateNUWMul(LHS, RHS), Builder.getFalse(), - true); - if (OR == OverflowResult::AlwaysOverflows) - return SetResult(Builder.CreateMul(LHS, RHS), Builder.getTrue(), true); - LLVM_FALLTHROUGH; - } - case OCF_SIGNED_MUL: + case OCF_UNSIGNED_MUL: + case OCF_SIGNED_MUL: { // X * undef -> undef if (isa<UndefValue>(RHS)) return SetResult(RHS, UndefValue::get(Builder.getInt1Ty()), false); @@ -4027,12 +4015,21 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, if (match(RHS, m_One())) return SetResult(LHS, Builder.getFalse(), false); - if (OCF == OCF_SIGNED_MUL) + if (OCF == OCF_UNSIGNED_MUL) { + OverflowResult OR = computeOverflowForUnsignedMul(LHS, RHS, &OrigI); + if (OR == OverflowResult::NeverOverflows) + return SetResult(Builder.CreateNUWMul(LHS, RHS), Builder.getFalse(), + true); + if (OR == OverflowResult::AlwaysOverflows) + return SetResult(Builder.CreateMul(LHS, RHS), Builder.getTrue(), true); + } else { if (willNotOverflowSignedMul(LHS, RHS, OrigI)) return SetResult(Builder.CreateNSWMul(LHS, RHS), Builder.getFalse(), true); + } break; } + } return false; } |