mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
[InstSimplify] fold icmp with mul nuw and constant operands
https://rise4fun.com/Alive/pZEr Name: mul nuw with icmp eq Pre: (C2 %u C1) != 0 %a = mul nuw i8 %x, C1 %r = icmp eq i8 %a, C2 => %r = false Name: mul nuw with icmp ne Pre: (C2 %u C1) != 0 %a = mul nuw i8 %x, C1 %r = icmp ne i8 %a, C2 => %r = true There are potentially several other transforms we need to add based on: D51625 ...but it doesn't look like there was follow-up to that patch.
This commit is contained in:
parent
f3548b0c21
commit
60815c576a
@ -2750,6 +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)
|
||||
const APInt *MulC;
|
||||
if (ICmpInst::isEquality(Pred) &&
|
||||
match(LHS, m_NUWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
|
||||
C->urem(*MulC) != 0)
|
||||
return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -141,9 +141,7 @@ define i1 @ne_rem_zero(i8 %x) {
|
||||
|
||||
define i1 @eq_rem_nz(i8 %x) {
|
||||
; CHECK-LABEL: @eq_rem_nz(
|
||||
; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 5
|
||||
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[A]], 31
|
||||
; CHECK-NEXT: ret i1 [[B]]
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%a = mul nuw i8 %x, 5
|
||||
%b = icmp eq i8 %a, 31
|
||||
@ -152,9 +150,7 @@ define i1 @eq_rem_nz(i8 %x) {
|
||||
|
||||
define i1 @ne_rem_nz(i8 %x) {
|
||||
; CHECK-LABEL: @ne_rem_nz(
|
||||
; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 5
|
||||
; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[A]], 31
|
||||
; CHECK-NEXT: ret i1 [[B]]
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
%a = mul nuw i8 %x, 5
|
||||
%b = icmp ne i8 %a, 31
|
||||
|
@ -810,11 +810,11 @@ define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; No overflow, so mul constant must be a factor of cmp constant.
|
||||
|
||||
define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant1(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%m = mul nuw i8 %x, 43
|
||||
%r = icmp eq i8 %m, 42
|
||||
@ -825,31 +825,29 @@ define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
|
||||
|
||||
define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 45, i8 45>
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[M]], <i8 15, i8 15>
|
||||
; CHECK-NEXT: ret <2 x i1> [[R]]
|
||||
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||
;
|
||||
%m = mul nuw <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_nuw_urem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef1(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 45, i8 45>
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[M]], <i8 15, i8 undef>
|
||||
; CHECK-NEXT: ret <2 x i1> [[R]]
|
||||
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||
;
|
||||
%m = mul nuw <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_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef2(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 undef, i8 45>
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[M]], <i8 15, i8 15>
|
||||
; CHECK-NEXT: ret <2 x i1> [[R]]
|
||||
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||
;
|
||||
%m = mul nuw <2 x i8> %x, <i8 undef, i8 45>
|
||||
%r = icmp ne <2 x i8> %m, <i8 15, i8 15>
|
||||
@ -860,15 +858,15 @@ define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
|
||||
|
||||
define i1 @mul_nuw_urem_cmp_constant2(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant2(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], -42
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -84
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%m = mul nuw i8 %x, -42
|
||||
%r = icmp eq i8 %m, -84
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - require nuw.
|
||||
|
||||
define i1 @mul_urem_cmp_constant1(i8 %x) {
|
||||
; CHECK-LABEL: @mul_urem_cmp_constant1(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43
|
||||
@ -880,6 +878,8 @@ define i1 @mul_urem_cmp_constant1(i8 %x) {
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - x could be 0.
|
||||
|
||||
define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant0(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 23
|
||||
@ -891,6 +891,8 @@ define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - cmp constant is multiple of mul constant.
|
||||
|
||||
define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 42
|
||||
@ -902,6 +904,8 @@ define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test - cmp constant is multiple (treated as unsigned).
|
||||
|
||||
define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
|
||||
; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0(
|
||||
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
|
||||
|
Loading…
Reference in New Issue
Block a user