From 41af60bdc0e3aa5695a9fc0a287442b175cb0b74 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 21 May 2015 23:04:21 +0000 Subject: [PATCH] [InstCombine] X - 0 is equal to X, not undef A refactoring made @llvm.ssub.with.overflow.i32(i32 %X, i32 0) transform into undef instead of %X. This fixes PR23624. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237968 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCompares.cpp | 46 ++++++++----------- test/Transforms/InstCombine/intrinsics.ll | 8 ++++ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index e979d76c1d0..09ab16511e7 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2141,13 +2141,11 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, case OCF_SIGNED_ADD: { // X + undef -> undef if (isa(RHS)) - return SetResult(UndefValue::get(RHS->getType()), - UndefValue::get(Builder->getInt1Ty()), false); + return SetResult(RHS, UndefValue::get(Builder->getInt1Ty()), false); - if (ConstantInt *ConstRHS = dyn_cast(RHS)) - // X + 0 -> {X, false} - if (ConstRHS->isZero()) - return SetResult(LHS, Builder->getFalse(), false); + // 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. @@ -2160,16 +2158,16 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, case OCF_UNSIGNED_SUB: case OCF_SIGNED_SUB: { // undef - X -> undef - // X - undef -> undef - if (isa(LHS) || isa(RHS)) - return SetResult(UndefValue::get(LHS->getType()), - UndefValue::get(Builder->getInt1Ty()), false); + if (isa(LHS)) + return SetResult(LHS, UndefValue::get(Builder->getInt1Ty()), false); - if (ConstantInt *ConstRHS = dyn_cast(RHS)) - // X - 0 -> {X, false} - if (ConstRHS->isZero()) - return SetResult(UndefValue::get(LHS->getType()), Builder->getFalse(), - false); + // X - undef -> undef + if (isa(RHS)) + return SetResult(RHS, UndefValue::get(Builder->getInt1Ty()), false); + + // X - 0 -> {X, false} + if (match(RHS, m_Zero())) + return SetResult(LHS, Builder->getFalse(), false); if (OCF == OCF_SIGNED_SUB) { if (WillNotOverflowSignedSub(LHS, RHS, OrigI)) @@ -2194,19 +2192,15 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, case OCF_SIGNED_MUL: // X * undef -> undef if (isa(RHS)) - return SetResult(UndefValue::get(LHS->getType()), - UndefValue::get(Builder->getInt1Ty()), false); + return SetResult(RHS, UndefValue::get(Builder->getInt1Ty()), false); - if (ConstantInt *RHSI = dyn_cast(RHS)) { - // X * 0 -> {0, false} - if (RHSI->isZero()) - return SetResult(Constant::getNullValue(RHS->getType()), - Builder->getFalse(), false); + // X * 0 -> {0, false} + if (match(RHS, m_Zero())) + return SetResult(RHS, Builder->getFalse(), false); - // X * 1 -> {X, false} - if (RHSI->equalsInt(1)) - return SetResult(LHS, Builder->getFalse(), false); - } + // X * 1 -> {X, false} + if (match(RHS, m_One())) + return SetResult(LHS, Builder->getFalse(), false); if (OCF == OCF_SIGNED_MUL) if (WillNotOverflowSignedMul(LHS, RHS, OrigI)) diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index f9ccf51a621..974ee4395b8 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -417,3 +417,11 @@ define %ov.result.32 @ssubtest_reorder(i8 %a) { ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0 ; CHECK-NEXT: ret %ov.result.32 %1 } + +define %ov.result.32 @never_overflows_ssub(i32 %a) { + %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %a, i32 0) + ret %ov.result.32 %x +; CHECK-LABEL: @never_overflows_ssub +; CHECK-NEXT: %[[x:.*]] = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %a, 0 +; CHECK-NEXT: ret %ov.result.32 %[[x]] +}