Skip to content

Commit f879c9b

Browse files
committed
[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.
1 parent a569a0a commit f879c9b

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,6 +2750,14 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
27502750
return ConstantInt::getFalse(ITy);
27512751
}
27522752

2753+
// (mul nuw X, MulC) != C --> true (if C is not a multiple of MulC)
2754+
// (mul nuw X, MulC) == C --> false (if C is not a multiple of MulC)
2755+
const APInt *MulC;
2756+
if (ICmpInst::isEquality(Pred) &&
2757+
match(LHS, m_NUWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
2758+
C->urem(*MulC) != 0)
2759+
return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
2760+
27532761
return nullptr;
27542762
}
27552763

llvm/test/Transforms/InstCombine/icmp-mul.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,7 @@ define i1 @ne_rem_zero(i8 %x) {
141141

142142
define i1 @eq_rem_nz(i8 %x) {
143143
; CHECK-LABEL: @eq_rem_nz(
144-
; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 5
145-
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[A]], 31
146-
; CHECK-NEXT: ret i1 [[B]]
144+
; CHECK-NEXT: ret i1 false
147145
;
148146
%a = mul nuw i8 %x, 5
149147
%b = icmp eq i8 %a, 31
@@ -152,9 +150,7 @@ define i1 @eq_rem_nz(i8 %x) {
152150

153151
define i1 @ne_rem_nz(i8 %x) {
154152
; CHECK-LABEL: @ne_rem_nz(
155-
; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 5
156-
; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[A]], 31
157-
; CHECK-NEXT: ret i1 [[B]]
153+
; CHECK-NEXT: ret i1 true
158154
;
159155
%a = mul nuw i8 %x, 5
160156
%b = icmp ne i8 %a, 31

llvm/test/Transforms/InstSimplify/icmp-constant.ll

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -810,11 +810,11 @@ define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
810810
ret i1 %cmp
811811
}
812812

813+
; No overflow, so mul constant must be a factor of cmp constant.
814+
813815
define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
814816
; CHECK-LABEL: @mul_nuw_urem_cmp_constant1(
815-
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
816-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42
817-
; CHECK-NEXT: ret i1 [[R]]
817+
; CHECK-NEXT: ret i1 false
818818
;
819819
%m = mul nuw i8 %x, 43
820820
%r = icmp eq i8 %m, 42
@@ -825,31 +825,29 @@ define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
825825

826826
define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) {
827827
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat(
828-
; CHECK-NEXT: [[M:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 45, i8 45>
829-
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[M]], <i8 15, i8 15>
830-
; CHECK-NEXT: ret <2 x i1> [[R]]
828+
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
831829
;
832830
%m = mul nuw <2 x i8> %x, <i8 45, i8 45>
833831
%r = icmp ne <2 x i8> %m, <i8 15, i8 15>
834832
ret <2 x i1> %r
835833
}
836834

835+
; Undefs in vector constants are ok.
836+
837837
define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
838838
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef1(
839-
; CHECK-NEXT: [[M:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 45, i8 45>
840-
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[M]], <i8 15, i8 undef>
841-
; CHECK-NEXT: ret <2 x i1> [[R]]
839+
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
842840
;
843841
%m = mul nuw <2 x i8> %x, <i8 45, i8 45>
844842
%r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
845843
ret <2 x i1> %r
846844
}
847845

846+
; Undefs in vector constants are ok.
847+
848848
define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
849849
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef2(
850-
; CHECK-NEXT: [[M:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 undef, i8 45>
851-
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[M]], <i8 15, i8 15>
852-
; CHECK-NEXT: ret <2 x i1> [[R]]
850+
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
853851
;
854852
%m = mul nuw <2 x i8> %x, <i8 undef, i8 45>
855853
%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) {
860858

861859
define i1 @mul_nuw_urem_cmp_constant2(i8 %x) {
862860
; CHECK-LABEL: @mul_nuw_urem_cmp_constant2(
863-
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], -42
864-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -84
865-
; CHECK-NEXT: ret i1 [[R]]
861+
; CHECK-NEXT: ret i1 false
866862
;
867863
%m = mul nuw i8 %x, -42
868864
%r = icmp eq i8 %m, -84
869865
ret i1 %r
870866
}
871867

868+
; Negative test - require nuw.
869+
872870
define i1 @mul_urem_cmp_constant1(i8 %x) {
873871
; CHECK-LABEL: @mul_urem_cmp_constant1(
874872
; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43
@@ -880,6 +878,8 @@ define i1 @mul_urem_cmp_constant1(i8 %x) {
880878
ret i1 %r
881879
}
882880

881+
; Negative test - x could be 0.
882+
883883
define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
884884
; CHECK-LABEL: @mul_nuw_urem_cmp_constant0(
885885
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 23
@@ -891,6 +891,8 @@ define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
891891
ret i1 %r
892892
}
893893

894+
; Negative test - cmp constant is multiple of mul constant.
895+
894896
define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
895897
; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0(
896898
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 42
@@ -902,6 +904,8 @@ define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
902904
ret i1 %r
903905
}
904906

907+
; Negative test - cmp constant is multiple (treated as unsigned).
908+
905909
define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
906910
; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0(
907911
; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 43

0 commit comments

Comments
 (0)