1571 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @llvm.assume(i1)5declare void @use(i8)6declare void @usev2xi8(<2 x i8>)7 8 9define i1 @squared_nsw_eq0(i5 %x) {10; CHECK-LABEL: @squared_nsw_eq0(11; CHECK-NEXT: [[R:%.*]] = icmp eq i5 [[X:%.*]], 012; CHECK-NEXT: ret i1 [[R]]13;14 %m = mul nsw i5 %x, %x15 %r = icmp eq i5 %m, 016 ret i1 %r17}18 19define <2 x i1> @squared_nuw_eq0(<2 x i8> %x) {20; CHECK-LABEL: @squared_nuw_eq0(21; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer22; CHECK-NEXT: ret <2 x i1> [[R]]23;24 %m = mul nuw <2 x i8> %x, %x25 %r = icmp eq <2 x i8> %m, zeroinitializer26 ret <2 x i1> %r27}28 29; extra use is ok30 31define i1 @squared_nsw_nuw_ne0(i8 %x) {32; CHECK-LABEL: @squared_nsw_nuw_ne0(33; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]34; CHECK-NEXT: call void @use(i8 [[M]])35; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 036; CHECK-NEXT: ret i1 [[R]]37;38 %m = mul nsw nuw i8 %x, %x39 call void @use(i8 %m)40 %r = icmp ne i8 %m, 041 ret i1 %r42}43 44; negative test - must have no-overflow45 46define i1 @squared_eq0(i8 %x) {47; CHECK-LABEL: @squared_eq0(48; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], [[X]]49; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 050; CHECK-NEXT: ret i1 [[R]]51;52 %m = mul i8 %x, %x53 %r = icmp eq i8 %m, 054 ret i1 %r55}56 57; negative test - not squared58; TODO: This could be or-of-icmps.59 60define i1 @mul_nsw_eq0(i5 %x, i5 %y) {61; CHECK-LABEL: @mul_nsw_eq0(62; CHECK-NEXT: [[M:%.*]] = mul nsw i5 [[X:%.*]], [[Y:%.*]]63; CHECK-NEXT: [[R:%.*]] = icmp eq i5 [[M]], 064; CHECK-NEXT: ret i1 [[R]]65;66 %m = mul nsw i5 %x, %y67 %r = icmp eq i5 %m, 068 ret i1 %r69}70 71; negative test - non-zero cmp72 73define i1 @squared_nsw_eq1(i5 %x) {74; CHECK-LABEL: @squared_nsw_eq1(75; CHECK-NEXT: [[M:%.*]] = mul nsw i5 [[X:%.*]], [[X]]76; CHECK-NEXT: [[R:%.*]] = icmp eq i5 [[M]], 177; CHECK-NEXT: ret i1 [[R]]78;79 %m = mul nsw i5 %x, %x80 %r = icmp eq i5 %m, 181 ret i1 %r82}83 84define i1 @squared_nsw_sgt0(i5 %x) {85; CHECK-LABEL: @squared_nsw_sgt0(86; CHECK-NEXT: [[R:%.*]] = icmp ne i5 [[X:%.*]], 087; CHECK-NEXT: ret i1 [[R]]88;89 %m = mul nsw i5 %x, %x90 %r = icmp sgt i5 %m, 091 ret i1 %r92}93 94; Tests for slt/ult95 96define i1 @slt_positive_multip_rem_zero(i8 %x) {97; CHECK-LABEL: @slt_positive_multip_rem_zero(98; CHECK-NEXT: [[B:%.*]] = icmp slt i8 [[X:%.*]], 399; CHECK-NEXT: ret i1 [[B]]100;101 %a = mul nsw i8 %x, 7102 %b = icmp slt i8 %a, 21103 ret i1 %b104}105 106define i1 @slt_negative_multip_rem_zero(i8 %x) {107; CHECK-LABEL: @slt_negative_multip_rem_zero(108; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 [[X:%.*]], -3109; CHECK-NEXT: ret i1 [[B]]110;111 %a = mul nsw i8 %x, -7112 %b = icmp slt i8 %a, 21113 ret i1 %b114}115 116define i1 @slt_positive_multip_rem_nz(i8 %x) {117; CHECK-LABEL: @slt_positive_multip_rem_nz(118; CHECK-NEXT: [[B:%.*]] = icmp slt i8 [[X:%.*]], 5119; CHECK-NEXT: ret i1 [[B]]120;121 %a = mul nsw i8 %x, 5122 %b = icmp slt i8 %a, 21123 ret i1 %b124}125 126define i1 @ult_rem_zero(i8 %x) {127; CHECK-LABEL: @ult_rem_zero(128; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 3129; CHECK-NEXT: ret i1 [[B]]130;131 %a = mul nuw i8 %x, 7132 %b = icmp ult i8 %a, 21133 ret i1 %b134}135 136; Same as above, but with nsw flag too.137; This used to not optimize due to nsw being prioritized too much.138define i1 @ult_rem_zero_nsw(i8 %x) {139; CHECK-LABEL: @ult_rem_zero_nsw(140; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 3141; CHECK-NEXT: ret i1 [[B]]142;143 %a = mul nuw nsw i8 %x, 7144 %b = icmp ult i8 %a, 21145 ret i1 %b146}147 148define i1 @ult_rem_nz(i8 %x) {149; CHECK-LABEL: @ult_rem_nz(150; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 5151; CHECK-NEXT: ret i1 [[B]]152;153 %a = mul nuw i8 %x, 5154 %b = icmp ult i8 %a, 21155 ret i1 %b156}157 158; Same as above, but with nsw flag too.159; This used to not optimize due to nsw being prioritized too much.160define i1 @ult_rem_nz_nsw(i8 %x) {161; CHECK-LABEL: @ult_rem_nz_nsw(162; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 5163; CHECK-NEXT: ret i1 [[B]]164;165 %a = mul nuw nsw i8 %x, 5166 %b = icmp ult i8 %a, 21167 ret i1 %b168}169 170; Tests for sgt/ugt171 172define i1 @sgt_positive_multip_rem_zero(i8 %x) {173; CHECK-LABEL: @sgt_positive_multip_rem_zero(174; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 [[X:%.*]], 3175; CHECK-NEXT: ret i1 [[B]]176;177 %a = mul nsw i8 %x, 7178 %b = icmp sgt i8 %a, 21179 ret i1 %b180}181 182define i1 @sgt_negative_multip_rem_zero(i8 %x) {183; CHECK-LABEL: @sgt_negative_multip_rem_zero(184; CHECK-NEXT: [[B:%.*]] = icmp slt i8 [[X:%.*]], -3185; CHECK-NEXT: ret i1 [[B]]186;187 %a = mul nsw i8 %x, -7188 %b = icmp sgt i8 %a, 21189 ret i1 %b190}191 192define i1 @sgt_positive_multip_rem_nz(i8 %x) {193; CHECK-LABEL: @sgt_positive_multip_rem_nz(194; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 [[X:%.*]], 4195; CHECK-NEXT: ret i1 [[B]]196;197 %a = mul nsw i8 %x, 5198 %b = icmp sgt i8 %a, 21199 ret i1 %b200}201 202define i1 @ugt_rem_zero(i8 %x) {203; CHECK-LABEL: @ugt_rem_zero(204; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3205; CHECK-NEXT: ret i1 [[B]]206;207 %a = mul nuw i8 %x, 7208 %b = icmp ugt i8 %a, 21209 ret i1 %b210}211 212; Same as above, but with nsw flag too.213; This used to not optimize due to nsw being prioritized too much.214define i1 @ugt_rem_zero_nsw(i8 %x) {215; CHECK-LABEL: @ugt_rem_zero_nsw(216; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3217; CHECK-NEXT: ret i1 [[B]]218;219 %a = mul nuw nsw i8 %x, 7220 %b = icmp ugt i8 %a, 21221 ret i1 %b222}223 224define i1 @ugt_rem_nz(i8 %x) {225; CHECK-LABEL: @ugt_rem_nz(226; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 4227; CHECK-NEXT: ret i1 [[B]]228;229 %a = mul nuw i8 %x, 5230 %b = icmp ugt i8 %a, 21231 ret i1 %b232}233 234; Same as above, but with nsw flag too.235; This used to not optimize due to nsw being prioritized too much.236define i1 @ugt_rem_nz_nsw(i8 %x) {237; CHECK-LABEL: @ugt_rem_nz_nsw(238; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 4239; CHECK-NEXT: ret i1 [[B]]240;241 %a = mul nuw nsw i8 %x, 5242 %b = icmp ugt i8 %a, 21243 ret i1 %b244}245 246; Tests for eq/ne247 248define i1 @eq_nsw_rem_zero(i8 %x) {249; CHECK-LABEL: @eq_nsw_rem_zero(250; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[X:%.*]], -4251; CHECK-NEXT: ret i1 [[B]]252;253 %a = mul nsw i8 %x, -5254 %b = icmp eq i8 %a, 20255 ret i1 %b256}257 258define <2 x i1> @ne_nsw_rem_zero(<2 x i8> %x) {259; CHECK-LABEL: @ne_nsw_rem_zero(260; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i8> [[X:%.*]], splat (i8 -6)261; CHECK-NEXT: ret <2 x i1> [[B]]262;263 %a = mul nsw <2 x i8> %x, <i8 5, i8 5>264 %b = icmp ne <2 x i8> %a, <i8 -30, i8 -30>265 ret <2 x i1> %b266}267 268; TODO: Missed fold with undef.269 270define <2 x i1> @ne_nsw_rem_zero_undef1(<2 x i8> %x) {271; CHECK-LABEL: @ne_nsw_rem_zero_undef1(272; CHECK-NEXT: [[A:%.*]] = mul nsw <2 x i8> [[X:%.*]], <i8 5, i8 undef>273; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i8> [[A]], splat (i8 -30)274; CHECK-NEXT: ret <2 x i1> [[B]]275;276 %a = mul nsw <2 x i8> %x, <i8 5, i8 undef>277 %b = icmp ne <2 x i8> %a, <i8 -30, i8 -30>278 ret <2 x i1> %b279}280 281; TODO: Missed fold with undef.282 283define <2 x i1> @ne_nsw_rem_zero_undef2(<2 x i8> %x) {284; CHECK-LABEL: @ne_nsw_rem_zero_undef2(285; CHECK-NEXT: [[A:%.*]] = mul nsw <2 x i8> [[X:%.*]], splat (i8 5)286; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i8> [[A]], <i8 -30, i8 undef>287; CHECK-NEXT: ret <2 x i1> [[B]]288;289 %a = mul nsw <2 x i8> %x, <i8 5, i8 5>290 %b = icmp ne <2 x i8> %a, <i8 -30, i8 undef>291 ret <2 x i1> %b292}293 294define i1 @eq_nsw_rem_zero_uses(i8 %x) {295; CHECK-LABEL: @eq_nsw_rem_zero_uses(296; CHECK-NEXT: [[A:%.*]] = mul nsw i8 [[X:%.*]], -5297; CHECK-NEXT: call void @use(i8 [[A]])298; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[X]], -4299; CHECK-NEXT: ret i1 [[B]]300;301 %a = mul nsw i8 %x, -5302 call void @use(i8 %a)303 %b = icmp eq i8 %a, 20304 ret i1 %b305}306 307; Impossible multiple should be handled by instsimplify.308 309define i1 @eq_nsw_rem_nz(i8 %x) {310; CHECK-LABEL: @eq_nsw_rem_nz(311; CHECK-NEXT: ret i1 false312;313 %a = mul nsw i8 %x, 5314 %b = icmp eq i8 %a, 245315 ret i1 %b316}317 318; Impossible multiple should be handled by instsimplify.319 320define i1 @ne_nsw_rem_nz(i8 %x) {321; CHECK-LABEL: @ne_nsw_rem_nz(322; CHECK-NEXT: ret i1 true323;324 %a = mul nsw i8 %x, 5325 %b = icmp ne i8 %a, 130326 ret i1 %b327}328 329define <2 x i1> @eq_nuw_rem_zero(<2 x i8> %x) {330; CHECK-LABEL: @eq_nuw_rem_zero(331; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 4)332; CHECK-NEXT: ret <2 x i1> [[B]]333;334 %a = mul nuw <2 x i8> %x, <i8 5, i8 5>335 %b = icmp eq <2 x i8> %a, <i8 20, i8 20>336 ret <2 x i1> %b337}338 339; TODO: Missed fold with undef.340 341define <2 x i1> @eq_nuw_rem_zero_undef1(<2 x i8> %x) {342; CHECK-LABEL: @eq_nuw_rem_zero_undef1(343; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[X:%.*]], <i8 undef, i8 5>344; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i8> [[A]], splat (i8 20)345; CHECK-NEXT: ret <2 x i1> [[B]]346;347 %a = mul nuw <2 x i8> %x, <i8 undef, i8 5>348 %b = icmp eq <2 x i8> %a, <i8 20, i8 20>349 ret <2 x i1> %b350}351 352; TODO: Missed fold with undef.353 354define <2 x i1> @eq_nuw_rem_zero_undef2(<2 x i8> %x) {355; CHECK-LABEL: @eq_nuw_rem_zero_undef2(356; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[X:%.*]], splat (i8 5)357; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i8> [[A]], <i8 undef, i8 20>358; CHECK-NEXT: ret <2 x i1> [[B]]359;360 %a = mul nuw <2 x i8> %x, <i8 5, i8 5>361 %b = icmp eq <2 x i8> %a, <i8 undef, i8 20>362 ret <2 x i1> %b363}364 365define i1 @ne_nuw_rem_zero(i8 %x) {366; CHECK-LABEL: @ne_nuw_rem_zero(367; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[X:%.*]], 26368; CHECK-NEXT: ret i1 [[B]]369;370 %a = mul nuw i8 %x, 5371 %b = icmp ne i8 %a, 130372 ret i1 %b373}374 375define i1 @ne_nuw_rem_zero_uses(i8 %x) {376; CHECK-LABEL: @ne_nuw_rem_zero_uses(377; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 5378; CHECK-NEXT: call void @use(i8 [[A]])379; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[X]], 26380; CHECK-NEXT: ret i1 [[B]]381;382 %a = mul nuw i8 %x, 5383 call void @use(i8 %a)384 %b = icmp ne i8 %a, 130385 ret i1 %b386}387 388; Impossible multiple should be handled by instsimplify.389 390define i1 @eq_nuw_rem_nz(i8 %x) {391; CHECK-LABEL: @eq_nuw_rem_nz(392; CHECK-NEXT: ret i1 false393;394 %a = mul nuw i8 %x, -5395 %b = icmp eq i8 %a, 20396 ret i1 %b397}398 399; Impossible multiple should be handled by instsimplify.400 401define i1 @ne_nuw_rem_nz(i8 %x) {402; CHECK-LABEL: @ne_nuw_rem_nz(403; CHECK-NEXT: ret i1 true404;405 %a = mul nuw i8 %x, 5406 %b = icmp ne i8 %a, -30407 ret i1 %b408}409 410; Negative tests for the icmp mul folds411 412define i1 @sgt_positive_multip_rem_zero_nonsw(i8 %x) {413; CHECK-LABEL: @sgt_positive_multip_rem_zero_nonsw(414; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 7415; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 [[A]], 21416; CHECK-NEXT: ret i1 [[B]]417;418 %a = mul i8 %x, 7419 %b = icmp sgt i8 %a, 21420 ret i1 %b421}422 423define i1 @ult_multip_rem_zero_nonsw(i8 %x) {424; CHECK-LABEL: @ult_multip_rem_zero_nonsw(425; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 7426; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[A]], 21427; CHECK-NEXT: ret i1 [[B]]428;429 %a = mul i8 %x, 7430 %b = icmp ult i8 %a, 21431 ret i1 %b432}433 434define i1 @ugt_rem_zero_nonuw(i8 %x) {435; CHECK-LABEL: @ugt_rem_zero_nonuw(436; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 7437; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[A]], 21438; CHECK-NEXT: ret i1 [[B]]439;440 %a = mul i8 %x, 7441 %b = icmp ugt i8 %a, 21442 ret i1 %b443}444 445define i1 @sgt_minnum(i8 %x) {446; CHECK-LABEL: @sgt_minnum(447; CHECK-NEXT: ret i1 true448;449 %a = mul nsw i8 %x, 7450 %b = icmp sgt i8 %a, -128451 ret i1 %b452}453 454define i1 @ule_bignum(i8 %x) {455; CHECK-LABEL: @ule_bignum(456; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[X:%.*]], 0457; CHECK-NEXT: ret i1 [[B]]458;459 %a = mul i8 %x, 2147483647460 %b = icmp ule i8 %a, 0461 ret i1 %b462}463 464define i1 @sgt_mulzero(i8 %x) {465; CHECK-LABEL: @sgt_mulzero(466; CHECK-NEXT: ret i1 false467;468 %a = mul nsw i8 %x, 0469 %b = icmp sgt i8 %a, 21470 ret i1 %b471}472 473define i1 @eq_rem_zero_nonuw(i8 %x) {474; CHECK-LABEL: @eq_rem_zero_nonuw(475; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[X:%.*]], 4476; CHECK-NEXT: ret i1 [[B]]477;478 %a = mul i8 %x, 5479 %b = icmp eq i8 %a, 20480 ret i1 %b481}482 483define i1 @ne_rem_zero_nonuw(i8 %x) {484; CHECK-LABEL: @ne_rem_zero_nonuw(485; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[X:%.*]], 6486; CHECK-NEXT: ret i1 [[B]]487;488 %a = mul i8 %x, 5489 %b = icmp ne i8 %a, 30490 ret i1 %b491}492 493define i1 @mul_constant_eq(i32 %x, i32 %y) {494; CHECK-LABEL: @mul_constant_eq(495; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]496; CHECK-NEXT: ret i1 [[C]]497;498 %A = mul i32 %x, 5499 %B = mul i32 %y, 5500 %C = icmp eq i32 %A, %B501 ret i1 %C502}503 504define <2 x i1> @mul_constant_ne_splat(<2 x i32> %x, <2 x i32> %y) {505; CHECK-LABEL: @mul_constant_ne_splat(506; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]507; CHECK-NEXT: ret <2 x i1> [[C]]508;509 %A = mul <2 x i32> %x, <i32 5, i32 5>510 %B = mul <2 x i32> %y, <i32 5, i32 5>511 %C = icmp ne <2 x i32> %A, %B512 ret <2 x i1> %C513}514 515define i1 @mul_constant_ne_extra_use1(i8 %x, i8 %y) {516; CHECK-LABEL: @mul_constant_ne_extra_use1(517; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 5518; CHECK-NEXT: call void @use(i8 [[A]])519; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], [[Y:%.*]]520; CHECK-NEXT: ret i1 [[C]]521;522 %A = mul i8 %x, 5523 call void @use(i8 %A)524 %B = mul i8 %y, 5525 %C = icmp ne i8 %A, %B526 ret i1 %C527}528 529define i1 @mul_constant_eq_extra_use2(i8 %x, i8 %y) {530; CHECK-LABEL: @mul_constant_eq_extra_use2(531; CHECK-NEXT: [[B:%.*]] = mul i8 [[Y:%.*]], 5532; CHECK-NEXT: call void @use(i8 [[B]])533; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X:%.*]], [[Y]]534; CHECK-NEXT: ret i1 [[C]]535;536 %A = mul i8 %x, 5537 %B = mul i8 %y, 5538 call void @use(i8 %B)539 %C = icmp eq i8 %A, %B540 ret i1 %C541}542 543define i1 @mul_constant_ne_extra_use3(i8 %x, i8 %y) {544; CHECK-LABEL: @mul_constant_ne_extra_use3(545; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 5546; CHECK-NEXT: call void @use(i8 [[A]])547; CHECK-NEXT: [[B:%.*]] = mul i8 [[Y:%.*]], 5548; CHECK-NEXT: call void @use(i8 [[B]])549; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], [[Y]]550; CHECK-NEXT: ret i1 [[C]]551;552 %A = mul i8 %x, 5553 call void @use(i8 %A)554 %B = mul i8 %y, 5555 call void @use(i8 %B)556 %C = icmp ne i8 %A, %B557 ret i1 %C558}559 560define i1 @mul_constant_eq_nsw(i32 %x, i32 %y) {561; CHECK-LABEL: @mul_constant_eq_nsw(562; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]563; CHECK-NEXT: ret i1 [[C]]564;565 %A = mul nsw i32 %x, 6566 %B = mul nsw i32 %y, 6567 %C = icmp eq i32 %A, %B568 ret i1 %C569}570 571define <2 x i1> @mul_constant_ne_nsw_splat(<2 x i32> %x, <2 x i32> %y) {572; CHECK-LABEL: @mul_constant_ne_nsw_splat(573; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]574; CHECK-NEXT: ret <2 x i1> [[C]]575;576 %A = mul nsw <2 x i32> %x, <i32 12, i32 12>577 %B = mul nsw <2 x i32> %y, <i32 12, i32 12>578 %C = icmp ne <2 x i32> %A, %B579 ret <2 x i1> %C580}581 582define i1 @mul_constant_ne_nsw_extra_use1(i8 %x, i8 %y) {583; CHECK-LABEL: @mul_constant_ne_nsw_extra_use1(584; CHECK-NEXT: [[A:%.*]] = mul nsw i8 [[X:%.*]], 74585; CHECK-NEXT: call void @use(i8 [[A]])586; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], [[Y:%.*]]587; CHECK-NEXT: ret i1 [[C]]588;589 %A = mul nsw i8 %x, 74590 call void @use(i8 %A)591 %B = mul nsw i8 %y, 74592 %C = icmp ne i8 %A, %B593 ret i1 %C594}595 596define i1 @mul_constant_eq_nsw_extra_use2(i8 %x, i8 %y) {597; CHECK-LABEL: @mul_constant_eq_nsw_extra_use2(598; CHECK-NEXT: [[B:%.*]] = mul nsw i8 [[Y:%.*]], 20599; CHECK-NEXT: call void @use(i8 [[B]])600; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X:%.*]], [[Y]]601; CHECK-NEXT: ret i1 [[C]]602;603 %A = mul nsw i8 %x, 20604 %B = mul nsw i8 %y, 20605 call void @use(i8 %B)606 %C = icmp eq i8 %A, %B607 ret i1 %C608}609 610define i1 @mul_constant_ne_nsw_extra_use3(i8 %x, i8 %y) {611; CHECK-LABEL: @mul_constant_ne_nsw_extra_use3(612; CHECK-NEXT: [[A:%.*]] = mul nsw i8 [[X:%.*]], 24613; CHECK-NEXT: call void @use(i8 [[A]])614; CHECK-NEXT: [[B:%.*]] = mul nsw i8 [[Y:%.*]], 24615; CHECK-NEXT: call void @use(i8 [[B]])616; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], [[Y]]617; CHECK-NEXT: ret i1 [[C]]618;619 %A = mul nsw i8 %x, 24620 call void @use(i8 %A)621 %B = mul nsw i8 %y, 24622 call void @use(i8 %B)623 %C = icmp ne i8 %A, %B624 ret i1 %C625}626 627define i1 @mul_constant_nuw_eq(i32 %x, i32 %y) {628; CHECK-LABEL: @mul_constant_nuw_eq(629; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]630; CHECK-NEXT: ret i1 [[C]]631;632 %A = mul nuw i32 %x, 22633 %B = mul nuw i32 %y, 22634 %C = icmp eq i32 %A, %B635 ret i1 %C636}637 638define <2 x i1> @mul_constant_ne_nuw_splat(<2 x i32> %x, <2 x i32> %y) {639; CHECK-LABEL: @mul_constant_ne_nuw_splat(640; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]641; CHECK-NEXT: ret <2 x i1> [[C]]642;643 %A = mul nuw <2 x i32> %x, <i32 10, i32 10>644 %B = mul nuw <2 x i32> %y, <i32 10, i32 10>645 %C = icmp ne <2 x i32> %A, %B646 ret <2 x i1> %C647}648 649define i1 @mul_constant_ne_nuw_extra_use1(i8 %x, i8 %y) {650; CHECK-LABEL: @mul_constant_ne_nuw_extra_use1(651; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 6652; CHECK-NEXT: call void @use(i8 [[A]])653; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], [[Y:%.*]]654; CHECK-NEXT: ret i1 [[C]]655;656 %A = mul nuw i8 %x, 6657 call void @use(i8 %A)658 %B = mul nuw i8 %y, 6659 %C = icmp ne i8 %A, %B660 ret i1 %C661}662 663define i1 @mul_constant_eq_nuw_extra_use2(i8 %x, i8 %y) {664; CHECK-LABEL: @mul_constant_eq_nuw_extra_use2(665; CHECK-NEXT: [[B:%.*]] = mul nuw i8 [[Y:%.*]], 36666; CHECK-NEXT: call void @use(i8 [[B]])667; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X:%.*]], [[Y]]668; CHECK-NEXT: ret i1 [[C]]669;670 %A = mul nuw i8 %x, 36671 %B = mul nuw i8 %y, 36672 call void @use(i8 %B)673 %C = icmp eq i8 %A, %B674 ret i1 %C675}676 677define i1 @mul_constant_ne_nuw_extra_use3(i8 %x, i8 %y) {678; CHECK-LABEL: @mul_constant_ne_nuw_extra_use3(679; CHECK-NEXT: [[A:%.*]] = mul nuw i8 [[X:%.*]], 38680; CHECK-NEXT: call void @use(i8 [[A]])681; CHECK-NEXT: [[B:%.*]] = mul nuw i8 [[Y:%.*]], 38682; CHECK-NEXT: call void @use(i8 [[B]])683; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], [[Y]]684; CHECK-NEXT: ret i1 [[C]]685;686 %A = mul nuw i8 %x, 38687 call void @use(i8 %A)688 %B = mul nuw i8 %y, 38689 call void @use(i8 %B)690 %C = icmp ne i8 %A, %B691 ret i1 %C692}693 694; Negative test - wrong pred695 696define i1 @mul_constant_ult(i32 %x, i32 %y) {697; CHECK-LABEL: @mul_constant_ult(698; CHECK-NEXT: [[A:%.*]] = mul i32 [[X:%.*]], 47699; CHECK-NEXT: [[B:%.*]] = mul i32 [[Y:%.*]], 47700; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]]701; CHECK-NEXT: ret i1 [[C]]702;703 %A = mul i32 %x, 47704 %B = mul i32 %y, 47705 %C = icmp ult i32 %A, %B706 ret i1 %C707}708 709; Negative test - wrong pred710 711define i1 @mul_constant_nuw_sgt(i32 %x, i32 %y) {712; CHECK-LABEL: @mul_constant_nuw_sgt(713; CHECK-NEXT: [[A:%.*]] = mul nuw i32 [[X:%.*]], 46714; CHECK-NEXT: [[B:%.*]] = mul nuw i32 [[Y:%.*]], 46715; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]716; CHECK-NEXT: ret i1 [[C]]717;718 %A = mul nuw i32 %x, 46719 %B = mul nuw i32 %y, 46720 %C = icmp sgt i32 %A, %B721 ret i1 %C722}723 724; Negative test - wrong constants725 726define i1 @mul_mismatch_constant_nuw_eq(i32 %x, i32 %y) {727; CHECK-LABEL: @mul_mismatch_constant_nuw_eq(728; CHECK-NEXT: [[A:%.*]] = mul nuw i32 [[X:%.*]], 46729; CHECK-NEXT: [[B:%.*]] = mul nuw i32 [[Y:%.*]], 44730; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A]], [[B]]731; CHECK-NEXT: ret i1 [[C]]732;733 %A = mul nuw i32 %x, 46734 %B = mul nuw i32 %y, 44735 %C = icmp eq i32 %A, %B736 ret i1 %C737}738 739; If the multiply constant has any trailing zero bits but could overflow,740; we get something completely different.741; We mask off the high bits of each input and then convert:742; (X&Z) == (Y&Z) -> (X^Y) & Z == 0743 744define i1 @mul_constant_partial_nuw_eq(i32 %x, i32 %y) {745; CHECK-LABEL: @mul_constant_partial_nuw_eq(746; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]747; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823748; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[TMP2]], 0749; CHECK-NEXT: ret i1 [[C]]750;751 %A = mul i32 %x, 44752 %B = mul nuw i32 %y, 44753 %C = icmp eq i32 %A, %B754 ret i1 %C755}756 757define i1 @mul_constant_mismatch_wrap_eq(i32 %x, i32 %y) {758; CHECK-LABEL: @mul_constant_mismatch_wrap_eq(759; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]760; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 2147483647761; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[TMP2]], 0762; CHECK-NEXT: ret i1 [[C]]763;764 %A = mul nsw i32 %x, 54765 %B = mul nuw i32 %y, 54766 %C = icmp eq i32 %A, %B767 ret i1 %C768}769 770define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) {771; CHECK-LABEL: @eq_mul_constants_with_tz(772; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]773; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823774; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[TMP2]], 0775; CHECK-NEXT: ret i1 [[C]]776;777 %A = mul i32 %x, 12778 %B = mul i32 %y, 12779 %C = icmp ne i32 %A, %B780 ret i1 %C781}782 783define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) {784; CHECK-LABEL: @eq_mul_constants_with_tz_splat(785; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]786; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], splat (i32 1073741823)787; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer788; CHECK-NEXT: ret <2 x i1> [[C]]789;790 %A = mul <2 x i32> %x, <i32 12, i32 12>791 %B = mul <2 x i32> %y, <i32 12, i32 12>792 %C = icmp eq <2 x i32> %A, %B793 ret <2 x i1> %C794}795 796@g = extern_weak global i32797 798define i1 @oss_fuzz_39934(i32 %arg) {799; CHECK-LABEL: @oss_fuzz_39934(800; CHECK-NEXT: [[C10:%.*]] = icmp ne i32 [[ARG:%.*]], 1801; CHECK-NEXT: ret i1 [[C10]]802;803 %B13 = mul nsw i32 %arg, -65536804 %cmp = icmp eq ptr @g, null805 %ext = zext i1 %cmp to i32806 %or = or i32 %ext, 65537807 %mul = mul i32 %or, -65536808 %C10 = icmp ne i32 %mul, %B13809 ret i1 %C10810}811 812define i1 @mul_of_bool(i32 %x, i8 %y) {813; CHECK-LABEL: @mul_of_bool(814; CHECK-NEXT: ret i1 false815;816 %b = and i32 %x, 1817 %z = zext i8 %y to i32818 %m = mul i32 %b, %z819 %r = icmp ugt i32 %m, 255820 ret i1 %r821}822 823define i1 @mul_of_bool_commute(i32 %x, i32 %y) {824; CHECK-LABEL: @mul_of_bool_commute(825; CHECK-NEXT: ret i1 false826;827 %x1 = and i32 %x, 1828 %y8 = and i32 %y, 255829 %m = mul i32 %y8, %x1830 %r = icmp ugt i32 %m, 255831 ret i1 %r832}833 834define i1 @mul_of_bools(i32 %x, i32 %y) {835; CHECK-LABEL: @mul_of_bools(836; CHECK-NEXT: ret i1 true837;838 %x1 = and i32 %x, 1839 %y1 = and i32 %y, 1840 %m = mul i32 %x1, %y1841 %r = icmp ult i32 %m, 2842 ret i1 %r843}844 845; negative test - not a mask of low bit846 847define i1 @not_mul_of_bool(i32 %x, i8 %y) {848; CHECK-LABEL: @not_mul_of_bool(849; CHECK-NEXT: [[Q:%.*]] = and i32 [[X:%.*]], 3850; CHECK-NEXT: [[Z:%.*]] = zext i8 [[Y:%.*]] to i32851; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Q]], [[Z]]852; CHECK-NEXT: [[R:%.*]] = icmp samesign ugt i32 [[M]], 255853; CHECK-NEXT: ret i1 [[R]]854;855 %q = and i32 %x, 3856 %z = zext i8 %y to i32857 %m = mul i32 %q, %z858 %r = icmp ugt i32 %m, 255859 ret i1 %r860}861 862; negative test - not a single low bit863 864define i1 @not_mul_of_bool_commute(i32 %x, i32 %y) {865; CHECK-LABEL: @not_mul_of_bool_commute(866; CHECK-NEXT: [[X30:%.*]] = lshr i32 [[X:%.*]], 30867; CHECK-NEXT: [[Y8:%.*]] = and i32 [[Y:%.*]], 255868; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Y8]], [[X30]]869; CHECK-NEXT: [[R:%.*]] = icmp samesign ugt i32 [[M]], 255870; CHECK-NEXT: ret i1 [[R]]871;872 %x30 = lshr i32 %x, 30873 %y8 = and i32 %y, 255874 %m = mul i32 %y8, %x30875 %r = icmp ugt i32 %m, 255876 ret i1 %r877}878 879; no leading zeros for 's', but we reduce this with other transforms880 881define i1 @mul_of_bool_no_lz_other_op(i32 %x, i8 %y) {882; CHECK-LABEL: @mul_of_bool_no_lz_other_op(883; CHECK-NEXT: ret i1 false884;885 %b = and i32 %x, 1886 %s = sext i8 %y to i32887 %m = mul nuw nsw i32 %b, %s888 %r = icmp sgt i32 %m, 127889 ret i1 %r890}891 892; high and low bits are known 0893 894define i1 @mul_of_pow2(i32 %x, i8 %y) {895; CHECK-LABEL: @mul_of_pow2(896; CHECK-NEXT: ret i1 false897;898 %b = and i32 %x, 2899 %z = zext i8 %y to i32900 %m = mul i32 %b, %z901 %r = icmp ugt i32 %m, 510902 ret i1 %r903}904 905; high and low bits are known 0906 907define i1 @mul_of_pow2_commute(i32 %x, i32 %y) {908; CHECK-LABEL: @mul_of_pow2_commute(909; CHECK-NEXT: ret i1 false910;911 %x4 = and i32 %x, 4912 %y8 = and i32 %y, 255913 %m = mul i32 %y8, %x4914 %r = icmp ugt i32 %m, 1020915 ret i1 %r916}917 918; only bit 7 can be set by the multiply919 920define i32 @mul_of_pow2s(i32 %x, i32 %y) {921; CHECK-LABEL: @mul_of_pow2s(922; CHECK-NEXT: ret i32 128923;924 %x8 = and i32 %x, 8925 %y16 = and i32 %y, 16926 %m = mul i32 %x8, %y16927 %bit7 = or i32 %m, 128928 ret i32 %bit7929}930 931; negative test - 6 * 255 = 1530 (but constant range analysis can get this)932 933define i1 @not_mul_of_pow2(i32 %x, i8 %y) {934; CHECK-LABEL: @not_mul_of_pow2(935; CHECK-NEXT: [[Q:%.*]] = and i32 [[X:%.*]], 6936; CHECK-NEXT: [[Z:%.*]] = zext i8 [[Y:%.*]] to i32937; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Q]], [[Z]]938; CHECK-NEXT: [[R:%.*]] = icmp samesign ugt i32 [[M]], 1530939; CHECK-NEXT: ret i1 [[R]]940;941 %q = and i32 %x, 6942 %z = zext i8 %y to i32943 %m = mul i32 %q, %z944 %r = icmp ugt i32 %m, 1530945 ret i1 %r946}947 948; negative test - 12 * 255 = 3060 (but constant range analysis can get this)949 950define i1 @not_mul_of_pow2_commute(i32 %x, i32 %y) {951; CHECK-LABEL: @not_mul_of_pow2_commute(952; CHECK-NEXT: [[X30:%.*]] = and i32 [[X:%.*]], 12953; CHECK-NEXT: [[Y8:%.*]] = and i32 [[Y:%.*]], 255954; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Y8]], [[X30]]955; CHECK-NEXT: [[R:%.*]] = icmp samesign ugt i32 [[M]], 3060956; CHECK-NEXT: ret i1 [[R]]957;958 %x30 = and i32 %x, 12959 %y8 = and i32 %y, 255960 %m = mul i32 %y8, %x30961 %r = icmp ugt i32 %m, 3060962 ret i1 %r963}964 965; negative test - no leading zeros for 's'966; TODO: If analysis was generalized for sign bits, we could reduce this to false.967 968define i1 @mul_of_pow2_no_lz_other_op(i32 %x, i8 %y) {969; CHECK-LABEL: @mul_of_pow2_no_lz_other_op(970; CHECK-NEXT: [[B:%.*]] = and i32 [[X:%.*]], 2971; CHECK-NEXT: [[S:%.*]] = sext i8 [[Y:%.*]] to i32972; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[B]], [[S]]973; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[M]], 254974; CHECK-NEXT: ret i1 [[R]]975;976 %b = and i32 %x, 2977 %s = sext i8 %y to i32978 %m = mul nuw nsw i32 %b, %s979 %r = icmp sgt i32 %m, 254980 ret i1 %r981}982 983; The top 32-bits must be zero.984 985define i1 @splat_mul_known_lz(i32 %x) {986; CHECK-LABEL: @splat_mul_known_lz(987; CHECK-NEXT: ret i1 true988;989 %z = zext i32 %x to i128990 %m = mul i128 %z, 18446744078004518913 ; 0x00000000_00000001_00000001_00000001991 %s = lshr i128 %m, 96992 %r = icmp eq i128 %s, 0993 ret i1 %r994}995 996; The 33rd bit can only be set when MSB of x is set.997 998define i1 @splat_mul_unknown_lz(i32 %x) {999; CHECK-LABEL: @splat_mul_unknown_lz(1000; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[X:%.*]], -11001; CHECK-NEXT: ret i1 [[R]]1002;1003 %z = zext i32 %x to i1281004 %m = mul i128 %z, 18446744078004518913 ; 0x00000000_00000001_00000001_000000011005 %s = lshr i128 %m, 951006 %r = icmp eq i128 %s, 01007 ret i1 %r1008}1009 1010define i1 @mul_oddC_overflow_eq(i8 %v) {1011; CHECK-LABEL: @mul_oddC_overflow_eq(1012; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 51013; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL]], 1011014; CHECK-NEXT: ret i1 [[CMP]]1015;1016 %mul = mul i8 %v, 51017 %cmp = icmp eq i8 %mul, 1011018 ret i1 %cmp1019}1020 1021define i1 @mul_oddC_eq_nomod(i8 %v) {1022; CHECK-LABEL: @mul_oddC_eq_nomod(1023; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 31024; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL]], 341025; CHECK-NEXT: ret i1 [[CMP]]1026;1027 %mul = mul i8 %v, 31028 %cmp = icmp eq i8 %mul, 341029 ret i1 %cmp1030}1031 1032define i1 @mul_evenC_ne(i8 %v) {1033; CHECK-LABEL: @mul_evenC_ne(1034; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 61035; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[MUL]], 361036; CHECK-NEXT: ret i1 [[CMP]]1037;1038 %mul = mul i8 %v, 61039 %cmp = icmp ne i8 %mul, 361040 ret i1 %cmp1041}1042 1043define <2 x i1> @mul_oddC_ne_vec(<2 x i8> %v) {1044; CHECK-LABEL: @mul_oddC_ne_vec(1045; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[V:%.*]], splat (i8 4)1046; CHECK-NEXT: ret <2 x i1> [[CMP]]1047;1048 %mul = mul <2 x i8> %v, <i8 3, i8 3>1049 %cmp = icmp ne <2 x i8> %mul, <i8 12, i8 12>1050 ret <2 x i1> %cmp1051}1052 1053define <2 x i1> @mul_oddC_ne_nosplat_vec(<2 x i8> %v) {1054; CHECK-LABEL: @mul_oddC_ne_nosplat_vec(1055; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i8> [[V:%.*]], <i8 3, i8 5>1056; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[MUL]], <i8 12, i8 15>1057; CHECK-NEXT: ret <2 x i1> [[CMP]]1058;1059 %mul = mul <2 x i8> %v, <i8 3, i8 5>1060 %cmp = icmp ne <2 x i8> %mul, <i8 12, i8 15>1061 ret <2 x i1> %cmp1062}1063 1064define i1 @mul_nsuw_xy_z_maybe_zero_eq(i8 %x, i8 %y, i8 %z) {1065; CHECK-LABEL: @mul_nsuw_xy_z_maybe_zero_eq(1066; CHECK-NEXT: [[MULX:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Z:%.*]]1067; CHECK-NEXT: [[MULY:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[Z]]1068; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MULX]], [[MULY]]1069; CHECK-NEXT: ret i1 [[CMP]]1070;1071 %mulx = mul nsw nuw i8 %x, %z1072 %muly = mul nsw nuw i8 %y, %z1073 %cmp = icmp eq i8 %mulx, %muly1074 ret i1 %cmp1075}1076 1077define i1 @mul_xy_z_assumenozero_ne(i8 %x, i8 %y, i8 %z) {1078; CHECK-LABEL: @mul_xy_z_assumenozero_ne(1079; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[Z:%.*]], 01080; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])1081; CHECK-NEXT: [[MULX:%.*]] = mul i8 [[X:%.*]], [[Z]]1082; CHECK-NEXT: [[MULY:%.*]] = mul i8 [[Y:%.*]], [[Z]]1083; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[MULY]], [[MULX]]1084; CHECK-NEXT: ret i1 [[CMP]]1085;1086 %nz = icmp ne i8 %z, 01087 call void @llvm.assume(i1 %nz)1088 %mulx = mul i8 %x, %z1089 %muly = mul i8 %y, %z1090 %cmp = icmp ne i8 %muly, %mulx1091 ret i1 %cmp1092}1093 1094define i1 @mul_xy_z_assumeodd_eq(i8 %x, i8 %y, i8 %z) {1095; CHECK-LABEL: @mul_xy_z_assumeodd_eq(1096; CHECK-NEXT: [[LB:%.*]] = and i8 [[Z:%.*]], 11097; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[LB]], 01098; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])1099; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]1100; CHECK-NEXT: ret i1 [[CMP]]1101;1102 %lb = and i8 %z, 11103 %nz = icmp ne i8 %lb, 01104 call void @llvm.assume(i1 %nz)1105 %mulx = mul i8 %x, %z1106 %muly = mul i8 %z, %y1107 %cmp = icmp eq i8 %mulx, %muly1108 ret i1 %cmp1109}1110 1111define <2 x i1> @reused_mul_nsw_xy_z_setnonzero_vec_ne(<2 x i8> %x, <2 x i8> %y, <2 x i8> %zi) {1112; CHECK-LABEL: @reused_mul_nsw_xy_z_setnonzero_vec_ne(1113; CHECK-NEXT: [[Z:%.*]] = or <2 x i8> [[ZI:%.*]], splat (i8 4)1114; CHECK-NEXT: [[MULY:%.*]] = mul nsw <2 x i8> [[Y:%.*]], [[Z]]1115; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[Y]], [[X:%.*]]1116; CHECK-NEXT: call void @usev2xi8(<2 x i8> [[MULY]])1117; CHECK-NEXT: ret <2 x i1> [[CMP]]1118;1119 %z = or <2 x i8> %zi, <i8 4, i8 4>1120 %mulx = mul nsw <2 x i8> %z, %x1121 %muly = mul nsw <2 x i8> %y, %z1122 %cmp = icmp ne <2 x i8> %muly, %mulx1123 call void @usev2xi8(<2 x i8> %muly)1124 ret <2 x i1> %cmp1125}1126 1127define i1 @mul_mixed_nuw_nsw_xy_z_setodd_ult(i8 %x, i8 %y, i8 %zi) {1128; CHECK-LABEL: @mul_mixed_nuw_nsw_xy_z_setodd_ult(1129; CHECK-NEXT: [[Z:%.*]] = or i8 [[ZI:%.*]], 11130; CHECK-NEXT: [[MULX:%.*]] = mul nsw i8 [[X:%.*]], [[Z]]1131; CHECK-NEXT: [[MULY:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[Z]]1132; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[MULX]], [[MULY]]1133; CHECK-NEXT: ret i1 [[CMP]]1134;1135 %z = or i8 %zi, 11136 %mulx = mul nsw i8 %x, %z1137 %muly = mul nuw nsw i8 %y, %z1138 %cmp = icmp ult i8 %mulx, %muly1139 ret i1 %cmp1140}1141 1142define i1 @mul_nuw_xy_z_assumenonzero_uge(i8 %x, i8 %y, i8 %z) {1143; CHECK-LABEL: @mul_nuw_xy_z_assumenonzero_uge(1144; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[Z:%.*]], 01145; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])1146; CHECK-NEXT: [[MULX:%.*]] = mul nuw i8 [[X:%.*]], [[Z]]1147; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X]]1148; CHECK-NEXT: call void @use(i8 [[MULX]])1149; CHECK-NEXT: ret i1 [[CMP]]1150;1151 %nz = icmp ne i8 %z, 01152 call void @llvm.assume(i1 %nz)1153 %mulx = mul nuw i8 %x, %z1154 %muly = mul nuw i8 %y, %z1155 %cmp = icmp uge i8 %muly, %mulx1156 call void @use(i8 %mulx)1157 ret i1 %cmp1158}1159 1160define <2 x i1> @mul_nuw_xy_z_setnonzero_vec_eq(<2 x i8> %x, <2 x i8> %y, <2 x i8> %zi) {1161; CHECK-LABEL: @mul_nuw_xy_z_setnonzero_vec_eq(1162; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], [[Y:%.*]]1163; CHECK-NEXT: ret <2 x i1> [[CMP]]1164;1165 %z = or <2 x i8> %zi, <i8 41, i8 12>1166 %mulx = mul nuw <2 x i8> %z, %x1167 %muly = mul nuw <2 x i8> %z, %y1168 %cmp = icmp eq <2 x i8> %mulx, %muly1169 ret <2 x i1> %cmp1170}1171 1172define i1 @mul_nuw_xy_z_brnonzero_ult(i8 %x, i8 %y, i8 %z) {1173; CHECK-LABEL: @mul_nuw_xy_z_brnonzero_ult(1174; CHECK-NEXT: [[NZ_NOT:%.*]] = icmp eq i8 [[Z:%.*]], 01175; CHECK-NEXT: br i1 [[NZ_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]1176; CHECK: true:1177; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]1178; CHECK-NEXT: ret i1 [[CMP]]1179; CHECK: false:1180; CHECK-NEXT: call void @use(i8 [[Z]])1181; CHECK-NEXT: ret i1 true1182;1183 %nz = icmp ne i8 %z, 01184 br i1 %nz, label %true, label %false1185true:1186 %mulx = mul nuw i8 %x, %z1187 %muly = mul nuw i8 %y, %z1188 %cmp = icmp ult i8 %muly, %mulx1189 ret i1 %cmp1190false:1191 call void @use(i8 %z)1192 ret i1 true1193}1194 1195define i1 @reused_mul_nuw_xy_z_selectnonzero_ugt(i8 %x, i8 %y, i8 %z) {1196; CHECK-LABEL: @reused_mul_nuw_xy_z_selectnonzero_ugt(1197; CHECK-NEXT: [[NZ_NOT:%.*]] = icmp eq i8 [[Z:%.*]], 01198; CHECK-NEXT: [[MULX:%.*]] = mul nuw i8 [[X:%.*]], [[Z]]1199; CHECK-NEXT: [[MULY:%.*]] = mul nuw i8 [[Y:%.*]], [[Z]]1200; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[MULY]], [[MULX]]1201; CHECK-NEXT: [[R:%.*]] = select i1 [[NZ_NOT]], i1 true, i1 [[CMP]]1202; CHECK-NEXT: ret i1 [[R]]1203;1204 %nz = icmp ne i8 %z, 01205 %mulx = mul nuw i8 %x, %z1206 %muly = mul nuw i8 %y, %z1207 %cmp = icmp ugt i8 %muly, %mulx1208 %r = select i1 %nz, i1 %cmp, i1 true1209 ret i1 %r1210}1211 1212define <2 x i1> @mul_mixed_nsw_nuw_xy_z_setnonzero_vec_ule(<2 x i8> %x, <2 x i8> %y, <2 x i8> %zi) {1213; CHECK-LABEL: @mul_mixed_nsw_nuw_xy_z_setnonzero_vec_ule(1214; CHECK-NEXT: [[Z:%.*]] = or <2 x i8> [[ZI:%.*]], <i8 1, i8 3>1215; CHECK-NEXT: [[MULX:%.*]] = mul nuw <2 x i8> [[X:%.*]], [[Z]]1216; CHECK-NEXT: [[MULY:%.*]] = mul nsw <2 x i8> [[Z]], [[Y:%.*]]1217; CHECK-NEXT: [[CMP:%.*]] = icmp ule <2 x i8> [[MULY]], [[MULX]]1218; CHECK-NEXT: ret <2 x i1> [[CMP]]1219;1220 %z = or <2 x i8> %zi, <i8 1, i8 3>1221 %mulx = mul nuw <2 x i8> %x, %z1222 %muly = mul nsw <2 x i8> %z, %y1223 %cmp = icmp ule <2 x i8> %muly, %mulx1224 ret <2 x i1> %cmp1225}1226 1227define i1 @icmp_eq_mul_nsw_nonequal(i8 %a, i8 %c) {1228; CHECK-LABEL: @icmp_eq_mul_nsw_nonequal(1229; CHECK-NEXT: entry:1230; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C:%.*]], 01231; CHECK-NEXT: ret i1 [[CMP]]1232;1233entry:1234 %b = add i8 %a, 11235 %mul1 = mul nsw i8 %a, %c1236 %mul2 = mul nsw i8 %b, %c1237 %cmp = icmp eq i8 %mul1, %mul21238 ret i1 %cmp1239}1240 1241define i1 @icmp_eq_mul_nuw_nonequal(i8 %a, i8 %c) {1242; CHECK-LABEL: @icmp_eq_mul_nuw_nonequal(1243; CHECK-NEXT: entry:1244; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C:%.*]], 01245; CHECK-NEXT: ret i1 [[CMP]]1246;1247entry:1248 %b = add i8 %a, 11249 %mul1 = mul nuw i8 %a, %c1250 %mul2 = mul nuw i8 %b, %c1251 %cmp = icmp eq i8 %mul1, %mul21252 ret i1 %cmp1253}1254 1255define i1 @icmp_eq_mul_nsw_nonequal_commuted(i8 %a, i8 %c) {1256; CHECK-LABEL: @icmp_eq_mul_nsw_nonequal_commuted(1257; CHECK-NEXT: entry:1258; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C:%.*]], 01259; CHECK-NEXT: ret i1 [[CMP]]1260;1261entry:1262 %b = add i8 %a, 11263 %mul1 = mul nsw i8 %a, %c1264 %mul2 = mul nsw i8 %c, %b1265 %cmp = icmp eq i8 %mul1, %mul21266 ret i1 %cmp1267}1268 1269define i1 @icmp_ne_mul_nsw_nonequal(i8 %a, i8 %c) {1270; CHECK-LABEL: @icmp_ne_mul_nsw_nonequal(1271; CHECK-NEXT: entry:1272; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[C:%.*]], 01273; CHECK-NEXT: ret i1 [[CMP]]1274;1275entry:1276 %b = add i8 %a, 11277 %mul1 = mul nsw i8 %a, %c1278 %mul2 = mul nsw i8 %b, %c1279 %cmp = icmp ne i8 %mul1, %mul21280 ret i1 %cmp1281}1282 1283; Negative tests1284 1285define i1 @icmp_eq_mul_nsw_mayequal(i8 %a, i8 %b, i8 %c) {1286; CHECK-LABEL: @icmp_eq_mul_nsw_mayequal(1287; CHECK-NEXT: entry:1288; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i8 [[A:%.*]], [[C:%.*]]1289; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i8 [[B:%.*]], [[C]]1290; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL1]], [[MUL2]]1291; CHECK-NEXT: ret i1 [[CMP]]1292;1293entry:1294 %mul1 = mul nsw i8 %a, %c1295 %mul2 = mul nsw i8 %b, %c1296 %cmp = icmp eq i8 %mul1, %mul21297 ret i1 %cmp1298}1299 1300define i1 @icmp_eq_mul_nsw_nuw_nonequal(i8 %a, i8 %c) {1301; CHECK-LABEL: @icmp_eq_mul_nsw_nuw_nonequal(1302; CHECK-NEXT: entry:1303; CHECK-NEXT: [[B:%.*]] = add i8 [[A:%.*]], 11304; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i8 [[A]], [[C:%.*]]1305; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i8 [[B]], [[C]]1306; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL1]], [[MUL2]]1307; CHECK-NEXT: ret i1 [[CMP]]1308;1309entry:1310 %b = add i8 %a, 11311 %mul1 = mul nsw i8 %a, %c1312 %mul2 = mul nuw i8 %b, %c1313 %cmp = icmp eq i8 %mul1, %mul21314 ret i1 %cmp1315}1316 1317define i1 @icmp_ult_mul_nsw_nonequal(i8 %a, i8 %c) {1318; CHECK-LABEL: @icmp_ult_mul_nsw_nonequal(1319; CHECK-NEXT: entry:1320; CHECK-NEXT: [[B:%.*]] = add i8 [[A:%.*]], 11321; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i8 [[A]], [[C:%.*]]1322; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i8 [[B]], [[C]]1323; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[MUL1]], [[MUL2]]1324; CHECK-NEXT: ret i1 [[CMP]]1325;1326entry:1327 %b = add i8 %a, 11328 %mul1 = mul nsw i8 %a, %c1329 %mul2 = mul nsw i8 %b, %c1330 %cmp = icmp ult i8 %mul1, %mul21331 ret i1 %cmp1332}1333 1334define i1 @icmp_mul_nsw_slt(i8 %x, i8 %y) {1335; CHECK-LABEL: @icmp_mul_nsw_slt(1336; CHECK-NEXT: entry:1337; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]1338; CHECK-NEXT: ret i1 [[CMP]]1339;1340entry:1341 %mul1 = mul nsw i8 %x, 71342 %mul2 = mul nsw i8 %y, 71343 %cmp = icmp slt i8 %mul1, %mul21344 ret i1 %cmp1345}1346 1347define i1 @icmp_mul_nsw_sle(i8 %x, i8 %y) {1348; CHECK-LABEL: @icmp_mul_nsw_sle(1349; CHECK-NEXT: entry:1350; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]1351; CHECK-NEXT: ret i1 [[CMP]]1352;1353entry:1354 %mul1 = mul nsw i8 %x, 71355 %mul2 = mul nsw i8 %y, 71356 %cmp = icmp sle i8 %mul1, %mul21357 ret i1 %cmp1358}1359 1360define i1 @icmp_mul_nsw_sgt(i8 %x, i8 %y) {1361; CHECK-LABEL: @icmp_mul_nsw_sgt(1362; CHECK-NEXT: entry:1363; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]1364; CHECK-NEXT: ret i1 [[CMP]]1365;1366entry:1367 %mul1 = mul nsw i8 %x, 71368 %mul2 = mul nsw i8 %y, 71369 %cmp = icmp sgt i8 %mul1, %mul21370 ret i1 %cmp1371}1372 1373define i1 @icmp_mul_nsw_sge(i8 %x, i8 %y) {1374; CHECK-LABEL: @icmp_mul_nsw_sge(1375; CHECK-NEXT: entry:1376; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]1377; CHECK-NEXT: ret i1 [[CMP]]1378;1379entry:1380 %mul1 = mul nsw i8 %x, 71381 %mul2 = mul nsw i8 %y, 71382 %cmp = icmp sge i8 %mul1, %mul21383 ret i1 %cmp1384}1385 1386define i1 @icmp_mul_nsw_slt_neg(i8 %x, i8 %y) {1387; CHECK-LABEL: @icmp_mul_nsw_slt_neg(1388; CHECK-NEXT: entry:1389; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]1390; CHECK-NEXT: ret i1 [[CMP]]1391;1392entry:1393 %mul1 = mul nsw i8 %x, -71394 %mul2 = mul nsw i8 %y, -71395 %cmp = icmp slt i8 %mul1, %mul21396 ret i1 %cmp1397}1398 1399define i1 @icmp_mul_nsw_slt_neg_var(i8 %x, i8 %y, i8 %z) {1400; CHECK-LABEL: @icmp_mul_nsw_slt_neg_var(1401; CHECK-NEXT: entry:1402; CHECK-NEXT: [[COND:%.*]] = icmp slt i8 [[Z:%.*]], 01403; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])1404; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]1405; CHECK-NEXT: ret i1 [[CMP]]1406;1407entry:1408 %cond = icmp slt i8 %z, 01409 call void @llvm.assume(i1 %cond)1410 %mul1 = mul nsw i8 %x, %z1411 %mul2 = mul nsw i8 %y, %z1412 %cmp = icmp slt i8 %mul1, %mul21413 ret i1 %cmp1414}1415 1416; Negative tests1417 1418define i1 @icmp_mul_nonsw_slt(i8 %x, i8 %y) {1419; CHECK-LABEL: @icmp_mul_nonsw_slt(1420; CHECK-NEXT: entry:1421; CHECK-NEXT: [[MUL1:%.*]] = mul i8 [[X:%.*]], 71422; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i8 [[Y:%.*]], 71423; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[MUL1]], [[MUL2]]1424; CHECK-NEXT: ret i1 [[CMP]]1425;1426entry:1427 %mul1 = mul i8 %x, 71428 %mul2 = mul nsw i8 %y, 71429 %cmp = icmp slt i8 %mul1, %mul21430 ret i1 %cmp1431}1432 1433define i1 @icmp_mul_nsw_slt_unknown_sign(i8 %x, i8 %y, i8 %z) {1434; CHECK-LABEL: @icmp_mul_nsw_slt_unknown_sign(1435; CHECK-NEXT: entry:1436; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i8 [[X:%.*]], [[Z:%.*]]1437; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i8 [[Y:%.*]], [[Z]]1438; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[MUL1]], [[MUL2]]1439; CHECK-NEXT: ret i1 [[CMP]]1440;1441entry:1442 %mul1 = mul nsw i8 %x, %z1443 %mul2 = mul nsw i8 %y, %z1444 %cmp = icmp slt i8 %mul1, %mul21445 ret i1 %cmp1446}1447 1448define i1 @icmp_mul_nsw_slt_may_be_zero(i8 %x, i8 %y, i8 %z) {1449; CHECK-LABEL: @icmp_mul_nsw_slt_may_be_zero(1450; CHECK-NEXT: entry:1451; CHECK-NEXT: [[COND:%.*]] = icmp sgt i8 [[Z:%.*]], -11452; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])1453; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i8 [[X:%.*]], [[Z]]1454; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i8 [[Y:%.*]], [[Z]]1455; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[MUL1]], [[MUL2]]1456; CHECK-NEXT: ret i1 [[CMP]]1457;1458entry:1459 %cond = icmp sgt i8 %z, -11460 call void @llvm.assume(i1 %cond)1461 1462 %mul1 = mul nsw i8 %x, %z1463 %mul2 = mul nsw i8 %y, %z1464 %cmp = icmp slt i8 %mul1, %mul21465 ret i1 %cmp1466}1467 1468define i1 @test_icmp_slt_mul_known_sgt(i64 %x, i64 %z) {1469; CHECK-LABEL: @test_icmp_slt_mul_known_sgt(1470; CHECK-NEXT: entry:1471; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 01472; CHECK-NEXT: ret i1 [[CMP]]1473;1474entry:1475 %y = add nsw i64 %x, 11476 %mul1 = mul nsw i64 %x, %z1477 %mul2 = mul nsw i64 %y, %z1478 %cmp = icmp slt i64 %mul1, %mul21479 ret i1 %cmp1480}1481 1482define i1 @test_icmp_sle_mul_known_sgt(i64 %x, i64 %z) {1483; CHECK-LABEL: @test_icmp_sle_mul_known_sgt(1484; CHECK-NEXT: entry:1485; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], -11486; CHECK-NEXT: ret i1 [[CMP]]1487;1488entry:1489 %y = add nsw i64 %x, 11490 %mul1 = mul nsw i64 %x, %z1491 %mul2 = mul nsw i64 %y, %z1492 %cmp = icmp sle i64 %mul1, %mul21493 ret i1 %cmp1494}1495 1496define i1 @test_icmp_mul_known_slt(i64 %x, i64 %z) {1497; CHECK-LABEL: @test_icmp_mul_known_slt(1498; CHECK-NEXT: entry:1499; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[Z:%.*]], 01500; CHECK-NEXT: ret i1 [[CMP]]1501;1502entry:1503 %y = add nsw i64 %x, 11504 %mul1 = mul nsw i64 %x, %z1505 %mul2 = mul nsw i64 %y, %z1506 %cmp = icmp slt i64 %mul2, %mul11507 ret i1 %cmp1508}1509 1510define i1 @test_icmp_slt_mul_known_sgt_commuted1(i64 %x, i64 %z) {1511; CHECK-LABEL: @test_icmp_slt_mul_known_sgt_commuted1(1512; CHECK-NEXT: entry:1513; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 01514; CHECK-NEXT: ret i1 [[CMP]]1515;1516entry:1517 %y = add nsw i64 %x, 11518 %mul1 = mul nsw i64 %z, %x1519 %mul2 = mul nsw i64 %y, %z1520 %cmp = icmp slt i64 %mul1, %mul21521 ret i1 %cmp1522}1523 1524define i1 @test_icmp_slt_mul_known_sgt_commuted2(i64 %x, i64 %z) {1525; CHECK-LABEL: @test_icmp_slt_mul_known_sgt_commuted2(1526; CHECK-NEXT: entry:1527; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 01528; CHECK-NEXT: ret i1 [[CMP]]1529;1530entry:1531 %y = add nsw i64 %x, 11532 %mul1 = mul nsw i64 %x, %z1533 %mul2 = mul nsw i64 %z, %y1534 %cmp = icmp slt i64 %mul1, %mul21535 ret i1 %cmp1536}1537 1538define i1 @test_icmp_slt_mul_unknown(i64 %x, i64 %z) {1539; CHECK-LABEL: @test_icmp_slt_mul_unknown(1540; CHECK-NEXT: entry:1541; CHECK-NEXT: [[Y:%.*]] = add i64 [[X:%.*]], 11542; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i64 [[X]], [[Z:%.*]]1543; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i64 [[Z]], [[Y]]1544; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MUL1]], [[MUL2]]1545; CHECK-NEXT: ret i1 [[CMP]]1546;1547entry:1548 %y = add i64 %x, 11549 %mul1 = mul nsw i64 %x, %z1550 %mul2 = mul nsw i64 %z, %y1551 %cmp = icmp slt i64 %mul1, %mul21552 ret i1 %cmp1553}1554 1555define i1 @test_icmp_slt_mul_no_nsw(i64 %x, i64 %z) {1556; CHECK-LABEL: @test_icmp_slt_mul_no_nsw(1557; CHECK-NEXT: entry:1558; CHECK-NEXT: [[Y:%.*]] = add nsw i64 [[X:%.*]], 11559; CHECK-NEXT: [[MUL1:%.*]] = mul i64 [[X]], [[Z:%.*]]1560; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i64 [[Z]], [[Y]]1561; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MUL1]], [[MUL2]]1562; CHECK-NEXT: ret i1 [[CMP]]1563;1564entry:1565 %y = add nsw i64 %x, 11566 %mul1 = mul i64 %x, %z1567 %mul2 = mul nsw i64 %z, %y1568 %cmp = icmp slt i64 %mul1, %mul21569 ret i1 %cmp1570}1571