1698 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3; These should be InstSimplify checks, but most of the code4; is currently only in InstCombine. TODO: move supporting code5 6declare void @use(i8)7declare void @use_vec(<2 x i8>)8 9; Definitely out of range10define i1 @test_nonzero(ptr nocapture readonly %arg) {11; CHECK-LABEL: @test_nonzero(12; CHECK-NEXT: ret i1 true13;14 %val = load i32, ptr %arg, !range !015 %rval = icmp ne i32 %val, 016 ret i1 %rval17}18define i1 @test_nonzero2(ptr nocapture readonly %arg) {19; CHECK-LABEL: @test_nonzero2(20; CHECK-NEXT: ret i1 false21;22 %val = load i32, ptr %arg, !range !023 %rval = icmp eq i32 %val, 024 ret i1 %rval25}26 27; Potentially in range28define i1 @test_nonzero3(ptr nocapture readonly %arg) {29; CHECK-LABEL: @test_nonzero3(30; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG0:![0-9]+]]31; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i32 [[VAL]], 032; CHECK-NEXT: ret i1 [[RVAL]]33;34; Check that this does not trigger - it wouldn't be legal35 %val = load i32, ptr %arg, !range !136 %rval = icmp ne i32 %val, 037 ret i1 %rval38}39 40; Definitely in range41define i1 @test_nonzero4(ptr nocapture readonly %arg) {42; CHECK-LABEL: @test_nonzero4(43; CHECK-NEXT: ret i1 false44;45 %val = load i8, ptr %arg, !range !246 %rval = icmp ne i8 %val, 047 ret i1 %rval48}49 50define i1 @test_nonzero5(ptr nocapture readonly %arg) {51; CHECK-LABEL: @test_nonzero5(52; CHECK-NEXT: ret i1 false53;54 %val = load i8, ptr %arg, !range !255 %rval = icmp ugt i8 %val, 056 ret i1 %rval57}58 59; Cheaper checks (most values in range meet requirements)60define i1 @test_nonzero6(ptr %argw) {61; CHECK-LABEL: @test_nonzero6(62; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[ARGW:%.*]], align 1, !range [[RNG1:![0-9]+]]63; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i8 [[VAL]], 064; CHECK-NEXT: ret i1 [[RVAL]]65;66 %val = load i8, ptr %argw, !range !367 %rval = icmp sgt i8 %val, 068 ret i1 %rval69}70 71; Constant not in range, should return true.72define i1 @test_not_in_range(ptr nocapture readonly %arg) {73; CHECK-LABEL: @test_not_in_range(74; CHECK-NEXT: ret i1 true75;76 %val = load i32, ptr %arg, !range !077 %rval = icmp ne i32 %val, 678 ret i1 %rval79}80 81; Constant in range, can not fold.82define i1 @test_in_range(ptr nocapture readonly %arg) {83; CHECK-LABEL: @test_in_range(84; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG2:![0-9]+]]85; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i32 [[VAL]], 386; CHECK-NEXT: ret i1 [[RVAL]]87;88 %val = load i32, ptr %arg, !range !089 %rval = icmp ne i32 %val, 390 ret i1 %rval91}92 93; Values in range greater than constant.94define i1 @test_range_sgt_constant(ptr nocapture readonly %arg) {95; CHECK-LABEL: @test_range_sgt_constant(96; CHECK-NEXT: ret i1 true97;98 %val = load i32, ptr %arg, !range !099 %rval = icmp sgt i32 %val, 0100 ret i1 %rval101}102 103; Values in range less than constant.104define i1 @test_range_slt_constant(ptr nocapture readonly %arg) {105; CHECK-LABEL: @test_range_slt_constant(106; CHECK-NEXT: ret i1 false107;108 %val = load i32, ptr %arg, !range !0109 %rval = icmp sgt i32 %val, 6110 ret i1 %rval111}112 113; Values in union of multiple sub ranges not equal to constant.114define i1 @test_multi_range1(ptr nocapture readonly %arg) {115; CHECK-LABEL: @test_multi_range1(116; CHECK-NEXT: ret i1 true117;118 %val = load i32, ptr %arg, !range !4119 %rval = icmp ne i32 %val, 0120 ret i1 %rval121}122 123; Values in multiple sub ranges not equal to constant, but in124; union of sub ranges could possibly equal to constant. This125; in theory could also be folded and might be implemented in126; the future if shown profitable in practice.127define i1 @test_multi_range2(ptr nocapture readonly %arg) {128; CHECK-LABEL: @test_multi_range2(129; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG3:![0-9]+]]130; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i32 [[VAL]], 7131; CHECK-NEXT: ret i1 [[RVAL]]132;133 %val = load i32, ptr %arg, !range !4134 %rval = icmp ne i32 %val, 7135 ret i1 %rval136}137 138; Values' ranges overlap each other, so it can not be simplified.139define i1 @test_two_ranges(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {140; CHECK-LABEL: @test_two_ranges(141; CHECK-NEXT: [[VAL1:%.*]] = load i32, ptr [[ARG1:%.*]], align 4, !range [[RNG4:![0-9]+]]142; CHECK-NEXT: [[VAL2:%.*]] = load i32, ptr [[ARG2:%.*]], align 4, !range [[RNG5:![0-9]+]]143; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult i32 [[VAL2]], [[VAL1]]144; CHECK-NEXT: ret i1 [[RVAL]]145;146 %val1 = load i32, ptr %arg1, !range !5147 %val2 = load i32, ptr %arg2, !range !6148 %rval = icmp ult i32 %val2, %val1149 ret i1 %rval150}151 152; Values' ranges overlap each other, so it can not be simplified.153define i1 @test_two_attribute_ranges(i32 range(i32 5, 10) %arg1, i32 range(i32 8, 16) %arg2) {154; CHECK-LABEL: @test_two_attribute_ranges(155; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult i32 [[ARG2:%.*]], [[ARG1:%.*]]156; CHECK-NEXT: ret i1 [[RVAL]]157;158 %rval = icmp ult i32 %arg2, %arg1159 ret i1 %rval160}161 162; Values' ranges do not overlap each other, so it can simplified to false.163define i1 @test_two_ranges2(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {164; CHECK-LABEL: @test_two_ranges2(165; CHECK-NEXT: ret i1 false166;167 %val1 = load i32, ptr %arg1, !range !0168 %val2 = load i32, ptr %arg2, !range !6169 %rval = icmp ult i32 %val2, %val1170 ret i1 %rval171}172 173; Values' ranges do not overlap each other, so it can simplified to false.174define i1 @test_two_argument_ranges(i32 range(i32 1, 6) %arg1, i32 range(i32 8, 16) %arg2) {175; CHECK-LABEL: @test_two_argument_ranges(176; CHECK-NEXT: ret i1 false177;178 %rval = icmp ult i32 %arg2, %arg1179 ret i1 %rval180}181 182; Values' ranges do not overlap each other, so it can simplified to false.183define i1 @test_one_range_and_one_argument_range(ptr nocapture readonly %arg1, i32 range(i32 8, 16) %arg2) {184; CHECK-LABEL: @test_one_range_and_one_argument_range(185; CHECK-NEXT: ret i1 false186;187 %val1 = load i32, ptr %arg1, !range !0188 %rval = icmp ult i32 %arg2, %val1189 ret i1 %rval190}191 192; Values' ranges do not overlap each other, so it can simplified to false.193define i1 @test_one_argument_range_and_one_range(i32 range(i32 1, 6) %arg1, ptr nocapture readonly %arg2) {194; CHECK-LABEL: @test_one_argument_range_and_one_range(195; CHECK-NEXT: ret i1 false196;197 %val1 = load i32, ptr %arg2, !range !6198 %rval = icmp ult i32 %val1, %arg1199 ret i1 %rval200}201 202; Values' ranges do not overlap each other, so it can simplified to true.203define i1 @test_two_ranges3(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {204; CHECK-LABEL: @test_two_ranges3(205; CHECK-NEXT: ret i1 true206;207 %val1 = load i32, ptr %arg1, !range !0208 %val2 = load i32, ptr %arg2, !range !6209 %rval = icmp ugt i32 %val2, %val1210 ret i1 %rval211}212 213; Values' ranges overlap each other, so it can not be simplified.214define <2 x i1> @test_two_ranges_vec(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {215; CHECK-LABEL: @test_two_ranges_vec(216; CHECK-NEXT: [[VAL1:%.*]] = load <2 x i32>, ptr [[ARG1:%.*]], align 8, !range [[RNG4]]217; CHECK-NEXT: [[VAL2:%.*]] = load <2 x i32>, ptr [[ARG2:%.*]], align 8, !range [[RNG5]]218; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult <2 x i32> [[VAL2]], [[VAL1]]219; CHECK-NEXT: ret <2 x i1> [[RVAL]]220;221 %val1 = load <2 x i32>, ptr %arg1, !range !5222 %val2 = load <2 x i32>, ptr %arg2, !range !6223 %rval = icmp ult <2 x i32> %val2, %val1224 ret <2 x i1> %rval225}226 227; Values' ranges do not overlap each other, so it can simplified to false.228define <2 x i1> @test_two_ranges_vec_false(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {229; CHECK-LABEL: @test_two_ranges_vec_false(230; CHECK-NEXT: ret <2 x i1> zeroinitializer231;232 %val1 = load <2 x i32>, ptr %arg1, !range !0233 %val2 = load <2 x i32>, ptr %arg2, !range !6234 %rval = icmp ult <2 x i32> %val2, %val1235 ret <2 x i1> %rval236}237 238; Values' ranges do not overlap each other, so it can simplified to true.239define <2 x i1> @test_two_ranges_vec_true(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {240; CHECK-LABEL: @test_two_ranges_vec_true(241; CHECK-NEXT: ret <2 x i1> splat (i1 true)242;243 %val1 = load <2 x i32>, ptr %arg1, !range !0244 %val2 = load <2 x i32>, ptr %arg2, !range !6245 %rval = icmp ugt <2 x i32> %val2, %val1246 ret <2 x i1> %rval247}248 249; Values' ranges overlap each other, so it can not be simplified.250define <2 x i1> @test_two_argument_ranges_vec(<2 x i32> range(i32 5, 10) %arg1, <2 x i32> range(i32 8, 16) %arg2) {251; CHECK-LABEL: @test_two_argument_ranges_vec(252; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult <2 x i32> [[ARG2:%.*]], [[ARG1:%.*]]253; CHECK-NEXT: ret <2 x i1> [[RVAL]]254;255 %rval = icmp ult <2 x i32> %arg2, %arg1256 ret <2 x i1> %rval257}258 259; Values' ranges do not overlap each other, so it can simplified to false.260define <2 x i1> @test_two_argument_ranges_vec_false(<2 x i32> range(i32 1, 6) %arg1, <2 x i32> range(i32 8, 16) %arg2) {261; CHECK-LABEL: @test_two_argument_ranges_vec_false(262; CHECK-NEXT: ret <2 x i1> zeroinitializer263;264 %rval = icmp ult <2 x i32> %arg2, %arg1265 ret <2 x i1> %rval266}267 268; Values' ranges do not overlap each other, so it can simplified to true.269define <2 x i1> @test_two_argument_ranges_vec_true(<2 x i32> range(i32 1, 6) %arg1, <2 x i32> range(i32 8, 16) %arg2) {270; CHECK-LABEL: @test_two_argument_ranges_vec_true(271; CHECK-NEXT: ret <2 x i1> splat (i1 true)272;273 %rval = icmp ugt <2 x i32> %arg2, %arg1274 ret <2 x i1> %rval275}276 277declare i32 @create_range1()278declare range(i32 8, 16) i32 @create_range2()279declare range(i32 1, 6) i32 @create_range3()280 281; Values' ranges overlap each other, so it can not be simplified.282define i1 @test_two_return_attribute_ranges_not_simplified() {283; CHECK-LABEL: @test_two_return_attribute_ranges_not_simplified(284; CHECK-NEXT: [[VAL1:%.*]] = call range(i32 5, 10) i32 @create_range1()285; CHECK-NEXT: [[VAL2:%.*]] = call i32 @create_range2()286; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult i32 [[VAL2]], [[VAL1]]287; CHECK-NEXT: ret i1 [[RVAL]]288;289 %val1 = call range(i32 5, 10) i32 @create_range1()290 %val2 = call i32 @create_range2()291 %rval = icmp ult i32 %val2, %val1292 ret i1 %rval293}294 295; Values' ranges do not overlap each other, so it can simplified to false.296define i1 @test_two_return_attribute_ranges_one_in_call() {297; CHECK-LABEL: @test_two_return_attribute_ranges_one_in_call(298; CHECK-NEXT: [[VAL1:%.*]] = call range(i32 1, 6) i32 @create_range1()299; CHECK-NEXT: [[VAL2:%.*]] = call i32 @create_range2()300; CHECK-NEXT: ret i1 false301;302 %val1 = call range(i32 1, 6) i32 @create_range1()303 %val2 = call i32 @create_range2()304 %rval = icmp ult i32 %val2, %val1305 ret i1 %rval306}307 308; Values' ranges do not overlap each other, so it can simplified to false.309define i1 @test_two_return_attribute_ranges() {310; CHECK-LABEL: @test_two_return_attribute_ranges(311; CHECK-NEXT: [[VAL1:%.*]] = call i32 @create_range3()312; CHECK-NEXT: [[VAL2:%.*]] = call i32 @create_range2()313; CHECK-NEXT: ret i1 false314;315 %val1 = call i32 @create_range3()316 %val2 = call i32 @create_range2()317 %rval = icmp ult i32 %val2, %val1318 ret i1 %rval319}320 321; Values' ranges do not overlap each other, so it can simplified to false.322define i1 @test_one_return_argument_and_one_argument_range(i32 range(i32 8, 16) %arg1) {323; CHECK-LABEL: @test_one_return_argument_and_one_argument_range(324; CHECK-NEXT: [[VAL1:%.*]] = call i32 @create_range3()325; CHECK-NEXT: ret i1 false326;327 %val1 = call i32 @create_range3()328 %rval = icmp ult i32 %arg1, %val1329 ret i1 %rval330}331 332; Values' ranges do not overlap each other, so it can simplified to false.333define i1 @test_one_range_and_one_return_argument(ptr nocapture readonly %arg1) {334; CHECK-LABEL: @test_one_range_and_one_return_argument(335; CHECK-NEXT: [[VAL1:%.*]] = call i32 @create_range3()336; CHECK-NEXT: ret i1 false337;338 %val1 = call i32 @create_range3()339 %val2 = load i32, ptr %arg1, !range !6340 %rval = icmp ult i32 %val2, %val1341 ret i1 %rval342}343 344define i1 @ugt_zext(i1 %b, i8 %x) {345; CHECK-LABEL: @ugt_zext(346; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0347; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]348; CHECK-NEXT: ret i1 [[R]]349;350 %z = zext i1 %b to i8351 %r = icmp ugt i8 %z, %x352 ret i1 %r353}354 355define <2 x i1> @ult_zext(<2 x i1> %b, <2 x i8> %p) {356; CHECK-LABEL: @ult_zext(357; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]358; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer359; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[TMP1]], [[B:%.*]]360; CHECK-NEXT: ret <2 x i1> [[R]]361;362 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization363 %z = zext <2 x i1> %b to <2 x i8>364 %r = icmp ult <2 x i8> %x, %z365 ret <2 x i1> %r366}367 368; negative test - need ult/ugt369 370define i1 @uge_zext(i1 %b, i8 %x) {371; CHECK-LABEL: @uge_zext(372; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8373; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X:%.*]], [[Z]]374; CHECK-NEXT: ret i1 [[R]]375;376 %z = zext i1 %b to i8377 %r = icmp uge i8 %z, %x378 ret i1 %r379}380 381; negative test - need ult/ugt382 383define i1 @ule_zext(i1 %b, i8 %p) {384; CHECK-LABEL: @ule_zext(385; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]386; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8387; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[Z]]388; CHECK-NEXT: ret i1 [[R]]389;390 %x = mul i8 %p, %p ; thwart complexity-based canonicalization391 %z = zext i1 %b to i8392 %r = icmp ule i8 %x, %z393 ret i1 %r394}395 396; negative test - extra use397 398define i1 @ugt_zext_use(i1 %b, i8 %x) {399; CHECK-LABEL: @ugt_zext_use(400; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8401; CHECK-NEXT: call void @use(i8 [[Z]])402; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[Z]]403; CHECK-NEXT: ret i1 [[R]]404;405 %z = zext i1 %b to i8406 call void @use(i8 %z)407 %r = icmp ugt i8 %z, %x408 ret i1 %r409}410 411; negative test - must be zext of i1412 413define i1 @ult_zext_not_i1(i2 %b, i8 %x) {414; CHECK-LABEL: @ult_zext_not_i1(415; CHECK-NEXT: [[Z:%.*]] = zext i2 [[B:%.*]] to i8416; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[Z]]417; CHECK-NEXT: ret i1 [[R]]418;419 %z = zext i2 %b to i8420 %r = icmp ult i8 %x, %z421 ret i1 %r422}423 424; sub is eliminated425 426define i1 @sub_ult_zext(i1 %b, i8 %x, i8 %y) {427; CHECK-LABEL: @sub_ult_zext(428; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]429; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]430; CHECK-NEXT: ret i1 [[R]]431;432 %z = zext i1 %b to i8433 %s = sub i8 %x, %y434 %r = icmp ult i8 %s, %z435 ret i1 %r436}437 438define i1 @zext_ult_zext(i1 %b, i8 %p) {439; CHECK-LABEL: @zext_ult_zext(440; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]441; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X]], 0442; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]443; CHECK-NEXT: ret i1 [[R]]444;445 %x = mul i8 %p, %p ; thwart complexity-based canonicalization446 %z = zext i1 %b to i16447 %zx = zext i8 %x to i16448 %r = icmp ult i16 %zx, %z449 ret i1 %r450}451 452; match and fold even if both sides are zexts (from different source types)453 454define i1 @zext_ugt_zext(i1 %b, i4 %x) {455; CHECK-LABEL: @zext_ugt_zext(456; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i8457; CHECK-NEXT: call void @use(i8 [[ZX]])458; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i4 [[X]], 0459; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]460; CHECK-NEXT: ret i1 [[R]]461;462 %z = zext i1 %b to i8463 %zx = zext i4 %x to i8464 call void @use(i8 %zx)465 %r = icmp ugt i8 %z, %zx466 ret i1 %r467}468 469; negative test - must be zext of i1470 471define i1 @sub_ult_zext_not_i1(i2 %b, i8 %x, i8 %y) {472; CHECK-LABEL: @sub_ult_zext_not_i1(473; CHECK-NEXT: [[Z:%.*]] = zext i2 [[B:%.*]] to i8474; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]475; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[S]], [[Z]]476; CHECK-NEXT: ret i1 [[R]]477;478 %z = zext i2 %b to i8479 %s = sub i8 %x, %y480 %r = icmp ult i8 %s, %z481 ret i1 %r482}483 484; negative test - extra use (but we could try harder to fold this)485 486define i1 @sub_ult_zext_use1(i1 %b, i8 %x, i8 %y) {487; CHECK-LABEL: @sub_ult_zext_use1(488; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8489; CHECK-NEXT: call void @use(i8 [[Z]])490; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]491; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[S]], [[Z]]492; CHECK-NEXT: ret i1 [[R]]493;494 %z = zext i1 %b to i8495 call void @use(i8 %z)496 %s = sub i8 %x, %y497 %r = icmp ult i8 %s, %z498 ret i1 %r499}500 501define <2 x i1> @zext_ugt_sub_use2(<2 x i1> %b, <2 x i8> %x, <2 x i8> %y) {502; CHECK-LABEL: @zext_ugt_sub_use2(503; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]504; CHECK-NEXT: call void @use_vec(<2 x i8> [[S]])505; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], [[Y]]506; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[TMP1]], [[B:%.*]]507; CHECK-NEXT: ret <2 x i1> [[R]]508;509 %z = zext <2 x i1> %b to <2 x i8>510 %s = sub <2 x i8> %x, %y511 call void @use_vec(<2 x i8> %s)512 %r = icmp ugt <2 x i8> %z, %s513 ret <2 x i1> %r514}515 516define i1 @sub_ult_zext_use3(i1 %b, i8 %x, i8 %y) {517; CHECK-LABEL: @sub_ult_zext_use3(518; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8519; CHECK-NEXT: call void @use(i8 [[Z]])520; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]521; CHECK-NEXT: call void @use(i8 [[S]])522; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[S]], [[Z]]523; CHECK-NEXT: ret i1 [[R]]524;525 %z = zext i1 %b to i8526 call void @use(i8 %z)527 %s = sub i8 %x, %y528 call void @use(i8 %s)529 %r = icmp ult i8 %s, %z530 ret i1 %r531}532 533define i1 @sub_ule_zext(i1 %b, i8 %x, i8 %y) {534; CHECK-LABEL: @sub_ule_zext(535; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8536; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]537; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[S]], [[Z]]538; CHECK-NEXT: ret i1 [[R]]539;540 %z = zext i1 %b to i8541 %s = sub i8 %x, %y542 %r = icmp ule i8 %s, %z543 ret i1 %r544}545 546define <2 x i1> @sub_ult_and(<2 x i8> %b, <2 x i8> %x, <2 x i8> %y) {547; CHECK-LABEL: @sub_ult_and(548; CHECK-NEXT: [[A:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 1)549; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]550; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[S]], [[A]]551; CHECK-NEXT: ret <2 x i1> [[R]]552;553 %a = and <2 x i8> %b, <i8 1, i8 1>554 %s = sub <2 x i8> %x, %y555 %r = icmp ult <2 x i8> %s, %a556 ret <2 x i1> %r557}558 559define i1 @and_ugt_sub(i8 %b, i8 %x, i8 %y) {560; CHECK-LABEL: @and_ugt_sub(561; CHECK-NEXT: [[A:%.*]] = and i8 [[B:%.*]], 1562; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]563; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[A]], [[S]]564; CHECK-NEXT: ret i1 [[R]]565;566 %a = and i8 %b, 1567 %s = sub i8 %x, %y568 %r = icmp ugt i8 %a, %s569 ret i1 %r570}571 572; Repeat the zext set of tests with a sext instead.573 574define i1 @uge_sext(i1 %b, i8 %x) {575; CHECK-LABEL: @uge_sext(576; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0577; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]578; CHECK-NEXT: ret i1 [[R]]579;580 %s = sext i1 %b to i8581 %r = icmp uge i8 %s, %x582 ret i1 %r583}584 585define <2 x i1> @ule_sext(<2 x i1> %b, <2 x i8> %p) {586; CHECK-LABEL: @ule_sext(587; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]588; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer589; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]]590; CHECK-NEXT: ret <2 x i1> [[R]]591;592 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization593 %s = sext <2 x i1> %b to <2 x i8>594 %r = icmp ule <2 x i8> %x, %s595 ret <2 x i1> %r596}597 598; negative test - need ule/uge599 600define i1 @ugt_sext(i1 %b, i8 %x) {601; CHECK-LABEL: @ugt_sext(602; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8603; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[S]]604; CHECK-NEXT: ret i1 [[R]]605;606 %s = sext i1 %b to i8607 %r = icmp ugt i8 %s, %x608 ret i1 %r609}610 611; negative test - need ule/uge612 613define i1 @ult_sext(i1 %b, i8 %p) {614; CHECK-LABEL: @ult_sext(615; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]616; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8617; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X]], [[S]]618; CHECK-NEXT: ret i1 [[R]]619;620 %x = mul i8 %p, %p ; thwart complexity-based canonicalization621 %s = sext i1 %b to i8622 %r = icmp ult i8 %x, %s623 ret i1 %r624}625 626; negative test - extra use627 628define i1 @uge_sext_use(i1 %b, i8 %x) {629; CHECK-LABEL: @uge_sext_use(630; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8631; CHECK-NEXT: call void @use(i8 [[S]])632; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X:%.*]], [[S]]633; CHECK-NEXT: ret i1 [[R]]634;635 %s = sext i1 %b to i8636 call void @use(i8 %s)637 %r = icmp uge i8 %s, %x638 ret i1 %r639}640 641; negative test - must be sext of i1642 643define i1 @ule_sext_not_i1(i2 %b, i8 %x) {644; CHECK-LABEL: @ule_sext_not_i1(645; CHECK-NEXT: [[S:%.*]] = sext i2 [[B:%.*]] to i8646; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X:%.*]], [[S]]647; CHECK-NEXT: ret i1 [[R]]648;649 %s = sext i2 %b to i8650 %r = icmp ule i8 %x, %s651 ret i1 %r652}653 654; sub is eliminated655 656define i1 @sub_ule_sext(i1 %b, i8 %x, i8 %y) {657; CHECK-LABEL: @sub_ule_sext(658; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]659; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]660; CHECK-NEXT: ret i1 [[R]]661;662 %s = sext i1 %b to i8663 %d = sub i8 %x, %y664 %r = icmp ule i8 %d, %s665 ret i1 %r666}667 668define i1 @sext_ule_sext(i1 %b, i8 %p) {669; CHECK-LABEL: @sext_ule_sext(670; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]671; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X]], 0672; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]673; CHECK-NEXT: ret i1 [[R]]674;675 %x = mul i8 %p, %p ; thwart complexity-based canonicalization676 %s = sext i1 %b to i16677 %sx = sext i8 %x to i16678 %r = icmp ule i16 %sx, %s679 ret i1 %r680}681 682; match and fold even if both sides are sexts (from different source types)683 684define i1 @sext_uge_sext(i1 %b, i4 %x) {685; CHECK-LABEL: @sext_uge_sext(686; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i8687; CHECK-NEXT: call void @use(i8 [[SX]])688; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i4 [[X]], 0689; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]690; CHECK-NEXT: ret i1 [[R]]691;692 %s = sext i1 %b to i8693 %sx = sext i4 %x to i8694 call void @use(i8 %sx)695 %r = icmp uge i8 %s, %sx696 ret i1 %r697}698 699; negative test - must be sext of i1700 701define i1 @sub_ule_sext_not_i1(i2 %b, i8 %x, i8 %y) {702; CHECK-LABEL: @sub_ule_sext_not_i1(703; CHECK-NEXT: [[S:%.*]] = sext i2 [[B:%.*]] to i8704; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]705; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[D]], [[S]]706; CHECK-NEXT: ret i1 [[R]]707;708 %s = sext i2 %b to i8709 %d = sub i8 %x, %y710 %r = icmp ule i8 %d, %s711 ret i1 %r712}713 714; negative test - extra use (but we could try harder to fold this)715 716define i1 @sub_ule_sext_use1(i1 %b, i8 %x, i8 %y) {717; CHECK-LABEL: @sub_ule_sext_use1(718; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8719; CHECK-NEXT: call void @use(i8 [[S]])720; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]721; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[D]], [[S]]722; CHECK-NEXT: ret i1 [[R]]723;724 %s = sext i1 %b to i8725 call void @use(i8 %s)726 %d = sub i8 %x, %y727 %r = icmp ule i8 %d, %s728 ret i1 %r729}730 731define <2 x i1> @sext_uge_sub_use2(<2 x i1> %b, <2 x i8> %x, <2 x i8> %y) {732; CHECK-LABEL: @sext_uge_sub_use2(733; CHECK-NEXT: [[D:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]734; CHECK-NEXT: call void @use_vec(<2 x i8> [[D]])735; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], [[Y]]736; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]]737; CHECK-NEXT: ret <2 x i1> [[R]]738;739 %s = sext <2 x i1> %b to <2 x i8>740 %d = sub <2 x i8> %x, %y741 call void @use_vec(<2 x i8> %d)742 %r = icmp uge <2 x i8> %s, %d743 ret <2 x i1> %r744}745 746define i1 @sub_ule_sext_use3(i1 %b, i8 %x, i8 %y) {747; CHECK-LABEL: @sub_ule_sext_use3(748; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8749; CHECK-NEXT: call void @use(i8 [[S]])750; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]751; CHECK-NEXT: call void @use(i8 [[D]])752; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[D]], [[S]]753; CHECK-NEXT: ret i1 [[R]]754;755 %s = sext i1 %b to i8756 call void @use(i8 %s)757 %d = sub i8 %x, %y758 call void @use(i8 %d)759 %r = icmp ule i8 %d, %s760 ret i1 %r761}762 763define i1 @sub_ult_sext(i1 %b, i8 %x, i8 %y) {764; CHECK-LABEL: @sub_ult_sext(765; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8766; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]767; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[D]], [[S]]768; CHECK-NEXT: ret i1 [[R]]769;770 %s = sext i1 %b to i8771 %d = sub i8 %x, %y772 %r = icmp ult i8 %d, %s773 ret i1 %r774}775 776define <2 x i1> @sub_ule_ashr(<2 x i8> %b, <2 x i8> %x, <2 x i8> %y) {777; CHECK-LABEL: @sub_ule_ashr(778; CHECK-NEXT: [[A:%.*]] = ashr <2 x i8> [[B:%.*]], splat (i8 7)779; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]780; CHECK-NEXT: [[R:%.*]] = icmp ule <2 x i8> [[S]], [[A]]781; CHECK-NEXT: ret <2 x i1> [[R]]782;783 %a = ashr <2 x i8> %b, <i8 7, i8 7>784 %s = sub <2 x i8> %x, %y785 %r = icmp ule <2 x i8> %s, %a786 ret <2 x i1> %r787}788 789define i1 @ashr_uge_sub(i8 %b, i8 %x, i8 %y) {790; CHECK-LABEL: @ashr_uge_sub(791; CHECK-NEXT: [[A:%.*]] = ashr i8 [[B:%.*]], 7792; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]793; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[A]], [[S]]794; CHECK-NEXT: ret i1 [[R]]795;796 %a = ashr i8 %b, 7797 %s = sub i8 %x, %y798 %r = icmp uge i8 %a, %s799 ret i1 %r800}801 802; (zext i1 a) + (sext i1 b)) s< -1 --> false803 804define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) {805; CHECK-LABEL: @zext_sext_add_icmp_slt_minus1(806; CHECK-NEXT: ret i1 false807;808 %zext.a = zext i1 %a to i8809 %sext.b = sext i1 %b to i8810 %add = add i8 %zext.a, %sext.b811 %r = icmp slt i8 %add, -1812 ret i1 %r813}814 815; (zext i1 a) + (sext i1 b)) s> 1 --> false816 817define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) {818; CHECK-LABEL: @zext_sext_add_icmp_sgt_1(819; CHECK-NEXT: ret i1 false820;821 %zext.a = zext i1 %a to i8822 %sext.b = sext i1 %b to i8823 %add = add i8 %zext.a, %sext.b824 %r = icmp sgt i8 %add, 1825 ret i1 %r826}827 828; (zext i1 a) + (sext i1 b)) s> -2 --> true829 830define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) {831; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus2(832; CHECK-NEXT: ret i1 true833;834 %zext.a = zext i1 %a to i8835 %sext.b = sext i1 %b to i8836 %add = add i8 %zext.a, %sext.b837 %r = icmp sgt i8 %add, -2838 ret i1 %r839}840 841; (zext i1 a) + (sext i1 b)) s< 2 --> true842 843define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) {844; CHECK-LABEL: @zext_sext_add_icmp_slt_2(845; CHECK-NEXT: ret i1 true846;847 %zext.a = zext i1 %a to i8848 %sext.b = sext i1 %b to i8849 %add = add i8 %zext.a, %sext.b850 %r = icmp slt i8 %add, 2851 ret i1 %r852}853 854; test case with i128855 856define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) {857; CHECK-LABEL: @zext_sext_add_icmp_i128(858; CHECK-NEXT: ret i1 false859;860 %zext.a = zext i1 %a to i128861 %sext.b = sext i1 %b to i128862 %add = add i128 %zext.a, %sext.b863 %r = icmp sgt i128 %add, 9223372036854775808864 ret i1 %r865}866 867; (zext i1 a) + (sext i1 b)) == -1 --> ~a & b868 869define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) {870; CHECK-LABEL: @zext_sext_add_icmp_eq_minus1(871; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true872; CHECK-NEXT: [[R:%.*]] = and i1 [[B:%.*]], [[TMP1]]873; CHECK-NEXT: ret i1 [[R]]874;875 %zext.a = zext i1 %a to i8876 %sext.b = sext i1 %b to i8877 %add = add i8 %zext.a, %sext.b878 %r = icmp eq i8 %add, -1879 ret i1 %r880}881 882 883; (zext i1 a) + (sext i1 b)) != -1 --> a | ~b884 885define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) {886; CHECK-LABEL: @zext_sext_add_icmp_ne_minus1(887; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true888; CHECK-NEXT: [[R:%.*]] = or i1 [[A:%.*]], [[TMP1]]889; CHECK-NEXT: ret i1 [[R]]890;891 %zext.a = zext i1 %a to i8892 %sext.b = sext i1 %b to i8893 %add = add i8 %zext.a, %sext.b894 %r = icmp ne i8 %add, -1895 ret i1 %r896}897 898; (zext i1 a) + (sext i1 b)) s> -1 --> a | ~b899 900define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) {901; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus1(902; CHECK-NEXT: [[B_NOT:%.*]] = xor i1 [[B:%.*]], true903; CHECK-NEXT: [[R:%.*]] = or i1 [[A:%.*]], [[B_NOT]]904; CHECK-NEXT: ret i1 [[R]]905;906 %zext.a = zext i1 %a to i8907 %sext.b = sext i1 %b to i8908 %add = add i8 %zext.a, %sext.b909 %r = icmp sgt i8 %add, -1910 ret i1 %r911}912 913; (zext i1 a) + (sext i1 b)) u< -1 --> a | ~b914 915define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) {916; CHECK-LABEL: @zext_sext_add_icmp_ult_minus1(917; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true918; CHECK-NEXT: [[R:%.*]] = or i1 [[A:%.*]], [[TMP1]]919; CHECK-NEXT: ret i1 [[R]]920;921 %zext.a = zext i1 %a to i8922 %sext.b = sext i1 %b to i8923 %add = add i8 %zext.a, %sext.b924 %r = icmp ult i8 %add, -1925 ret i1 %r926}927 928; (zext i1 a) + (sext i1 b)) s> 0 --> a & ~b929 930define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) {931; CHECK-LABEL: @zext_sext_add_icmp_sgt_0(932; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true933; CHECK-NEXT: [[R:%.*]] = and i1 [[A:%.*]], [[TMP1]]934; CHECK-NEXT: ret i1 [[R]]935;936 %zext.a = zext i1 %a to i8937 %sext.b = sext i1 %b to i8938 %add = add i8 %zext.a, %sext.b939 %r = icmp sgt i8 %add, 0940 ret i1 %r941}942 943; (zext i1 a) + (sext i1 b)) s< 0 --> ~a & b944 945define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) {946; CHECK-LABEL: @zext_sext_add_icmp_slt_0(947; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true948; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[B:%.*]], [[TMP1]]949; CHECK-NEXT: ret i1 [[TMP2]]950;951 %zext.a = zext i1 %a to i8952 %sext.b = sext i1 %b to i8953 %add = add i8 %zext.a, %sext.b954 %r = icmp slt i8 %add, 0955 ret i1 %r956}957 958; (zext i1 a) + (sext i1 b)) == 1 --> a & ~b959 960define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) {961; CHECK-LABEL: @zext_sext_add_icmp_eq_1(962; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true963; CHECK-NEXT: [[R:%.*]] = and i1 [[A:%.*]], [[TMP1]]964; CHECK-NEXT: ret i1 [[R]]965;966 %zext.a = zext i1 %a to i8967 %sext.b = sext i1 %b to i8968 %add = add i8 %zext.a, %sext.b969 %r = icmp eq i8 %add, 1970 ret i1 %r971}972 973; (zext i1 a) + (sext i1 b)) != 1 --> ~a | b974 975define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) {976; CHECK-LABEL: @zext_sext_add_icmp_ne_1(977; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true978; CHECK-NEXT: [[R:%.*]] = or i1 [[B:%.*]], [[TMP1]]979; CHECK-NEXT: ret i1 [[R]]980;981 %zext.a = zext i1 %a to i8982 %sext.b = sext i1 %b to i8983 %add = add i8 %zext.a, %sext.b984 %r = icmp ne i8 %add, 1985 ret i1 %r986}987 988; (zext i1 a) + (sext i1 b)) s< 1 --> ~a | b989 990define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) {991; CHECK-LABEL: @zext_sext_add_icmp_slt_1(992; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true993; CHECK-NEXT: [[R:%.*]] = or i1 [[B:%.*]], [[TMP1]]994; CHECK-NEXT: ret i1 [[R]]995;996 %zext.a = zext i1 %a to i8997 %sext.b = sext i1 %b to i8998 %add = add i8 %zext.a, %sext.b999 %r = icmp slt i8 %add, 11000 ret i1 %r1001}1002 1003; (zext i1 a) + (sext i1 b)) u> 1 --> ~a & b1004 1005define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) {1006; CHECK-LABEL: @zext_sext_add_icmp_ugt_1(1007; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true1008; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[B:%.*]], [[TMP1]]1009; CHECK-NEXT: ret i1 [[TMP2]]1010;1011 %zext.a = zext i1 %a to i81012 %sext.b = sext i1 %b to i81013 %add = add i8 %zext.a, %sext.b1014 %r = icmp ugt i8 %add, 11015 ret i1 %r1016}1017 1018define <2 x i1> @vector_zext_sext_add_icmp_slt_1(<2 x i1> %a, <2 x i1> %b) {1019; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1(1020; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)1021; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[B:%.*]], [[TMP1]]1022; CHECK-NEXT: ret <2 x i1> [[R]]1023;1024 %zext.a = zext <2 x i1> %a to <2 x i8>1025 %sext.b = sext <2 x i1> %b to <2 x i8>1026 %add = add <2 x i8> %zext.a, %sext.b1027 %r = icmp slt <2 x i8> %add, <i8 1, i8 1>1028 ret <2 x i1> %r1029}1030 1031define <2 x i1> @vector_zext_sext_add_icmp_slt_1_poison(<2 x i1> %a, <2 x i1> %b) {1032; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1_poison(1033; CHECK-NEXT: [[ZEXT_A:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i8>1034; CHECK-NEXT: [[SEXT_B:%.*]] = sext <2 x i1> [[B:%.*]] to <2 x i8>1035; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[ZEXT_A]], [[SEXT_B]]1036; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i8> [[ADD]], <i8 1, i8 poison>1037; CHECK-NEXT: ret <2 x i1> [[R]]1038;1039 %zext.a = zext <2 x i1> %a to <2 x i8>1040 %sext.b = sext <2 x i1> %b to <2 x i8>1041 %add = add <2 x i8> %zext.a, %sext.b1042 %r = icmp slt <2 x i8> %add, <i8 1, i8 poison>1043 ret <2 x i1> %r1044}1045 1046define i1 @zext_sext_add_icmp_slt_minus_1_no_oneuse(i1 %a, i1 %b) {1047; CHECK-LABEL: @zext_sext_add_icmp_slt_minus_1_no_oneuse(1048; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i81049; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81050; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1051; CHECK-NEXT: call void @use(i8 [[ADD]])1052; CHECK-NEXT: ret i1 false1053;1054 %zext.a = zext i1 %a to i81055 %sext.b = sext i1 %b to i81056 %add = add i8 %zext.a, %sext.b1057 call void @use(i8 %add)1058 %r = icmp slt i8 %add, -11059 ret i1 %r1060}1061 1062define i1 @zext_sext_add_icmp_sgt_1_no_oneuse(i1 %a, i1 %b) {1063; CHECK-LABEL: @zext_sext_add_icmp_sgt_1_no_oneuse(1064; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i81065; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81066; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1067; CHECK-NEXT: call void @use(i8 [[ADD]])1068; CHECK-NEXT: ret i1 false1069;1070 %zext.a = zext i1 %a to i81071 %sext.b = sext i1 %b to i81072 %add = add i8 %zext.a, %sext.b1073 call void @use(i8 %add)1074 %r = icmp sgt i8 %add, 11075 ret i1 %r1076}1077 1078define i1 @zext_sext_add_icmp_slt_2_no_oneuse(i1 %a, i1 %b) {1079; CHECK-LABEL: @zext_sext_add_icmp_slt_2_no_oneuse(1080; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i81081; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81082; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1083; CHECK-NEXT: call void @use(i8 [[ADD]])1084; CHECK-NEXT: ret i1 true1085;1086 %zext.a = zext i1 %a to i81087 %sext.b = sext i1 %b to i81088 %add = add i8 %zext.a, %sext.b1089 call void @use(i8 %add)1090 %r = icmp slt i8 %add, 21091 ret i1 %r1092}1093 1094define i1 @zext_sext_add_icmp_sgt_mins_2_no_oneuse(i1 %a, i1 %b) {1095; CHECK-LABEL: @zext_sext_add_icmp_sgt_mins_2_no_oneuse(1096; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i81097; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81098; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1099; CHECK-NEXT: call void @use(i8 [[ADD]])1100; CHECK-NEXT: ret i1 true1101;1102 %zext.a = zext i1 %a to i81103 %sext.b = sext i1 %b to i81104 %add = add i8 %zext.a, %sext.b1105 call void @use(i8 %add)1106 %r = icmp sgt i8 %add, -21107 ret i1 %r1108}1109 1110; Negative test, more than one use for icmp LHS1111 1112define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) {1113; CHECK-LABEL: @zext_sext_add_icmp_slt_1_no_oneuse(1114; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i81115; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81116; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1117; CHECK-NEXT: call void @use(i8 [[ADD]])1118; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 11119; CHECK-NEXT: ret i1 [[R]]1120;1121 %zext.a = zext i1 %a to i81122 %sext.b = sext i1 %b to i81123 %add = add i8 %zext.a, %sext.b1124 call void @use(i8 %add)1125 %r = icmp slt i8 %add, 11126 ret i1 %r1127}1128 1129; Negative test, icmp RHS is not a constant1130 1131define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) {1132; CHECK-LABEL: @zext_sext_add_icmp_slt_1_rhs_not_const(1133; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i81134; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81135; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1136; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], [[C:%.*]]1137; CHECK-NEXT: ret i1 [[R]]1138;1139 %zext.a = zext i1 %a to i81140 %sext.b = sext i1 %b to i81141 %add = add i8 %zext.a, %sext.b1142 %r = icmp slt i8 %add, %c1143 ret i1 %r1144}1145 1146; Negative test, ext source is not i11147 1148define i1 @zext_sext_add_icmp_slt_1_type_not_i1(i2 %a, i1 %b) {1149; CHECK-LABEL: @zext_sext_add_icmp_slt_1_type_not_i1(1150; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i2 [[A:%.*]] to i81151; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i81152; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]1153; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 11154; CHECK-NEXT: ret i1 [[R]]1155;1156 %zext.a = zext i2 %a to i81157 %sext.b = sext i1 %b to i81158 %add = add i8 %zext.a, %sext.b1159 %r = icmp slt i8 %add, 11160 ret i1 %r1161}1162 1163define i1 @icmp_eq_bool_0(ptr %ptr) {1164; CHECK-LABEL: @icmp_eq_bool_0(1165; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6:![0-9]+]]1166; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 01167; CHECK-NEXT: ret i1 [[CMP]]1168;1169 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}1170 %cmp = icmp eq i64 %val, 01171 ret i1 %cmp1172}1173 1174define i1 @icmp_eq_bool_1(ptr %ptr) {1175; CHECK-LABEL: @icmp_eq_bool_1(1176; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]1177; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 01178; CHECK-NEXT: ret i1 [[CMP]]1179;1180 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}1181 %cmp = icmp eq i64 %val, 11182 ret i1 %cmp1183}1184 1185define i1 @icmp_ne_bool_0(ptr %ptr) {1186; CHECK-LABEL: @icmp_ne_bool_0(1187; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]1188; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 01189; CHECK-NEXT: ret i1 [[CMP]]1190;1191 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}1192 %cmp = icmp ne i64 %val, 01193 ret i1 %cmp1194}1195 1196define i1 @icmp_ne_bool_1(ptr %ptr) {1197; CHECK-LABEL: @icmp_ne_bool_1(1198; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]1199; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 01200; CHECK-NEXT: ret i1 [[CMP]]1201;1202 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}1203 %cmp = icmp ne i64 %val, 11204 ret i1 %cmp1205}1206 1207; Tests from PR650731208define i1 @icmp_ne_zext_eq_zero(i32 %a) {1209; CHECK-LABEL: @icmp_ne_zext_eq_zero(1210; CHECK-NEXT: ret i1 true1211;1212 %cmp = icmp eq i32 %a, 01213 %conv = zext i1 %cmp to i321214 %cmp1 = icmp ne i32 %conv, %a1215 ret i1 %cmp11216}1217 1218define i1 @icmp_ne_zext_ne_zero(i32 %a) {1219; CHECK-LABEL: @icmp_ne_zext_ne_zero(1220; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 11221; CHECK-NEXT: ret i1 [[CMP1]]1222;1223 %cmp = icmp ne i32 %a, 01224 %conv = zext i1 %cmp to i321225 %cmp1 = icmp ne i32 %conv, %a1226 ret i1 %cmp11227}1228 1229define i1 @icmp_eq_zext_eq_zero(i32 %a) {1230; CHECK-LABEL: @icmp_eq_zext_eq_zero(1231; CHECK-NEXT: ret i1 false1232;1233 %cmp = icmp eq i32 %a, 01234 %conv = zext i1 %cmp to i321235 %cmp1 = icmp eq i32 %conv, %a1236 ret i1 %cmp11237}1238 1239define i1 @icmp_eq_zext_ne_zero(i32 %a) {1240; CHECK-LABEL: @icmp_eq_zext_ne_zero(1241; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 21242; CHECK-NEXT: ret i1 [[CMP1]]1243;1244 %cmp = icmp ne i32 %a, 01245 %conv = zext i1 %cmp to i321246 %cmp1 = icmp eq i32 %conv, %a1247 ret i1 %cmp11248}1249 1250define i1 @icmp_ne_zext_eq_one(i32 %a) {1251; CHECK-LABEL: @icmp_ne_zext_eq_one(1252; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 11253; CHECK-NEXT: ret i1 [[CMP1]]1254;1255 %cmp = icmp eq i32 %a, 11256 %conv = zext i1 %cmp to i321257 %cmp1 = icmp ne i32 %conv, %a1258 ret i1 %cmp11259}1260 1261define i1 @icmp_ne_zext_ne_one(i32 %a) {1262; CHECK-LABEL: @icmp_ne_zext_ne_one(1263; CHECK-NEXT: ret i1 true1264;1265 %cmp = icmp ne i32 %a, 11266 %conv = zext i1 %cmp to i321267 %cmp1 = icmp ne i32 %conv, %a1268 ret i1 %cmp11269}1270 1271define i1 @icmp_eq_zext_eq_one(i32 %a) {1272; CHECK-LABEL: @icmp_eq_zext_eq_one(1273; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 21274; CHECK-NEXT: ret i1 [[CMP1]]1275;1276 %cmp = icmp eq i32 %a, 11277 %conv = zext i1 %cmp to i321278 %cmp1 = icmp eq i32 %conv, %a1279 ret i1 %cmp11280}1281 1282define i1 @icmp_eq_zext_ne_one(i32 %a) {1283; CHECK-LABEL: @icmp_eq_zext_ne_one(1284; CHECK-NEXT: ret i1 false1285;1286 %cmp = icmp ne i32 %a, 11287 %conv = zext i1 %cmp to i321288 %cmp1 = icmp eq i32 %conv, %a1289 ret i1 %cmp11290}1291 1292define i1 @icmp_ne_zext_eq_non_boolean(i32 %a) {1293; CHECK-LABEL: @icmp_ne_zext_eq_non_boolean(1294; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 01295; CHECK-NEXT: ret i1 [[CMP1]]1296;1297 %cmp = icmp eq i32 %a, 21298 %conv = zext i1 %cmp to i321299 %cmp1 = icmp ne i32 %conv, %a1300 ret i1 %cmp11301}1302 1303define i1 @icmp_ne_zext_ne_non_boolean(i32 %a) {1304; CHECK-LABEL: @icmp_ne_zext_ne_non_boolean(1305; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 11306; CHECK-NEXT: ret i1 [[CMP1]]1307;1308 %cmp = icmp ne i32 %a, 21309 %conv = zext i1 %cmp to i321310 %cmp1 = icmp ne i32 %conv, %a1311 ret i1 %cmp11312}1313 1314define i1 @icmp_eq_zext_eq_non_boolean(i32 %a) {1315; CHECK-LABEL: @icmp_eq_zext_eq_non_boolean(1316; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 01317; CHECK-NEXT: ret i1 [[CMP1]]1318;1319 %cmp = icmp eq i32 %a, 21320 %conv = zext i1 %cmp to i321321 %cmp1 = icmp eq i32 %conv, %a1322 ret i1 %cmp11323}1324 1325define i1 @icmp_eq_zext_ne_non_boolean(i32 %a) {1326; CHECK-LABEL: @icmp_eq_zext_ne_non_boolean(1327; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 11328; CHECK-NEXT: ret i1 [[CMP1]]1329;1330 %cmp = icmp ne i32 %a, 21331 %conv = zext i1 %cmp to i321332 %cmp1 = icmp eq i32 %conv, %a1333 ret i1 %cmp11334}1335 1336define <2 x i1> @icmp_ne_zext_eq_zero_vec(<2 x i32> %a) {1337; CHECK-LABEL: @icmp_ne_zext_eq_zero_vec(1338; CHECK-NEXT: ret <2 x i1> splat (i1 true)1339;1340 %cmp = icmp eq <2 x i32> %a, <i32 0, i32 0>1341 %conv = zext <2 x i1> %cmp to <2 x i32>1342 %cmp1 = icmp ne <2 x i32> %conv, %a1343 ret <2 x i1> %cmp11344}1345 1346define <2 x i1> @icmp_ne_zext_ne_zero_vec(<2 x i32> %a) {1347; CHECK-LABEL: @icmp_ne_zext_ne_zero_vec(1348; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 1)1349; CHECK-NEXT: ret <2 x i1> [[CMP1]]1350;1351 %cmp = icmp ne <2 x i32> %a, <i32 0, i32 0>1352 %conv = zext <2 x i1> %cmp to <2 x i32>1353 %cmp1 = icmp ne <2 x i32> %conv, %a1354 ret <2 x i1> %cmp11355}1356 1357define <2 x i1> @icmp_ne_zext_eq_one_vec(<2 x i32> %a) {1358; CHECK-LABEL: @icmp_ne_zext_eq_one_vec(1359; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 1)1360; CHECK-NEXT: ret <2 x i1> [[CMP1]]1361;1362 %cmp = icmp eq <2 x i32> %a, <i32 1, i32 1>1363 %conv = zext <2 x i1> %cmp to <2 x i32>1364 %cmp1 = icmp ne <2 x i32> %conv, %a1365 ret <2 x i1> %cmp11366}1367 1368define <2 x i1> @icmp_ne_zext_ne_one_vec(<2 x i32> %a) {1369; CHECK-LABEL: @icmp_ne_zext_ne_one_vec(1370; CHECK-NEXT: ret <2 x i1> splat (i1 true)1371;1372 %cmp = icmp ne <2 x i32> %a, <i32 1, i32 1>1373 %conv = zext <2 x i1> %cmp to <2 x i32>1374 %cmp1 = icmp ne <2 x i32> %conv, %a1375 ret <2 x i1> %cmp11376}1377 1378define <2 x i1> @icmp_ne_zext_eq_non_boolean_vec(<2 x i32> %a) {1379; CHECK-LABEL: @icmp_ne_zext_eq_non_boolean_vec(1380; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], zeroinitializer1381; CHECK-NEXT: ret <2 x i1> [[CMP1]]1382;1383 %cmp = icmp eq <2 x i32> %a, <i32 2, i32 2>1384 %conv = zext <2 x i1> %cmp to <2 x i32>1385 %cmp1 = icmp ne <2 x i32> %conv, %a1386 ret <2 x i1> %cmp11387}1388 1389define i1 @icmp_ne_sext_eq_zero(i32 %a) {1390; CHECK-LABEL: @icmp_ne_sext_eq_zero(1391; CHECK-NEXT: ret i1 true1392;1393 %cmp = icmp eq i32 %a, 01394 %conv = sext i1 %cmp to i321395 %cmp1 = icmp ne i32 %conv, %a1396 ret i1 %cmp11397}1398 1399define i1 @icmp_ne_sext_ne_zero(i32 %a) {1400; CHECK-LABEL: @icmp_ne_sext_ne_zero(1401; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -11402; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], -21403; CHECK-NEXT: ret i1 [[CMP1]]1404;1405 %cmp = icmp ne i32 %a, 01406 %conv = sext i1 %cmp to i321407 %cmp1 = icmp ne i32 %conv, %a1408 ret i1 %cmp11409}1410 1411define i1 @icmp_eq_sext_eq_zero(i32 %a) {1412; CHECK-LABEL: @icmp_eq_sext_eq_zero(1413; CHECK-NEXT: ret i1 false1414;1415 %cmp = icmp eq i32 %a, 01416 %conv = sext i1 %cmp to i321417 %cmp1 = icmp eq i32 %conv, %a1418 ret i1 %cmp11419}1420 1421define i1 @icmp_eq_sext_ne_zero(i32 %a) {1422; CHECK-LABEL: @icmp_eq_sext_ne_zero(1423; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], 11424; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], 21425; CHECK-NEXT: ret i1 [[CMP1]]1426;1427 %cmp = icmp ne i32 %a, 01428 %conv = sext i1 %cmp to i321429 %cmp1 = icmp eq i32 %conv, %a1430 ret i1 %cmp11431}1432 1433define i1 @icmp_ne_sext_eq_allones(i32 %a) {1434; CHECK-LABEL: @icmp_ne_sext_eq_allones(1435; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -11436; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], -21437; CHECK-NEXT: ret i1 [[CMP1]]1438;1439 %cmp = icmp eq i32 %a, -11440 %conv = sext i1 %cmp to i321441 %cmp1 = icmp ne i32 %conv, %a1442 ret i1 %cmp11443}1444 1445define i1 @icmp_ne_sext_ne_allones(i32 %a) {1446; CHECK-LABEL: @icmp_ne_sext_ne_allones(1447; CHECK-NEXT: ret i1 true1448;1449 %cmp = icmp ne i32 %a, -11450 %conv = sext i1 %cmp to i321451 %cmp1 = icmp ne i32 %conv, %a1452 ret i1 %cmp11453}1454 1455define i1 @icmp_eq_sext_eq_allones(i32 %a) {1456; CHECK-LABEL: @icmp_eq_sext_eq_allones(1457; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], 11458; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], 21459; CHECK-NEXT: ret i1 [[CMP1]]1460;1461 %cmp = icmp eq i32 %a, -11462 %conv = sext i1 %cmp to i321463 %cmp1 = icmp eq i32 %conv, %a1464 ret i1 %cmp11465}1466 1467define i1 @icmp_eq_sext_ne_allones(i32 %a) {1468; CHECK-LABEL: @icmp_eq_sext_ne_allones(1469; CHECK-NEXT: ret i1 false1470;1471 %cmp = icmp ne i32 %a, -11472 %conv = sext i1 %cmp to i321473 %cmp1 = icmp eq i32 %conv, %a1474 ret i1 %cmp11475}1476 1477define i1 @icmp_ne_sext_eq_otherwise(i32 %a) {1478; CHECK-LABEL: @icmp_ne_sext_eq_otherwise(1479; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 01480; CHECK-NEXT: ret i1 [[CMP1]]1481;1482 %cmp = icmp eq i32 %a, 21483 %conv = sext i1 %cmp to i321484 %cmp1 = icmp ne i32 %conv, %a1485 ret i1 %cmp11486}1487 1488define i1 @icmp_ne_sext_ne_otherwise(i32 %a) {1489; CHECK-LABEL: @icmp_ne_sext_ne_otherwise(1490; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], -11491; CHECK-NEXT: ret i1 [[CMP1]]1492;1493 %cmp = icmp ne i32 %a, 21494 %conv = sext i1 %cmp to i321495 %cmp1 = icmp ne i32 %conv, %a1496 ret i1 %cmp11497}1498 1499define i1 @icmp_eq_sext_eq_otherwise(i32 %a) {1500; CHECK-LABEL: @icmp_eq_sext_eq_otherwise(1501; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 01502; CHECK-NEXT: ret i1 [[CMP1]]1503;1504 %cmp = icmp eq i32 %a, 21505 %conv = sext i1 %cmp to i321506 %cmp1 = icmp eq i32 %conv, %a1507 ret i1 %cmp11508}1509 1510define i1 @icmp_eq_sext_ne_otherwise(i32 %a) {1511; CHECK-LABEL: @icmp_eq_sext_ne_otherwise(1512; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], -11513; CHECK-NEXT: ret i1 [[CMP1]]1514;1515 %cmp = icmp ne i32 %a, 21516 %conv = sext i1 %cmp to i321517 %cmp1 = icmp eq i32 %conv, %a1518 ret i1 %cmp11519}1520 1521define <2 x i1> @icmp_ne_sext_eq_zero_vec(<2 x i32> %a) {1522; CHECK-LABEL: @icmp_ne_sext_eq_zero_vec(1523; CHECK-NEXT: ret <2 x i1> splat (i1 true)1524;1525 %cmp = icmp eq <2 x i32> %a, <i32 0, i32 0>1526 %conv = sext <2 x i1> %cmp to <2 x i32>1527 %cmp1 = icmp ne <2 x i32> %conv, %a1528 ret <2 x i1> %cmp11529}1530 1531define <2 x i1> @icmp_ne_sext_ne_zero_vec(<2 x i32> %a) {1532; CHECK-LABEL: @icmp_ne_sext_ne_zero_vec(1533; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -1)1534; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2)1535; CHECK-NEXT: ret <2 x i1> [[CMP1]]1536;1537 %cmp = icmp ne <2 x i32> %a, <i32 0, i32 0>1538 %conv = sext <2 x i1> %cmp to <2 x i32>1539 %cmp1 = icmp ne <2 x i32> %conv, %a1540 ret <2 x i1> %cmp11541}1542 1543define <2 x i1> @icmp_ne_sext_eq_allones_vec(<2 x i32> %a) {1544; CHECK-LABEL: @icmp_ne_sext_eq_allones_vec(1545; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -1)1546; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2)1547; CHECK-NEXT: ret <2 x i1> [[CMP1]]1548;1549 %cmp = icmp eq <2 x i32> %a, <i32 -1, i32 -1>1550 %conv = sext <2 x i1> %cmp to <2 x i32>1551 %cmp1 = icmp ne <2 x i32> %conv, %a1552 ret <2 x i1> %cmp11553}1554 1555define <2 x i1> @icmp_ne_sext_ne_allones_vec(<2 x i32> %a) {1556; CHECK-LABEL: @icmp_ne_sext_ne_allones_vec(1557; CHECK-NEXT: ret <2 x i1> splat (i1 true)1558;1559 %cmp = icmp ne <2 x i32> %a, <i32 -1, i32 -1>1560 %conv = sext <2 x i1> %cmp to <2 x i32>1561 %cmp1 = icmp ne <2 x i32> %conv, %a1562 ret <2 x i1> %cmp11563}1564 1565define <2 x i1> @icmp_ne_sext_eq_otherwise_vec(<2 x i32> %a) {1566; CHECK-LABEL: @icmp_ne_sext_eq_otherwise_vec(1567; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], zeroinitializer1568; CHECK-NEXT: ret <2 x i1> [[CMP1]]1569;1570 %cmp = icmp eq <2 x i32> %a, <i32 2, i32 2>1571 %conv = sext <2 x i1> %cmp to <2 x i32>1572 %cmp1 = icmp ne <2 x i32> %conv, %a1573 ret <2 x i1> %cmp11574}1575 1576define i1 @icmp_ne_sext_ne_zero_i128(i128 %a) {1577; CHECK-LABEL: @icmp_ne_sext_ne_zero_i128(1578; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[A:%.*]], -11579; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i128 [[TMP1]], -21580; CHECK-NEXT: ret i1 [[CMP1]]1581;1582 %cmp = icmp ne i128 %a, 01583 %conv = sext i1 %cmp to i1281584 %cmp1 = icmp ne i128 %conv, %a1585 ret i1 %cmp11586}1587 1588define i1 @icmp_ne_sext_ne_otherwise_i128(i128 %a) {1589; CHECK-LABEL: @icmp_ne_sext_ne_otherwise_i128(1590; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i128 [[A:%.*]], -11591; CHECK-NEXT: ret i1 [[CMP1]]1592;1593 %cmp = icmp ne i128 %a, 21594 %conv = sext i1 %cmp to i1281595 %cmp1 = icmp ne i128 %conv, %a1596 ret i1 %cmp11597}1598 1599; Negative tests with non-equality predicates1600define i1 @icmp_ne_sext_sgt_zero_nofold(i32 %a) {1601; CHECK-LABEL: @icmp_ne_sext_sgt_zero_nofold(1602; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 01603; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i321604; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]]1605; CHECK-NEXT: ret i1 [[CMP1]]1606;1607 %cmp = icmp sgt i32 %a, 01608 %conv = sext i1 %cmp to i321609 %cmp1 = icmp ne i32 %conv, %a1610 ret i1 %cmp11611}1612 1613define i1 @icmp_slt_sext_ne_zero_nofold(i32 %a) {1614; CHECK-LABEL: @icmp_slt_sext_ne_zero_nofold(1615; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], 01616; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i321617; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]]1618; CHECK-NEXT: ret i1 [[CMP1]]1619;1620 %cmp = icmp ne i32 %a, 01621 %conv = sext i1 %cmp to i321622 %cmp1 = icmp slt i32 %conv, %a1623 ret i1 %cmp11624}1625 1626define i1 @icmp_ne_sext_slt_allones_nofold(i32 %a) {1627; CHECK-LABEL: @icmp_ne_sext_slt_allones_nofold(1628; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], -11629; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i321630; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]]1631; CHECK-NEXT: ret i1 [[CMP1]]1632;1633 %cmp = icmp slt i32 %a, -11634 %conv = sext i1 %cmp to i321635 %cmp1 = icmp ne i32 %conv, %a1636 ret i1 %cmp11637}1638 1639define i1 @icmp_slt_sext_ne_allones_nofold(i32 %a) {1640; CHECK-LABEL: @icmp_slt_sext_ne_allones_nofold(1641; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], -11642; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i321643; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]]1644; CHECK-NEXT: ret i1 [[CMP1]]1645;1646 %cmp = icmp ne i32 %a, -11647 %conv = sext i1 %cmp to i321648 %cmp1 = icmp slt i32 %conv, %a1649 ret i1 %cmp11650}1651 1652define i1 @icmp_ne_sext_slt_otherwise_nofold(i32 %a) {1653; CHECK-LABEL: @icmp_ne_sext_slt_otherwise_nofold(1654; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 21655; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i321656; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]]1657; CHECK-NEXT: ret i1 [[CMP1]]1658;1659 %cmp = icmp slt i32 %a, 21660 %conv = sext i1 %cmp to i321661 %cmp1 = icmp ne i32 %conv, %a1662 ret i1 %cmp11663}1664 1665define i1 @icmp_slt_sext_ne_otherwise_nofold(i32 %a) {1666; CHECK-LABEL: @icmp_slt_sext_ne_otherwise_nofold(1667; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], 21668; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i321669; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]]1670; CHECK-NEXT: ret i1 [[CMP1]]1671;1672 %cmp = icmp ne i32 %a, 21673 %conv = sext i1 %cmp to i321674 %cmp1 = icmp slt i32 %conv, %a1675 ret i1 %cmp11676}1677 1678; tests from PR595551679define i1 @isFloat(i64 %0) {1680; CHECK-LABEL: @isFloat(1681; CHECK-NEXT: [[TMP5:%.*]] = icmp ugt i64 [[TMP0:%.*]], 5629499534213111682; CHECK-NEXT: ret i1 [[TMP5]]1683;1684 %2 = icmp ugt i64 %0, 2814749767106551685 %3 = and i64 %0, -2814749767106561686 %4 = icmp ne i64 %3, 2814749767106561687 %5 = and i1 %2, %41688 ret i1 %51689}1690 1691!0 = !{i32 1, i32 6}1692!1 = !{i32 0, i32 6}1693!2 = !{i8 0, i8 1}1694!3 = !{i8 0, i8 6}1695!4 = !{i32 1, i32 6, i32 8, i32 10}1696!5 = !{i32 5, i32 10}1697!6 = !{i32 8, i32 16}1698