summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-27 07:25:21 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-27 07:25:21 +0000
commit40157d5c4db4a75ebc845022961a89661c728fea (patch)
treef67e7018150d510eeaa9c5644cc1bd7839b6db36 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
parent5d50b1a432f654bfcd11f0fc7fed4f4ea2b28c20 (diff)
downloadbcm5719-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.cpp28
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);
OpenPOWER on IntegriCloud