From b844f35bcd7f92fc51dba9dddd202b4ed493b536 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 17 Apr 2017 03:41:47 +0000 Subject: [PATCH] [InstCombine] Simplify 1/X for vectors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300439 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineMulDivRem.cpp | 31 +++++++++++----------- test/Transforms/InstCombine/div.ll | 7 +++-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 953e7f36467..2d93e80fc13 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -944,22 +944,21 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) { } } - if (ConstantInt *One = dyn_cast(Op0)) { - if (One->isOne() && !I.getType()->isIntegerTy(1)) { - bool isSigned = I.getOpcode() == Instruction::SDiv; - if (isSigned) { - // If Op1 is 0 then it's undefined behaviour, if Op1 is 1 then the - // result is one, if Op1 is -1 then the result is minus one, otherwise - // it's zero. - Value *Inc = Builder->CreateAdd(Op1, One); - Value *Cmp = Builder->CreateICmpULT( - Inc, ConstantInt::get(I.getType(), 3)); - return SelectInst::Create(Cmp, Op1, ConstantInt::get(I.getType(), 0)); - } else { - // If Op1 is 0 then it's undefined behaviour. If Op1 is 1 then the - // result is one, otherwise it's zero. - return new ZExtInst(Builder->CreateICmpEQ(Op1, One), I.getType()); - } + if (match(Op0, m_One())) { + assert(!I.getType()->getScalarType()->isIntegerTy(1) && + "i1 divide not removed?"); + if (I.getOpcode() == Instruction::SDiv) { + // If Op1 is 0 then it's undefined behaviour, if Op1 is 1 then the + // result is one, if Op1 is -1 then the result is minus one, otherwise + // it's zero. + Value *Inc = Builder->CreateAdd(Op1, Op0); + Value *Cmp = Builder->CreateICmpULT( + Inc, ConstantInt::get(I.getType(), 3)); + return SelectInst::Create(Cmp, Op1, ConstantInt::get(I.getType(), 0)); + } else { + // If Op1 is 0 then it's undefined behaviour. If Op1 is 1 then the + // result is one, otherwise it's zero. + return new ZExtInst(Builder->CreateICmpEQ(Op1, Op0), I.getType()); } } diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll index ab72f2cc5f5..796fce020fd 100644 --- a/test/Transforms/InstCombine/div.ll +++ b/test/Transforms/InstCombine/div.ll @@ -227,7 +227,8 @@ define i32 @test19(i32 %x) { define <2 x i32> @test19vec(<2 x i32> %x) { ; CHECK-LABEL: @test19vec( -; CHECK-NEXT: [[A:%.*]] = udiv <2 x i32> , [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[A]] ; %A = udiv <2 x i32> , %x @@ -247,7 +248,9 @@ define i32 @test20(i32 %x) { define <2 x i32> @test20vec(<2 x i32> %x) { ; CHECK-LABEL: @test20vec( -; CHECK-NEXT: [[A:%.*]] = sdiv <2 x i32> , [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], +; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X]], <2 x i32> zeroinitializer ; CHECK-NEXT: ret <2 x i32> [[A]] ; %A = sdiv <2 x i32> , %x -- 2.11.0