From b22d64b7ed33e20b1897cd56f3b836baad63b72a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 13 Oct 2017 16:29:38 +0000 Subject: [PATCH] [InstCombine] allow zext(bool) + C --> select bool, C+1, C for vector types The backend should be prepared for this transform after: https://reviews.llvm.org/rL311731 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315701 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineAddSub.cpp | 25 +++++++++++-------- .../InstCombine/zext-bool-add-sub.ll | 6 ++--- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index bcd60bca177..e12bff01376 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -953,6 +953,19 @@ static Value *checkForNegativeOperand(BinaryOperator &I, static Instruction *foldAddWithConstant(BinaryOperator &Add, InstCombiner::BuilderTy &Builder) { Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1); + Constant *Op1C; + if (!match(Op1, m_Constant(Op1C))) + return nullptr; + + Value *X; + Type *Ty = Add.getType(); + if (match(Op0, m_ZExt(m_Value(X))) && + X->getType()->getScalarSizeInBits() == 1) { + // zext(bool) + C -> bool ? C + 1 : C + Constant *One = ConstantInt::get(Ty, 1); + return SelectInst::Create(X, ConstantExpr::getAdd(Op1C, One), Op1); + } + const APInt *C; if (!match(Op1, m_APInt(C))) return nullptr; @@ -968,12 +981,9 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add, return BinaryOperator::CreateXor(Op0, Op1); } - Value *X; - const APInt *C2; - Type *Ty = Add.getType(); - // Is this add the last step in a convoluted sext? // add(zext(xor i16 X, -32768), -32768) --> sext X + const APInt *C2; if (match(Op0, m_ZExt(m_Xor(m_Value(X), m_APInt(C2)))) && C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C) return CastInst::Create(Instruction::SExt, X, Ty); @@ -1031,13 +1041,8 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { return X; // FIXME: This should be moved into the above helper function to allow these - // transforms for splat vectors. + // transforms for general constant or constant splat vectors. if (ConstantInt *CI = dyn_cast(RHS)) { - // zext(bool) + C -> bool ? C + 1 : C - if (ZExtInst *ZI = dyn_cast(LHS)) - if (ZI->getSrcTy()->isIntegerTy(1)) - return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI); - Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr; if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); diff --git a/test/Transforms/InstCombine/zext-bool-add-sub.ll b/test/Transforms/InstCombine/zext-bool-add-sub.ll index f73c7c31c29..4ee8ee2acd1 100644 --- a/test/Transforms/InstCombine/zext-bool-add-sub.ll +++ b/test/Transforms/InstCombine/zext-bool-add-sub.ll @@ -73,8 +73,7 @@ define i32 @zext_add_scalar(i1 %x) { define <2 x i32> @zext_add_vec_splat(<2 x i1> %x) { ; CHECK-LABEL: @zext_add_vec_splat( -; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i1> %x to <2 x i32> -; CHECK-NEXT: [[ADD:%.*]] = or <2 x i32> [[ZEXT]], +; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> %x, <2 x i32> , <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[ADD]] ; %zext = zext <2 x i1> %x to <2 x i32> @@ -84,8 +83,7 @@ define <2 x i32> @zext_add_vec_splat(<2 x i1> %x) { define <2 x i32> @zext_add_vec(<2 x i1> %x) { ; CHECK-LABEL: @zext_add_vec( -; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i1> %x to <2 x i32> -; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw <2 x i32> [[ZEXT]], +; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> %x, <2 x i32> , <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[ADD]] ; %zext = zext <2 x i1> %x to <2 x i32> -- 2.40.0