diff options
author | Daniel Neilson <dneilson@azul.com> | 2018-04-03 17:26:20 +0000 |
---|---|---|
committer | Daniel Neilson <dneilson@azul.com> | 2018-04-03 17:26:20 +0000 |
commit | 901acfab0ccaf7f11326e57221ce9b0aed471ec7 (patch) | |
tree | 15719d613ae064b596b2881c8428af63938653f8 /llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | |
parent | 1ef746ba21c9b999f25bcb6dfecea59da90f29a9 (diff) | |
download | bcm5719-llvm-901acfab0ccaf7f11326e57221ce9b0aed471ec7.tar.gz bcm5719-llvm-901acfab0ccaf7f11326e57221ce9b0aed471ec7.zip |
[InstCombine] Fold compare of int constant against a splatted vector of ints
Summary:
Folding patterns like:
%vec = shufflevector <4 x i8> %insvec, <4 x i8> undef, <4 x i32> zeroinitializer
%cast = bitcast <4 x i8> %vec to i32
%cond = icmp eq i32 %cast, 0
into:
%ext = extractelement <4 x i8> %insvec, i32 0
%cond = icmp eq i32 %ext, 0
Combined with existing rules, this allows us to fold patterns like:
%insvec = insertelement <4 x i8> undef, i8 %val, i32 0
%vec = shufflevector <4 x i8> %insvec, <4 x i8> undef, <4 x i32> zeroinitializer
%cast = bitcast <4 x i8> %vec to i32
%cond = icmp eq i32 %cast, 0
into:
%cond = icmp eq i8 %val, 0
When we construct a splat vector via a shuffle, and bitcast the vector into an integer type for comparison against an integer constant. Then we can simplify the the comparison to compare the splatted value against the integer constant.
Reviewers: spatel, anna, mkazantsev
Reviewed By: spatel
Subscribers: efriedma, rengolin, llvm-commits
Differential Revision: https://reviews.llvm.org/D44997
llvm-svn: 329087
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index cea3a1d705b..246a335199c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2457,6 +2457,45 @@ Instruction *InstCombiner::foldICmpSelectConstant(ICmpInst &Cmp, return nullptr; } +Instruction *InstCombiner::foldICmpBitCastConstant(ICmpInst &Cmp, + BitCastInst *Bitcast, + const APInt &C) { + // Folding: icmp <pred> iN X, C + // where X = bitcast <M x iK> (shufflevector <M x iK> %vec, undef, SC)) to iN + // and C is a splat of a K-bit pattern + // and SC is a constant vector = <C', C', C', ..., C'> + // Into: + // %E = extractelement <M x iK> %vec, i32 C' + // icmp <pred> iK %E, trunc(C) + if (!Bitcast->getType()->isIntegerTy() || + !Bitcast->getSrcTy()->isIntOrIntVectorTy()) + return nullptr; + + Value *BCIOp = Bitcast->getOperand(0); + Value *Vec = nullptr; // 1st vector arg of the shufflevector + Constant *Mask = nullptr; // Mask arg of the shufflevector + if (match(BCIOp, + m_ShuffleVector(m_Value(Vec), m_Undef(), m_Constant(Mask)))) { + // Check whether every element of Mask is the same constant + if (auto *Elem = dyn_cast_or_null<ConstantInt>(Mask->getSplatValue())) { + auto *VecTy = cast<VectorType>(BCIOp->getType()); + auto *EltTy = cast<IntegerType>(VecTy->getElementType()); + auto Pred = Cmp.getPredicate(); + if (C.isSplat(EltTy->getBitWidth())) { + // Fold the icmp based on the value of C + // If C is M copies of an iK sized bit pattern, + // then: + // => %E = extractelement <N x iK> %vec, i32 Elem + // icmp <pred> iK %SplatVal, <pattern> + Value *Extract = Builder.CreateExtractElement(Vec, Elem); + Value *NewC = ConstantInt::get(EltTy, C.trunc(EltTy->getBitWidth())); + return new ICmpInst(Pred, Extract, NewC); + } + } + } + return nullptr; +} + /// Try to fold integer comparisons with a constant operand: icmp Pred X, C /// where X is some kind of instruction. Instruction *InstCombiner::foldICmpInstWithConstant(ICmpInst &Cmp) { @@ -2531,6 +2570,11 @@ Instruction *InstCombiner::foldICmpInstWithConstant(ICmpInst &Cmp) { return I; } + if (auto *BCI = dyn_cast<BitCastInst>(Cmp.getOperand(0))) { + if (Instruction *I = foldICmpBitCastConstant(Cmp, BCI, *C)) + return I; + } + if (Instruction *I = foldICmpIntrinsicWithConstant(Cmp, *C)) return I; |