From 1195d29a3938cad46fb1ab9b1f96bd229b709a07 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 23 Jul 2016 13:06:49 +0000 Subject: [PATCH] [InstCombine] allow icmp (bit-manipulation-intrinsic(), C) folds for vectors llvm-svn: 276523 --- .../InstCombine/InstCombineCompares.cpp | 29 ++++++++++--------- .../InstCombine/InstCombineInternal.h | 3 +- test/Transforms/InstCombine/intrinsics.ll | 11 ++----- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index f5514a8992e..40042002936 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2355,37 +2355,35 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI, return nullptr; } -Instruction *InstCombiner::foldICmpIntrinsicWithConstant(ICmpInst &ICI, - Instruction *LHSI, - ConstantInt *RHS) { - IntrinsicInst *II = dyn_cast(LHSI); - if (!II || !ICI.isEquality()) +Instruction *InstCombiner::foldICmpIntrinsicWithConstant(ICmpInst &ICI) { + IntrinsicInst *II = dyn_cast(ICI.getOperand(0)); + const APInt *Op1C; + if (!II || !ICI.isEquality() || !match(ICI.getOperand(1), m_APInt(Op1C))) return nullptr; // Handle icmp {eq|ne} , intcst. - const APInt &RHSV = RHS->getValue(); switch (II->getIntrinsicID()) { case Intrinsic::bswap: Worklist.Add(II); ICI.setOperand(0, II->getArgOperand(0)); - ICI.setOperand(1, Builder->getInt(RHSV.byteSwap())); + ICI.setOperand(1, Builder->getInt(Op1C->byteSwap())); return &ICI; case Intrinsic::ctlz: case Intrinsic::cttz: // ctz(A) == bitwidth(a) -> A == 0 and likewise for != - if (RHSV == RHS->getType()->getBitWidth()) { + if (*Op1C == Op1C->getBitWidth()) { Worklist.Add(II); ICI.setOperand(0, II->getArgOperand(0)); - ICI.setOperand(1, ConstantInt::get(RHS->getType(), 0)); + ICI.setOperand(1, ConstantInt::getNullValue(II->getType())); return &ICI; } break; case Intrinsic::ctpop: // popcount(A) == 0 -> A == 0 and likewise for != - if (RHS->isZero()) { + if (*Op1C == 0) { Worklist.Add(II); ICI.setOperand(0, II->getArgOperand(0)); - ICI.setOperand(1, RHS); + ICI.setOperand(1, ConstantInt::getNullValue(II->getType())); return &ICI; } break; @@ -3641,6 +3639,10 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { // See if we are doing a comparison between a constant and an instruction that // can be folded into the comparison. + + // FIXME: Use m_APInt instead of dyn_cast to allow these + // transforms for vectors. + if (ConstantInt *CI = dyn_cast(Op1)) { // Since the RHS is a ConstantInt (CI), if the left hand side is an // instruction, see if that instruction also has constants so that the @@ -3650,11 +3652,12 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { return Res; if (Instruction *Res = foldICmpEqualityWithConstant(I, LHSI, CI)) return Res; - if (Instruction *Res = foldICmpIntrinsicWithConstant(I, LHSI, CI)) - return Res; } } + if (Instruction *Res = foldICmpIntrinsicWithConstant(I)) + return Res; + // Handle icmp with constant (but not simple integer constant) RHS if (Constant *RHSC = dyn_cast(Op1)) { if (Instruction *LHSI = dyn_cast(Op0)) diff --git a/lib/Transforms/InstCombine/InstCombineInternal.h b/lib/Transforms/InstCombine/InstCombineInternal.h index 61dbd31448b..894e9a06468 100644 --- a/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/lib/Transforms/InstCombine/InstCombineInternal.h @@ -585,8 +585,7 @@ private: ConstantInt *RHS); Instruction *foldICmpEqualityWithConstant(ICmpInst &ICI, Instruction *LHS, ConstantInt *RHS); - Instruction *foldICmpIntrinsicWithConstant(ICmpInst &ICI, Instruction *LHS, - ConstantInt *RHS); + Instruction *foldICmpIntrinsicWithConstant(ICmpInst &ICI); Instruction *OptAndOp(Instruction *Op, ConstantInt *OpRHS, ConstantInt *AndRHS, BinaryOperator &TheAnd); diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 1d49a0c1241..f3845832c66 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -316,12 +316,9 @@ entry: ; CHECK-NEXT: store volatile i1 %pop.cmp, i1* %c } -; FIXME: Vectors should get the same folds as scalars. - define <2 x i1> @ctlz_cmp_vec(<2 x i32> %a) { ; CHECK-LABEL: @ctlz_cmp_vec( -; CHECK-NEXT: [[X:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false) #0 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X]], +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> %a, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %x = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false) nounwind readnone @@ -331,8 +328,7 @@ define <2 x i1> @ctlz_cmp_vec(<2 x i32> %a) { define <2 x i1> @cttz_cmp_vec(<2 x i32> %a) { ; CHECK-LABEL: @cttz_cmp_vec( -; CHECK-NEXT: [[X:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false) #0 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X]], +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> %a, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %x = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false) nounwind readnone @@ -342,8 +338,7 @@ define <2 x i1> @cttz_cmp_vec(<2 x i32> %a) { define <2 x i1> @ctpop_cmp_vec(<2 x i32> %a) { ; CHECK-LABEL: @ctpop_cmp_vec( -; CHECK-NEXT: [[X:%.*]] = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) #0 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> %a, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %x = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) nounwind readnone