#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
using namespace llvm;
if (matchICmpOperand(Offset, RHS, Val, SwappedPred))
return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset);
+ // If (Val & Mask) == C then all the masked bits are known and we can compute
+ // a value range based on that.
+ const APInt *Mask, *C;
+ if (EdgePred == ICmpInst::ICMP_EQ &&
+ match(LHS, m_And(m_Specific(Val), m_APInt(Mask))) &&
+ match(RHS, m_APInt(C))) {
+ KnownBits Known;
+ Known.Zero = ~*C & *Mask;
+ Known.One = *C & *Mask;
+ return ValueLatticeElement::getRange(
+ ConstantRange::fromKnownBits(Known, /*IsSigned*/ false));
+ }
+
return ValueLatticeElement::getOverdefined();
}
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 10
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], 11
-; CHECK-NEXT: call void @check1(i1 [[CMP3]])
-; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 10
-; CHECK-NEXT: call void @check1(i1 [[CMP4]])
-; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[A]], 11
-; CHECK-NEXT: call void @check1(i1 [[CMP5]])
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 false)
+; CHECK-NEXT: call void @check1(i1 false)
; CHECK-NEXT: ret void
; CHECK: if.false:
; CHECK-NEXT: ret void
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 32
; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 32
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
+; CHECK-NEXT: call void @check1(i1 true)
; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[A]], 33
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
; CHECK-NEXT: ret void
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[A]], -33
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
+; CHECK-NEXT: call void @check1(i1 true)
; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], -34
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
; CHECK-NEXT: ret void