diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-01-13 23:04:10 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-01-13 23:04:10 +0000 |
| commit | 2d4b4564277b9a535a56b9a13414c224d55f279e (patch) | |
| tree | ee854261e90e52dbf35a70367b99abce4df94df7 | |
| parent | d511dde2ec4df7d3a5e7b06a49e5b7bd5269372d (diff) | |
| download | bcm5719-llvm-2d4b4564277b9a535a56b9a13414c224d55f279e.tar.gz bcm5719-llvm-2d4b4564277b9a535a56b9a13414c224d55f279e.zip | |
[InstCombine] use m_APInt to allow lshr folds for vectors with splat constants
llvm-svn: 291972
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 31 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/lshr.ll | 14 |
2 files changed, 21 insertions, 24 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 5209dad31b5..078c938ff9a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -774,34 +774,31 @@ Instruction *InstCombiner::visitLShr(BinaryOperator &I) { if (Instruction *R = commonShiftTransforms(I)) return R; - if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { - unsigned ShAmt = Op1C->getZExtValue(); - - if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op0)) { - unsigned BitWidth = Op0->getType()->getScalarSizeInBits(); + const APInt *ShAmtAPInt; + if (match(Op1, m_APInt(ShAmtAPInt))) { + unsigned ShAmt = ShAmtAPInt->getZExtValue(); + unsigned BitWidth = Op0->getType()->getScalarSizeInBits(); + auto *II = dyn_cast<IntrinsicInst>(Op0); + if (II && isPowerOf2_32(BitWidth) && Log2_32(BitWidth) == ShAmt && + (II->getIntrinsicID() == Intrinsic::ctlz || + II->getIntrinsicID() == Intrinsic::cttz || + II->getIntrinsicID() == Intrinsic::ctpop)) { // ctlz.i32(x)>>5 --> zext(x == 0) // cttz.i32(x)>>5 --> zext(x == 0) // ctpop.i32(x)>>5 --> zext(x == -1) - if ((II->getIntrinsicID() == Intrinsic::ctlz || - II->getIntrinsicID() == Intrinsic::cttz || - II->getIntrinsicID() == Intrinsic::ctpop) && - isPowerOf2_32(BitWidth) && Log2_32(BitWidth) == ShAmt) { - bool isCtPop = II->getIntrinsicID() == Intrinsic::ctpop; - Constant *RHS = ConstantInt::getSigned(Op0->getType(), isCtPop ? -1:0); - Value *Cmp = Builder->CreateICmpEQ(II->getArgOperand(0), RHS); - return new ZExtInst(Cmp, II->getType()); - } + bool IsPop = II->getIntrinsicID() == Intrinsic::ctpop; + Constant *RHS = ConstantInt::getSigned(Op0->getType(), IsPop ? -1 : 0); + Value *Cmp = Builder->CreateICmpEQ(II->getArgOperand(0), RHS); + return new ZExtInst(Cmp, II->getType()); } // If the shifted-out value is known-zero, then this is an exact shift. if (!I.isExact() && - MaskedValueIsZero(Op0, APInt::getLowBitsSet(Op1C->getBitWidth(), ShAmt), - 0, &I)){ + MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) { I.setIsExact(); return &I; } } - return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll index 13aa5e7dc09..b81371b0304 100644 --- a/llvm/test/Transforms/InstCombine/lshr.ll +++ b/llvm/test/Transforms/InstCombine/lshr.ll @@ -43,8 +43,8 @@ define i32 @lshr_ctpop(i32 %x) { define <2 x i8> @lshr_ctlz_zero_is_not_undef_splat_vec(<2 x i8> %x) { ; CHECK-LABEL: @lshr_ctlz_zero_is_not_undef_splat_vec( -; CHECK-NEXT: [[CT:%.*]] = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %x, i1 false) -; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> [[CT]], <i8 3, i8 3> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> %x, zeroinitializer +; CHECK-NEXT: [[SH:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> ; CHECK-NEXT: ret <2 x i8> [[SH]] ; %ct = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %x, i1 false) @@ -54,8 +54,8 @@ define <2 x i8> @lshr_ctlz_zero_is_not_undef_splat_vec(<2 x i8> %x) { define <2 x i8> @lshr_cttz_zero_is_not_undef_splat_vec(<2 x i8> %x) { ; CHECK-LABEL: @lshr_cttz_zero_is_not_undef_splat_vec( -; CHECK-NEXT: [[CT:%.*]] = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false) -; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> [[CT]], <i8 3, i8 3> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> %x, zeroinitializer +; CHECK-NEXT: [[SH:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> ; CHECK-NEXT: ret <2 x i8> [[SH]] ; %ct = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false) @@ -65,8 +65,8 @@ define <2 x i8> @lshr_cttz_zero_is_not_undef_splat_vec(<2 x i8> %x) { define <2 x i8> @lshr_ctpop_splat_vec(<2 x i8> %x) { ; CHECK-LABEL: @lshr_ctpop_splat_vec( -; CHECK-NEXT: [[CT:%.*]] = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x) -; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> [[CT]], <i8 3, i8 3> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> %x, <i8 -1, i8 -1> +; CHECK-NEXT: [[SH:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> ; CHECK-NEXT: ret <2 x i8> [[SH]] ; %ct = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x) @@ -91,7 +91,7 @@ define <2 x i8> @lshr_exact_splat_vec(<2 x i8> %x) { ; CHECK-LABEL: @lshr_exact_splat_vec( ; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i8> %x, <i8 2, i8 2> ; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[SHL]], <i8 4, i8 4> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i8> [[ADD]], <i8 2, i8 2> +; CHECK-NEXT: [[LSHR:%.*]] = lshr exact <2 x i8> [[ADD]], <i8 2, i8 2> ; CHECK-NEXT: ret <2 x i8> [[LSHR]] ; %shl = shl <2 x i8> %x, <i8 2, i8 2> |

