llvm.org GIT mirror llvm / 7ddcd35
Use the new range metadata in computeMaskedBits and add a new optimization to instruction simplify that lets us remove an and when loding a boolean value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153423 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
3 changed file(s) with 56 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
13681368 if (isPowerOfTwo(Op1, Q.TD, /*OrZero*/true))
13691369 return Op1;
13701370 }
1371
1372 unsigned Bitwidth = Op1->getType()->getScalarSizeInBits();
1373 APInt DemandedMask = APInt::getAllOnesValue(Bitwidth);
1374 APInt KnownZero0 = APInt::getNullValue(Bitwidth);
1375 APInt KnownOne0 = APInt::getNullValue(Bitwidth);
1376 ComputeMaskedBits(Op0, DemandedMask, KnownZero0, KnownOne0);
1377 APInt KnownZero1 = APInt::getNullValue(Bitwidth);
1378 APInt KnownOne1 = APInt::getNullValue(Bitwidth);
1379 ComputeMaskedBits(Op1, DemandedMask, KnownZero1, KnownOne1);
1380
1381 if ((KnownZero0 | KnownOne1).isAllOnesValue())
1382 return Op0;
1383
1384 if ((KnownZero1 | KnownOne0).isAllOnesValue())
1385 return Op1;
13711386
13721387 // Try some generic simplifications for associative operations.
13731388 if (Value *V = SimplifyAssociativeBinOp(Instruction::And, Op0, Op1, Q,
1919 #include "llvm/GlobalAlias.h"
2020 #include "llvm/IntrinsicInst.h"
2121 #include "llvm/LLVMContext.h"
22 #include "llvm/Metadata.h"
2223 #include "llvm/Operator.h"
2324 #include "llvm/Target/TargetData.h"
25 #include "llvm/Support/ConstantRange.h"
2426 #include "llvm/Support/GetElementPtrTypeIterator.h"
2527 #include "llvm/Support/MathExtras.h"
2628 #include "llvm/Support/PatternMatch.h"
194196 KnownOne.setBit(BitWidth - 1);
195197 }
196198
199 static void computeMaskedBitsLoad(const MDNode &Ranges, const APInt &Mask,
200 APInt &KnownZero) {
201 unsigned BitWidth = Mask.getBitWidth();
202 unsigned NumRanges = Ranges.getNumOperands() / 2;
203 assert(NumRanges >= 1);
204
205 // Use the high end of the ranges to find leading zeros.
206 unsigned MinLeadingZeros = BitWidth;
207 for (unsigned i = 0; i < NumRanges; ++i) {
208 ConstantInt *Lower = cast(Ranges.getOperand(2*i + 0));
209 ConstantInt *Upper = cast(Ranges.getOperand(2*i + 1));
210 ConstantRange Range(Lower->getValue(), Upper->getValue());
211 if (Range.isWrappedSet())
212 MinLeadingZeros = 0; // -1 has no zeros
213 unsigned LeadingZeros = (Upper->getValue() - 1).countLeadingZeros();
214 MinLeadingZeros = std::min(LeadingZeros, MinLeadingZeros);
215 }
216
217 KnownZero = Mask & APInt::getHighBitsSet(BitWidth, MinLeadingZeros);
218 }
197219 /// ComputeMaskedBits - Determine which of the bits specified in Mask are
198220 /// known to be either zero or one and return them in the KnownZero/KnownOne
199221 /// bit sets. This code only analyzes bits in Mask, in order to short-circuit
314336 APInt KnownZero2(KnownZero), KnownOne2(KnownOne);
315337 switch (I->getOpcode()) {
316338 default: break;
339 case Instruction::Load:
340 if (MDNode *MD = cast(I)->getMetadata(LLVMContext::MD_range))
341 computeMaskedBitsLoad(*MD, Mask, KnownZero);
342 return;
317343 case Instruction::And: {
318344 // If either the LHS or the RHS are Zero, the result is zero.
319345 ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, TD, Depth+1);
0 ; RUN: opt < %s -instsimplify -S | FileCheck %s
1
2 define zeroext i1 @_Z3fooPb(i8* nocapture %x) {
3 entry:
4 %a = load i8* %x, align 1, !range !0
5 %b = and i8 %a, 1
6 %tobool = icmp ne i8 %b, 0
7 ret i1 %tobool
8 }
9
10 ; CHECK: %a = load i8* %x, align 1, !range !0
11 ; CHECK-NEXT: %tobool = icmp ne i8 %a, 0
12 ; CHECK-NEXT: ret i1 %tobool
13
14 !0 = metadata !{i8 0, i8 2}