diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-11-27 07:25:21 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-11-27 07:25:21 +0000 |
commit | 40157d5c4db4a75ebc845022961a89661c728fea (patch) | |
tree | f67e7018150d510eeaa9c5644cc1bd7839b6db36 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | |
parent | 5d50b1a432f654bfcd11f0fc7fed4f4ea2b28c20 (diff) | |
download | bcm5719-llvm-40157d5c4db4a75ebc845022961a89661c728fea.tar.gz bcm5719-llvm-40157d5c4db4a75ebc845022961a89661c728fea.zip |
InstCombine: Restore optimizations lost in r210006
This restores our ability to optimize:
(X & C) == 0 ? X ^ C : X into X | C
(X & C) != 0 ? X ^ C : X into X & ~C
llvm-svn: 222871
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 8e2a7d5ce65..83a2f2c563f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -617,6 +617,34 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI, } } + { + Value *X; + const APInt *Y, *C; + if (match(CmpLHS, m_And(m_Value(X), m_Power2(Y))) && + match(CmpRHS, m_Zero())) { + Value *V = nullptr; + // (X & Y) == 0 ? X : X ^ Y --> X & ~Y + if (Pred == ICmpInst::ICMP_EQ && TrueVal == X && + match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C) + V = Builder->CreateAnd(X, ~(*Y)); + // (X & Y) != 0 ? X ^ Y : X --> X & ~Y + else if (Pred == ICmpInst::ICMP_NE && FalseVal == X && + match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C) + V = Builder->CreateAnd(X, ~(*Y)); + // (X & Y) == 0 ? X ^ Y : X --> X | Y + else if (Pred == ICmpInst::ICMP_EQ && FalseVal == X && + match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C) + V = Builder->CreateOr(X, *Y); + // (X & Y) != 0 ? X : X ^ Y --> X | Y + else if (Pred == ICmpInst::ICMP_NE && TrueVal == X && + match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C) + V = Builder->CreateOr(X, *Y); + + if (V) + return ReplaceInstUsesWith(SI, V); + } + } + if (Value *V = foldSelectICmpAndOr(SI, TrueVal, FalseVal, Builder)) return ReplaceInstUsesWith(SI, V); |