if (match(V, m_BitwiseLogic(m_Value(A), m_Value(B)))) {
AddAffected(A);
AddAffected(B);
- // (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
+ // (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
} else if (match(V, m_Shift(m_Value(A), m_ConstantInt()))) {
AddAffected(A);
}
AddAffectedFromEq(A);
AddAffectedFromEq(B);
+ } else if (Pred == ICmpInst::ICMP_NE) {
+ Value *X, *Y;
+ // Handle (a & b != 0). If a/b is a power of 2 we can use this
+ // information.
+ if (match(A, m_And(m_Value(X), m_Value(Y))) && match(B, m_Zero())) {
+ AddAffected(X);
+ AddAffected(Y);
+ }
+ } else if (Pred == ICmpInst::ICMP_ULT) {
+ Value *X;
+ // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
+ // and recognized by LVI at least.
+ if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
+ match(B, m_ConstantInt()))
+ AddAffected(X);
}
-
- Value *X;
- // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
- // and recognized by LVI at least.
- if (Pred == ICmpInst::ICMP_ULT &&
- match(A, m_Add(m_Value(X), m_ConstantInt())) &&
- match(B, m_ConstantInt()))
- AddAffected(X);
}
if (TTI) {
Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros());
}
break;
+ case ICmpInst::ICMP_NE: {
+ // assume (v & b != 0) where b is a power of 2
+ const APInt *BPow2;
+ if (match(Cmp, m_ICmp(Pred, m_c_And(m_V, m_Power2(BPow2)), m_Zero())) &&
+ isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
+ Known.One |= BPow2->zextOrTrunc(BitWidth);
+ }
+ } break;
}
}
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 4
-; CHECK-NEXT: ret i32 [[AND2]]
+; CHECK-NEXT: ret i32 4
;
%and = and i32 %x, 4
%cmp = icmp ne i32 %and, 0
; CHECK-NEXT: [[AND:%.*]] = and i64 [[X:%.*]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[AND]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: [[OR:%.*]] = or i64 [[X]], 1
-; CHECK-NEXT: ret i64 [[OR]]
+; CHECK-NEXT: ret i64 [[X]]
;
%and = and i64 %x, 1
%cmp = icmp ne i64 %and, 0
; CHECK-NEXT: [[AND:%.*]] = and i16 [[X:%.*]], 16384
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[AND]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: [[AND2:%.*]] = and i16 [[X]], 16384
-; CHECK-NEXT: ret i16 [[AND2]]
+; CHECK-NEXT: ret i16 16384
;
%and = and i16 %x, 16384
%cmp = icmp eq i16 %and, 16384