From 0b7b446a406be2e7d28460d17de4746b47543691 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 16 Oct 2020 16:06:14 +0100 Subject: [PATCH] [InstCombine] Support vectors-with-undef in and(logicalshift(1,X),1) --> zext(X == 0) fold --- .../Transforms/InstCombine/InstCombineAndOrXor.cpp | 19 ++++++++++--------- llvm/test/Transforms/InstCombine/and2.ll | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index b9b73a4..11cfa4a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1764,17 +1764,18 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) { return replaceInstUsesWith(I, V); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + Value *X, *Y; + if (match(Op0, m_OneUse(m_LogicalShift(m_One(), m_Value(X)))) && + match(Op1, m_One())) { + // (1 << X) & 1 --> zext(X == 0) + // (1 >> X) & 1 --> zext(X == 0) + Value *IsZero = Builder.CreateICmpEQ(X, ConstantInt::get(Ty, 0)); + return new ZExtInst(IsZero, Ty); + } + const APInt *C; if (match(Op1, m_APInt(C))) { - Value *X, *Y; - if (match(Op0, m_OneUse(m_LogicalShift(m_One(), m_Value(X)))) && - C->isOneValue()) { - // (1 << X) & 1 --> zext(X == 0) - // (1 >> X) & 1 --> zext(X == 0) - Value *IsZero = Builder.CreateICmpEQ(X, ConstantInt::get(Ty, 0)); - return new ZExtInst(IsZero, Ty); - } - const APInt *XorC; if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_APInt(XorC))))) { // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) diff --git a/llvm/test/Transforms/InstCombine/and2.ll b/llvm/test/Transforms/InstCombine/and2.ll index 6cf71ee..47b0d2d 100644 --- a/llvm/test/Transforms/InstCombine/and2.ll +++ b/llvm/test/Transforms/InstCombine/and2.ll @@ -137,8 +137,8 @@ define <2 x i8> @and1_shl1_is_cmp_eq_0_vec(<2 x i8> %x) { define <2 x i8> @and1_shl1_is_cmp_eq_0_vec_undef(<2 x i8> %x) { ; CHECK-LABEL: @and1_shl1_is_cmp_eq_0_vec_undef( -; CHECK-NEXT: [[SH:%.*]] = shl <2 x i8> , [[X:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[SH]], +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer +; CHECK-NEXT: [[AND:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> ; CHECK-NEXT: ret <2 x i8> [[AND]] ; %sh = shl <2 x i8> , %x @@ -189,8 +189,8 @@ define <2 x i8> @and1_lshr1_is_cmp_eq_0_vec(<2 x i8> %x) { define <2 x i8> @and1_lshr1_is_cmp_eq_0_vec_undef(<2 x i8> %x) { ; CHECK-LABEL: @and1_lshr1_is_cmp_eq_0_vec_undef( -; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> , [[X:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[SH]], +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer +; CHECK-NEXT: [[AND:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> ; CHECK-NEXT: ret <2 x i8> [[AND]] ; %sh = lshr <2 x i8> , %x -- 2.7.4