From d60b8ac64fa161646d50c49d6171cb49e6a2c7ee Mon Sep 17 00:00:00 2001 From: Jakub Staszak Date: Mon, 31 Dec 2012 00:34:55 +0000 Subject: Transform (A == C1 || A == C2) into (A & ~(C1 ^ C2)) == C1 if C1 and C2 differ only with one bit. Fixes PR14708. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171270 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/Transforms/InstCombine/InstCombineAndOrXor.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index ecae3b6045..0fd1e2b2e4 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1524,6 +1524,18 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) { AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst); return Builder->CreateICmpULT(Add, AddCST); } + + if (LHS->getOperand(0) == RHS->getOperand(0)) { + // if LHSCst and RHSCst differ with only one bit: + // (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1 + APInt Xor = LHSCst->getValue() ^ RHSCst->getValue(); + if (Xor.isPowerOf2()) { + Value *NegCst = Builder->getInt(~Xor); + Value *And = Builder->CreateAnd(LHS->getOperand(0), NegCst); + return Builder->CreateICmp(ICmpInst::ICMP_EQ, And, LHSCst); + } + } + break; // (X == 13 | X == 15) -> no change case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change -- cgit v1.2.3