[ValueTracking] Extend r251146 to catch a fairly common case

Even though we may not know the value of the shifter operand, it's possible we know the shifter operand is non-zero. This can allow us to infer more known bits - for example:

  %1 = load %p !range {1, 5}
  %2 = shl %q, %1

We don't know %1, but we do know that it is nonzero so %2[0] is known zero, and importantly %2 is known non-zero.

Calling isKnownNonZero is nontrivially expensive so use an Optional to run it lazily and cache its result.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251294 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
James Molloy 2015-10-26 14:10:46 +00:00
parent bd8522817d
commit bf7b3fed5c
2 changed files with 35 additions and 2 deletions

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/InstructionSimplify.h"
@ -1004,9 +1005,18 @@ static void computeKnownBitsFromShiftOperator(Operator *I,
// calculation. Reusing the APInts here to prevent unnecessary allocations.
KnownZero.clearAllBits(), KnownOne.clearAllBits();
// If we know the shifter operand is nonzero, we can sometimes infer more
// known bits. However this is expensive to compute, so be lazy about it and
// only compute it when absolutely necessary.
Optional<bool> ShifterOperandIsNonZero;
// Early exit if we can't constrain any well-defined shift amount.
if (!(ShiftAmtKZ & (BitWidth-1)) && !(ShiftAmtKO & (BitWidth-1)))
return;
if (!(ShiftAmtKZ & (BitWidth - 1)) && !(ShiftAmtKO & (BitWidth - 1))) {
ShifterOperandIsNonZero =
isKnownNonZero(I->getOperand(1), DL, Depth + 1, Q);
if (!*ShifterOperandIsNonZero)
return;
}
computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, DL, Depth + 1, Q);
@ -1018,6 +1028,16 @@ static void computeKnownBitsFromShiftOperator(Operator *I,
continue;
if ((ShiftAmt | ShiftAmtKO) != ShiftAmt)
continue;
// If we know the shifter is nonzero, we may be able to infer more known
// bits. This check is sunk down as far as possible to avoid the expensive
// call to isKnownNonZero if the cheaper checks above fail.
if (ShiftAmt == 0) {
if (!ShifterOperandIsNonZero.hasValue())
ShifterOperandIsNonZero =
isKnownNonZero(I->getOperand(1), DL, Depth + 1, Q);
if (*ShifterOperandIsNonZero)
continue;
}
KnownZero &= KZF(KnownZero2, ShiftAmt);
KnownOne &= KOF(KnownOne2, ShiftAmt);

View File

@ -0,0 +1,13 @@
; RUN: opt -instsimplify -S < %s | FileCheck %s
; CHECK-LABEL: @test
define i1 @test(i8 %p, i8* %pq) {
%q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
%1 = shl i8 %p, %q ; because %q is nonzero, %1[0] is known to be zero.
%2 = and i8 %1, 1
%x = icmp eq i8 %2, 0
; CHECK: ret i1 true
ret i1 %x
}
!0 = !{ i8 1, i8 5 }