mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[InstSimplify] fold icmp with mul nsw and constant operands
https://rise4fun.com/Alive/slvl Name: mul nsw with icmp eq Pre: (C2 % C1) != 0 %a = mul nsw i8 %x, C1 %r = icmp eq i8 %a, C2 => %r = false Name: mul nsw with icmp ne Pre: (C2 % C1) != 0 %a = mul nsw i8 %x, C1 %r = icmp ne i8 %a, C2 => %r = true Follow-up to the 'nuw' variation added with: rGf879c9b79621
This commit is contained in:
parent
60815c576a
commit
82aa9a6b56
@ -2750,12 +2750,14 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
|
||||
return ConstantInt::getFalse(ITy);
|
||||
}
|
||||
|
||||
// (mul nuw X, MulC) != C --> true (if C is not a multiple of MulC)
|
||||
// (mul nuw X, MulC) == C --> false (if C is not a multiple of MulC)
|
||||
// (mul nuw/nsw X, MulC) != C --> true (if C is not a multiple of MulC)
|
||||
// (mul nuw/nsw X, MulC) == C --> false (if C is not a multiple of MulC)
|
||||
const APInt *MulC;
|
||||
if (ICmpInst::isEquality(Pred) &&
|
||||
match(LHS, m_NUWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
|
||||
C->urem(*MulC) != 0)
|
||||
((match(LHS, m_NUWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
|
||||
C->urem(*MulC) != 0) ||
|
||||
(match(LHS, m_NSWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
|
||||
C->srem(*MulC) != 0)))
|
||||
return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
|
||||
|
||||
return nullptr;
|
||||
|
@ -194,9 +194,7 @@ define i1 @ugt_rem_zero_nonuw(i8 %x) {
|
||||
|
||||
define i1 @sgt_minnum(i8 %x) {
|
||||
; CHECK-LABEL: @sgt_minnum(
|
||||
; CHECK-NEXT: [[A:%.*]] = mul nsw i8 [[X:%.*]], 7
|
||||
; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[A]], -128
|
||||
; CHECK-NEXT: ret i1 [[B]]
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
%a = mul nsw i8 %x, 7
|
||||
%b = icmp sgt i8 %a, -128
|
||||
|
@ -916,3 +916,110 @@ define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
|
||||
%r = icmp eq i8 %m, -127
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; No overflow, so mul constant must be a factor of cmp constant.
|
||||
|
||||
define i1 @mul_nsw_srem_cmp_constant1(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant1(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%m = mul nsw i8 %x, 43
|
||||
%r = icmp eq i8 %m, 45
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Invert predicate and check vector type.
|
||||
|
||||
define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat(
|
||||
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||
;
|
||||
%m = mul nsw <2 x i8> %x, <i8 45, i8 45>
|
||||
%r = icmp ne <2 x i8> %m, <i8 15, i8 15>
|
||||
ret <2 x i1> %r
|
||||
}
|
||||
|
||||
; Undefs in vector constants are ok.
|
||||
|
||||
define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef1(
|
||||
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||
;
|
||||
%m = mul nsw <2 x i8> %x, <i8 45, i8 45>
|
||||
%r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
|
||||
ret <2 x i1> %r
|
||||
}
|
||||
|
||||
; Undefs in vector constants are ok.
|
||||
|
||||
define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef2(
|
||||
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||
;
|
||||
%m = mul nsw <2 x i8> %x, <i8 undef, i8 45>
|
||||
%r = icmp ne <2 x i8> %m, <i8 15, i8 15>
|
||||
ret <2 x i1> %r
|
||||
}
|
||||
|
||||
; Check negative numbers (constants should be analyzed as signed).
|
||||
|
||||
define i1 @mul_nsw_srem_cmp_constant2(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant2(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%m = mul nsw i8 %x, 43
|
||||
%r = icmp eq i8 %m, -127
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - require nsw.
|
||||
|
||||
define i1 @mul_srem_cmp_constant1(i8 %x) {
|
||||
; CHECK-LABEL: @mul_srem_cmp_constant1(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%m = mul i8 %x, 43
|
||||
%r = icmp eq i8 %m, 42
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - x could be 0.
|
||||
|
||||
define i1 @mul_nsw_srem_cmp_constant0(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant0(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], 23
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 0
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%m = mul nsw i8 %x, 23
|
||||
%r = icmp eq i8 %m, 0
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - cmp constant is multiple of mul constant.
|
||||
|
||||
define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], 42
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 84
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%m = mul nsw i8 %x, 42
|
||||
%r = icmp eq i8 %m, 84
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - cmp constant is multiple (treated as signed).
|
||||
|
||||
define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], -42
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -84
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%m = mul nsw i8 %x, -42
|
||||
%r = icmp eq i8 %m, -84
|
||||
ret i1 %r
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user