6243 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"5 6declare i8 @llvm.abs.i8(i8, i1)7 8declare void @use_i1(i1)9declare void @use_i8(i8)10declare void @use_i32(i32)11declare void @use_i64(i64)12 13define i32 @test1(i32 %X) {14; CHECK-LABEL: define i32 @test1(15; CHECK-SAME: i32 [[X:%.*]]) {16; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X]], 3117; CHECK-NEXT: ret i32 [[X_LOBIT]]18;19 %a = icmp slt i32 %X, 020 %b = zext i1 %a to i3221 ret i32 %b22}23 24define <2 x i32> @test1vec(<2 x i32> %X) {25; CHECK-LABEL: define <2 x i32> @test1vec(26; CHECK-SAME: <2 x i32> [[X:%.*]]) {27; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X]], splat (i32 31)28; CHECK-NEXT: ret <2 x i32> [[X_LOBIT]]29;30 %a = icmp slt <2 x i32> %X, zeroinitializer31 %b = zext <2 x i1> %a to <2 x i32>32 ret <2 x i32> %b33}34 35define i32 @test2(i32 %X) {36; CHECK-LABEL: define i32 @test2(37; CHECK-SAME: i32 [[X:%.*]]) {38; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X]], -139; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i3240; CHECK-NEXT: ret i32 [[B]]41;42 %a = icmp ult i32 %X, -214748364843 %b = zext i1 %a to i3244 ret i32 %b45}46 47define <2 x i32> @test2vec(<2 x i32> %X) {48; CHECK-LABEL: define <2 x i32> @test2vec(49; CHECK-SAME: <2 x i32> [[X:%.*]]) {50; CHECK-NEXT: [[A:%.*]] = icmp sgt <2 x i32> [[X]], splat (i32 -1)51; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>52; CHECK-NEXT: ret <2 x i32> [[B]]53;54 %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>55 %b = zext <2 x i1> %a to <2 x i32>56 ret <2 x i32> %b57}58 59define i32 @test3(i32 %X) {60; CHECK-LABEL: define i32 @test3(61; CHECK-SAME: i32 [[X:%.*]]) {62; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X]], 3163; CHECK-NEXT: ret i32 [[X_LOBIT]]64;65 %a = icmp slt i32 %X, 066 %b = sext i1 %a to i3267 ret i32 %b68}69 70define i32 @test4(i32 %X) {71; CHECK-LABEL: define i32 @test4(72; CHECK-SAME: i32 [[X:%.*]]) {73; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X]], -174; CHECK-NEXT: [[B:%.*]] = sext i1 [[A]] to i3275; CHECK-NEXT: ret i32 [[B]]76;77 %a = icmp ult i32 %X, -214748364878 %b = sext i1 %a to i3279 ret i32 %b80}81 82; PR483783define <2 x i1> @test5_eq(<2 x i64> %x) {84; CHECK-LABEL: define <2 x i1> @test5_eq(85; CHECK-SAME: <2 x i64> [[X:%.*]]) {86; CHECK-NEXT: ret <2 x i1> undef87;88 %V = icmp eq <2 x i64> %x, undef89 ret <2 x i1> %V90}91define <2 x i1> @test5_ne(<2 x i64> %x) {92; CHECK-LABEL: define <2 x i1> @test5_ne(93; CHECK-SAME: <2 x i64> [[X:%.*]]) {94; CHECK-NEXT: ret <2 x i1> undef95;96 %V = icmp ne <2 x i64> %x, undef97 ret <2 x i1> %V98}99define <2 x i1> @test5_ugt(<2 x i64> %x) {100; CHECK-LABEL: define <2 x i1> @test5_ugt(101; CHECK-SAME: <2 x i64> [[X:%.*]]) {102; CHECK-NEXT: ret <2 x i1> zeroinitializer103;104 %V = icmp ugt <2 x i64> %x, undef105 ret <2 x i1> %V106}107define <2 x i1> @test5_zero() {108; CHECK-LABEL: define <2 x i1> @test5_zero() {109; CHECK-NEXT: ret <2 x i1> undef110;111 %V = icmp eq <2 x i64> zeroinitializer, undef112 ret <2 x i1> %V113}114 115define i32 @test6(i32 %a, i32 %b) {116; CHECK-LABEL: define i32 @test6(117; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {118; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[A]], 0119; CHECK-NEXT: [[F:%.*]] = select i1 [[ISNEG]], i32 [[B]], i32 0120; CHECK-NEXT: ret i32 [[F]]121;122 %c = icmp sle i32 %a, -1123 %d = zext i1 %c to i32124 %e = sub i32 0, %d125 %f = and i32 %e, %b126 ret i32 %f127}128 129 130define i1 @test7(i32 %x) {131; CHECK-LABEL: define i1 @test7(132; CHECK-SAME: i32 [[X:%.*]]) {133; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X]], 0134; CHECK-NEXT: ret i1 [[B]]135;136 %a = add i32 %x, -1137 %b = icmp ult i32 %a, %x138 ret i1 %b139}140 141define <2 x i1> @test7_vec(<2 x i32> %x) {142; CHECK-LABEL: define <2 x i1> @test7_vec(143; CHECK-SAME: <2 x i32> [[X:%.*]]) {144; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X]], zeroinitializer145; CHECK-NEXT: ret <2 x i1> [[B]]146;147 %a = add <2 x i32> %x, <i32 -1, i32 -1>148 %b = icmp ult <2 x i32> %a, %x149 ret <2 x i1> %b150}151 152define i1 @test8(i32 %x) {153; CHECK-LABEL: define i1 @test8(154; CHECK-SAME: i32 [[X:%.*]]) {155; CHECK-NEXT: ret i1 false156;157 %a = add i32 %x, -1158 %b = icmp eq i32 %a, %x159 ret i1 %b160}161 162define <2 x i1> @test8_vec(<2 x i32> %x) {163; CHECK-LABEL: define <2 x i1> @test8_vec(164; CHECK-SAME: <2 x i32> [[X:%.*]]) {165; CHECK-NEXT: ret <2 x i1> zeroinitializer166;167 %a = add <2 x i32> %x, <i32 -1, i32 -1>168 %b = icmp eq <2 x i32> %a, %x169 ret <2 x i1> %b170}171 172define i1 @test9(i32 %x) {173; CHECK-LABEL: define i1 @test9(174; CHECK-SAME: i32 [[X:%.*]]) {175; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 [[X]], 1176; CHECK-NEXT: ret i1 [[B]]177;178 %a = add i32 %x, -2179 %b = icmp ugt i32 %x, %a180 ret i1 %b181}182 183define <2 x i1> @test9_vec(<2 x i32> %x) {184; CHECK-LABEL: define <2 x i1> @test9_vec(185; CHECK-SAME: <2 x i32> [[X:%.*]]) {186; CHECK-NEXT: [[B:%.*]] = icmp ugt <2 x i32> [[X]], splat (i32 1)187; CHECK-NEXT: ret <2 x i1> [[B]]188;189 %a = add <2 x i32> %x, <i32 -2, i32 -2>190 %b = icmp ugt <2 x i32> %x, %a191 ret <2 x i1> %b192}193 194define i1 @test9b(i32 %x) {195; CHECK-LABEL: define i1 @test9b(196; CHECK-SAME: i32 [[X:%.*]]) {197; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X]], 2198; CHECK-NEXT: ret i1 [[B]]199;200 %a = add i32 %x, -2201 %b = icmp ugt i32 %a, %x202 ret i1 %b203}204 205define <2 x i1> @test9b_vec(<2 x i32> %x) {206; CHECK-LABEL: define <2 x i1> @test9b_vec(207; CHECK-SAME: <2 x i32> [[X:%.*]]) {208; CHECK-NEXT: [[B:%.*]] = icmp ult <2 x i32> [[X]], splat (i32 2)209; CHECK-NEXT: ret <2 x i1> [[B]]210;211 %a = add <2 x i32> %x, <i32 -2, i32 -2>212 %b = icmp ugt <2 x i32> %a, %x213 ret <2 x i1> %b214}215 216define i1 @test10(i32 %x) {217; CHECK-LABEL: define i1 @test10(218; CHECK-SAME: i32 [[X:%.*]]) {219; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X]], -2147483648220; CHECK-NEXT: ret i1 [[B]]221;222 %a = add i32 %x, -1223 %b = icmp slt i32 %a, %x224 ret i1 %b225}226 227define <2 x i1> @test10_vec(<2 x i32> %x) {228; CHECK-LABEL: define <2 x i1> @test10_vec(229; CHECK-SAME: <2 x i32> [[X:%.*]]) {230; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X]], splat (i32 -2147483648)231; CHECK-NEXT: ret <2 x i1> [[B]]232;233 %a = add <2 x i32> %x, <i32 -1, i32 -1>234 %b = icmp slt <2 x i32> %a, %x235 ret <2 x i1> %b236}237 238define i1 @test10b(i32 %x) {239; CHECK-LABEL: define i1 @test10b(240; CHECK-SAME: i32 [[X:%.*]]) {241; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X]], -2147483648242; CHECK-NEXT: ret i1 [[B]]243;244 %a = add i32 %x, -1245 %b = icmp sgt i32 %a, %x246 ret i1 %b247}248 249define <2 x i1> @test10b_vec(<2 x i32> %x) {250; CHECK-LABEL: define <2 x i1> @test10b_vec(251; CHECK-SAME: <2 x i32> [[X:%.*]]) {252; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X]], splat (i32 -2147483648)253; CHECK-NEXT: ret <2 x i1> [[B]]254;255 %a = add <2 x i32> %x, <i32 -1, i32 -1>256 %b = icmp sgt <2 x i32> %a, %x257 ret <2 x i1> %b258}259 260define i1 @test11(i32 %x) {261; CHECK-LABEL: define i1 @test11(262; CHECK-SAME: i32 [[X:%.*]]) {263; CHECK-NEXT: ret i1 true264;265 %a = add nsw i32 %x, 8266 %b = icmp slt i32 %x, %a267 ret i1 %b268}269 270define <2 x i1> @test11_vec(<2 x i32> %x) {271; CHECK-LABEL: define <2 x i1> @test11_vec(272; CHECK-SAME: <2 x i32> [[X:%.*]]) {273; CHECK-NEXT: ret <2 x i1> splat (i1 true)274;275 %a = add nsw <2 x i32> %x, <i32 8, i32 8>276 %b = icmp slt <2 x i32> %x, %a277 ret <2 x i1> %b278}279 280; PR6195281define i1 @test12(i1 %A) {282; CHECK-LABEL: define i1 @test12(283; CHECK-SAME: i1 [[A:%.*]]) {284; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A]], true285; CHECK-NEXT: ret i1 [[NOT_A]]286;287 %S = select i1 %A, i64 -4294967295, i64 8589934591288 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S289 ret i1 %B290}291 292; PR6481293define i1 @test13(i8 %X) {294; CHECK-LABEL: define i1 @test13(295; CHECK-SAME: i8 [[X:%.*]]) {296; CHECK-NEXT: ret i1 false297;298 %cmp = icmp slt i8 undef, %X299 ret i1 %cmp300}301 302define i1 @test14(i8 %X) {303; CHECK-LABEL: define i1 @test14(304; CHECK-SAME: i8 [[X:%.*]]) {305; CHECK-NEXT: ret i1 false306;307 %cmp = icmp slt i8 undef, -128308 ret i1 %cmp309}310 311define i1 @test15() {312; CHECK-LABEL: define i1 @test15() {313; CHECK-NEXT: ret i1 undef314;315 %cmp = icmp eq i8 undef, -128316 ret i1 %cmp317}318 319define i1 @test16() {320; CHECK-LABEL: define i1 @test16() {321; CHECK-NEXT: ret i1 undef322;323 %cmp = icmp ne i8 undef, -128324 ret i1 %cmp325}326 327define i1 @test17(i32 %x) {328; CHECK-LABEL: define i1 @test17(329; CHECK-SAME: i32 [[X:%.*]]) {330; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], 3331; CHECK-NEXT: ret i1 [[TMP1]]332;333 %shl = shl i32 1, %x334 %and = and i32 %shl, 8335 %cmp = icmp eq i32 %and, 0336 ret i1 %cmp337}338 339define <2 x i1> @test17vec(<2 x i32> %x) {340; CHECK-LABEL: define <2 x i1> @test17vec(341; CHECK-SAME: <2 x i32> [[X:%.*]]) {342; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X]], splat (i32 3)343; CHECK-NEXT: ret <2 x i1> [[TMP1]]344;345 %shl = shl <2 x i32> <i32 1, i32 1>, %x346 %and = and <2 x i32> %shl, <i32 8, i32 8>347 %cmp = icmp eq <2 x i32> %and, zeroinitializer348 ret <2 x i1> %cmp349}350 351define i1 @test17a(i32 %x) {352; CHECK-LABEL: define i1 @test17a(353; CHECK-SAME: i32 [[X:%.*]]) {354; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], 2355; CHECK-NEXT: ret i1 [[CMP]]356;357 %shl = shl i32 1, %x358 %and = and i32 %shl, 7359 %cmp = icmp eq i32 %and, 0360 ret i1 %cmp361}362 363define <2 x i1> @test17a_vec(<2 x i32> %x) {364; CHECK-LABEL: define <2 x i1> @test17a_vec(365; CHECK-SAME: <2 x i32> [[X:%.*]]) {366; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X]], splat (i32 2)367; CHECK-NEXT: ret <2 x i1> [[CMP]]368;369 %shl = shl <2 x i32> <i32 1, i32 1>, %x370 %and = and <2 x i32> %shl, <i32 7, i32 7>371 %cmp = icmp eq <2 x i32> %and, zeroinitializer372 ret <2 x i1> %cmp373}374 375define i1 @test18_eq(i32 %x) {376; CHECK-LABEL: define i1 @test18_eq(377; CHECK-SAME: i32 [[X:%.*]]) {378; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], 3379; CHECK-NEXT: ret i1 [[TMP1]]380;381 %sh = lshr i32 8, %x382 %and = and i32 %sh, 1383 %cmp = icmp eq i32 %and, 0384 ret i1 %cmp385}386 387define <2 x i1> @test18_eq_vec(<2 x i32> %x) {388; CHECK-LABEL: define <2 x i1> @test18_eq_vec(389; CHECK-SAME: <2 x i32> [[X:%.*]]) {390; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X]], splat (i32 3)391; CHECK-NEXT: ret <2 x i1> [[TMP1]]392;393 %sh = lshr <2 x i32> <i32 8, i32 8>, %x394 %and = and <2 x i32> %sh, <i32 1, i32 1>395 %cmp = icmp eq <2 x i32> %and, zeroinitializer396 ret <2 x i1> %cmp397}398 399define i1 @test18_ne(i32 %x) {400; CHECK-LABEL: define i1 @test18_ne(401; CHECK-SAME: i32 [[X:%.*]]) {402; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 3403; CHECK-NEXT: ret i1 [[TMP1]]404;405 %sh = lshr i32 8, %x406 %and = and i32 %sh, 1407 %cmp = icmp ne i32 %and, 0408 ret i1 %cmp409}410 411define <2 x i1> @test18_ne_vec(<2 x i32> %x) {412; CHECK-LABEL: define <2 x i1> @test18_ne_vec(413; CHECK-SAME: <2 x i32> [[X:%.*]]) {414; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X]], splat (i32 3)415; CHECK-NEXT: ret <2 x i1> [[TMP1]]416;417 %sh = lshr <2 x i32> <i32 8, i32 8>, %x418 %and = and <2 x i32> %sh, <i32 1, i32 1>419 %cmp = icmp ne <2 x i32> %and, zeroinitializer420 ret <2 x i1> %cmp421}422 423define i1 @test19(i32 %x) {424; CHECK-LABEL: define i1 @test19(425; CHECK-SAME: i32 [[X:%.*]]) {426; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 3427; CHECK-NEXT: ret i1 [[TMP1]]428;429 %shl = shl i32 1, %x430 %and = and i32 %shl, 8431 %cmp = icmp eq i32 %and, 8432 ret i1 %cmp433}434 435define <2 x i1> @test19vec(<2 x i32> %x) {436; CHECK-LABEL: define <2 x i1> @test19vec(437; CHECK-SAME: <2 x i32> [[X:%.*]]) {438; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X]], splat (i32 3)439; CHECK-NEXT: ret <2 x i1> [[TMP1]]440;441 %shl = shl <2 x i32> <i32 1, i32 1>, %x442 %and = and <2 x i32> %shl, <i32 8, i32 8>443 %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>444 ret <2 x i1> %cmp445}446 447define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {448; CHECK-LABEL: define <2 x i1> @cmp_and_signbit_vec(449; CHECK-SAME: <2 x i3> [[X:%.*]]) {450; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> [[X]], zeroinitializer451; CHECK-NEXT: ret <2 x i1> [[CMP]]452;453 %and = and <2 x i3> %x, <i3 4, i3 4>454 %cmp = icmp ne <2 x i3> %and, zeroinitializer455 ret <2 x i1> %cmp456}457 458define i1 @test20(i32 %x) {459; CHECK-LABEL: define i1 @test20(460; CHECK-SAME: i32 [[X:%.*]]) {461; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 3462; CHECK-NEXT: ret i1 [[TMP1]]463;464 %shl = shl i32 1, %x465 %and = and i32 %shl, 8466 %cmp = icmp ne i32 %and, 0467 ret i1 %cmp468}469 470define <2 x i1> @test20vec(<2 x i32> %x) {471; CHECK-LABEL: define <2 x i1> @test20vec(472; CHECK-SAME: <2 x i32> [[X:%.*]]) {473; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X]], splat (i32 3)474; CHECK-NEXT: ret <2 x i1> [[TMP1]]475;476 %shl = shl <2 x i32> <i32 1, i32 1>, %x477 %and = and <2 x i32> %shl, <i32 8, i32 8>478 %cmp = icmp ne <2 x i32> %and, zeroinitializer479 ret <2 x i1> %cmp480}481 482define i1 @test20a(i32 %x) {483; CHECK-LABEL: define i1 @test20a(484; CHECK-SAME: i32 [[X:%.*]]) {485; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], 3486; CHECK-NEXT: ret i1 [[CMP]]487;488 %shl = shl i32 1, %x489 %and = and i32 %shl, 7490 %cmp = icmp ne i32 %and, 0491 ret i1 %cmp492}493 494define <2 x i1> @test20a_vec(<2 x i32> %x) {495; CHECK-LABEL: define <2 x i1> @test20a_vec(496; CHECK-SAME: <2 x i32> [[X:%.*]]) {497; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X]], splat (i32 3)498; CHECK-NEXT: ret <2 x i1> [[CMP]]499;500 %shl = shl <2 x i32> <i32 1, i32 1>, %x501 %and = and <2 x i32> %shl, <i32 7, i32 7>502 %cmp = icmp ne <2 x i32> %and, zeroinitializer503 ret <2 x i1> %cmp504}505 506define i1 @test21(i8 %x, i8 %y) {507; CHECK-LABEL: define i1 @test21(508; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {509; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X]], 3510; CHECK-NEXT: ret i1 [[B]]511;512 %A = or i8 %x, 1513 %B = icmp ugt i8 %A, 3514 ret i1 %B515}516 517define i1 @test22(i8 %x, i8 %y) {518; CHECK-LABEL: define i1 @test22(519; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {520; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X]], 4521; CHECK-NEXT: ret i1 [[B]]522;523 %A = or i8 %x, 1524 %B = icmp ult i8 %A, 4525 ret i1 %B526}527 528; PR2740529define i1 @test23(i32 %x) {530; CHECK-LABEL: define i1 @test23(531; CHECK-SAME: i32 [[X:%.*]]) {532; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[X]], 1328634634533; CHECK-NEXT: ret i1 [[I4]]534;535 %i3 = sdiv i32 %x, -1328634635536 %i4 = icmp eq i32 %i3, -1537 ret i1 %i4538}539 540define <2 x i1> @test23vec(<2 x i32> %x) {541; CHECK-LABEL: define <2 x i1> @test23vec(542; CHECK-SAME: <2 x i32> [[X:%.*]]) {543; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> [[X]], splat (i32 1328634634)544; CHECK-NEXT: ret <2 x i1> [[I4]]545;546 %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>547 %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>548 ret <2 x i1> %i4549}550 551; Note: offs can be negative, LLVM used to make an incorrect assumption that552; unsigned overflow does not happen during offset computation553define i1 @test24_neg_offs(ptr %p, i64 %offs) {554; CHECK-LABEL: define i1 @test24_neg_offs(555; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFS:%.*]]) {556; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OFFS]], -2557; CHECK-NEXT: ret i1 [[CMP]]558;559 %p1 = getelementptr inbounds i32, ptr %p, i64 %offs560 %conv1 = ptrtoint ptr %p to i64561 %conv2 = ptrtoint ptr %p1 to i64562 %delta = sub i64 %conv1, %conv2563 %cmp = icmp eq i64 %delta, 8564 ret i1 %cmp565}566 567; X - Z > Y - Z -> X > Y if there is no overflow.568define i1 @test27(i32 %x, i32 %y, i32 %z) {569; CHECK-LABEL: define i1 @test27(570; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {571; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]572; CHECK-NEXT: ret i1 [[C]]573;574 %lhs = sub nsw i32 %x, %z575 %rhs = sub nsw i32 %y, %z576 %c = icmp sgt i32 %lhs, %rhs577 ret i1 %c578}579 580define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {581; CHECK-LABEL: define i1 @test27_extra_uses(582; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {583; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X]], [[Z]]584; CHECK-NEXT: call void @use_i32(i32 [[LHS]])585; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[Y]], [[Z]]586; CHECK-NEXT: call void @use_i32(i32 [[RHS]])587; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]588; CHECK-NEXT: ret i1 [[C]]589;590 %lhs = sub nsw i32 %x, %z591 call void @use_i32(i32 %lhs)592 %rhs = sub nsw i32 %y, %z593 call void @use_i32(i32 %rhs)594 %c = icmp sgt i32 %lhs, %rhs595 ret i1 %c596}597 598; X - Z > Y - Z -> X > Y if there is no overflow.599define i1 @test28(i32 %x, i32 %y, i32 %z) {600; CHECK-LABEL: define i1 @test28(601; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {602; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]603; CHECK-NEXT: ret i1 [[C]]604;605 %lhs = sub nuw i32 %x, %z606 %rhs = sub nuw i32 %y, %z607 %c = icmp ugt i32 %lhs, %rhs608 ret i1 %c609}610 611define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {612; CHECK-LABEL: define i1 @test28_extra_uses(613; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {614; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X]], [[Z]]615; CHECK-NEXT: call void @use_i32(i32 [[LHS]])616; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[Y]], [[Z]]617; CHECK-NEXT: call void @use_i32(i32 [[RHS]])618; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]619; CHECK-NEXT: ret i1 [[C]]620;621 %lhs = sub nuw i32 %x, %z622 call void @use_i32(i32 %lhs)623 %rhs = sub nuw i32 %y, %z624 call void @use_i32(i32 %rhs)625 %c = icmp ugt i32 %lhs, %rhs626 ret i1 %c627}628 629; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969630 631define i1 @ugt_sub(i32 %xsrc, i32 %y) {632; CHECK-LABEL: define i1 @ugt_sub(633; CHECK-SAME: i32 [[XSRC:%.*]], i32 [[Y:%.*]]) {634; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC]], 42635; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y]], [[X]]636; CHECK-NEXT: ret i1 [[CMP]]637;638 %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization639 %sub = sub i32 %x, %y640 %cmp = icmp ugt i32 %sub, %x641 ret i1 %cmp642}643 644; Swap operands and predicate. Try a vector type to verify that works too.645 646define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {647; CHECK-LABEL: define <2 x i1> @ult_sub(648; CHECK-SAME: <2 x i8> [[XSRC:%.*]], <2 x i8> [[Y:%.*]]) {649; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC]], <i8 42, i8 -42>650; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]651; CHECK-NEXT: ret <2 x i1> [[CMP]]652;653 %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization654 %sub = sub <2 x i8> %x, %y655 %cmp = icmp ult <2 x i8> %x, %sub656 ret <2 x i1> %cmp657}658 659; X - Y > X -> 0 > Y if there is no overflow.660define i1 @test33(i32 %x, i32 %y) {661; CHECK-LABEL: define i1 @test33(662; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {663; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y]], 0664; CHECK-NEXT: ret i1 [[C]]665;666 %lhs = sub nsw i32 %x, %y667 %c = icmp sgt i32 %lhs, %x668 ret i1 %c669}670 671; X - Y > X -> 0 > Y if there is no overflow.672define i1 @test34(i32 %x, i32 %y) {673; CHECK-LABEL: define i1 @test34(674; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {675; CHECK-NEXT: ret i1 false676;677 %lhs = sub nuw i32 %x, %y678 %c = icmp ugt i32 %lhs, %x679 ret i1 %c680}681 682; X > X - Y -> Y > 0 if there is no overflow.683define i1 @test35(i32 %x, i32 %y) {684; CHECK-LABEL: define i1 @test35(685; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {686; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y]], 0687; CHECK-NEXT: ret i1 [[C]]688;689 %rhs = sub nsw i32 %x, %y690 %c = icmp sgt i32 %x, %rhs691 ret i1 %c692}693 694; X > X - Y -> Y > 0 if there is no overflow.695define i1 @test36(i32 %x, i32 %y) {696; CHECK-LABEL: define i1 @test36(697; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {698; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y]], 0699; CHECK-NEXT: ret i1 [[C]]700;701 %rhs = sub nuw i32 %x, %y702 %c = icmp ugt i32 %x, %rhs703 ret i1 %c704}705 706; X - Y > X - Z -> Z > Y if there is no overflow.707define i1 @test37(i32 %x, i32 %y, i32 %z) {708; CHECK-LABEL: define i1 @test37(709; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {710; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]711; CHECK-NEXT: ret i1 [[C]]712;713 %lhs = sub nsw i32 %x, %y714 %rhs = sub nsw i32 %x, %z715 %c = icmp sgt i32 %lhs, %rhs716 ret i1 %c717}718 719define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {720; CHECK-LABEL: define i1 @test37_extra_uses(721; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {722; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X]], [[Y]]723; CHECK-NEXT: call void @use_i32(i32 [[LHS]])724; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[X]], [[Z]]725; CHECK-NEXT: call void @use_i32(i32 [[RHS]])726; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]727; CHECK-NEXT: ret i1 [[C]]728;729 %lhs = sub nsw i32 %x, %y730 call void @use_i32(i32 %lhs)731 %rhs = sub nsw i32 %x, %z732 call void @use_i32(i32 %rhs)733 %c = icmp sgt i32 %lhs, %rhs734 ret i1 %c735}736 737; TODO: Min/max pattern should not prevent the fold.738 739define i32 @neg_max_s32(i32 %x, i32 %y) {740; CHECK-LABEL: define i32 @neg_max_s32(741; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {742; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 [[Y]])743; CHECK-NEXT: ret i32 [[TMP1]]744;745 %nx = sub nsw i32 0, %x746 %ny = sub nsw i32 0, %y747 %c = icmp slt i32 %nx, %ny748 %s = select i1 %c, i32 %ny, i32 %nx749 %r = sub nsw i32 0, %s750 ret i32 %r751}752 753define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {754; CHECK-LABEL: define <4 x i32> @neg_max_v4s32(755; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {756; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])757; CHECK-NEXT: ret <4 x i32> [[TMP1]]758;759 %nx = sub nsw <4 x i32> zeroinitializer, %x760 %ny = sub nsw <4 x i32> zeroinitializer, %y761 %c = icmp sgt <4 x i32> %nx, %ny762 %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny763 %r = sub <4 x i32> zeroinitializer, %s764 ret <4 x i32> %r765}766 767; X - Y > X - Z -> Z > Y if there is no overflow.768define i1 @test38(i32 %x, i32 %y, i32 %z) {769; CHECK-LABEL: define i1 @test38(770; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {771; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]772; CHECK-NEXT: ret i1 [[C]]773;774 %lhs = sub nuw i32 %x, %y775 %rhs = sub nuw i32 %x, %z776 %c = icmp ugt i32 %lhs, %rhs777 ret i1 %c778}779 780define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {781; CHECK-LABEL: define i1 @test38_extra_uses(782; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {783; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X]], [[Y]]784; CHECK-NEXT: call void @use_i32(i32 [[LHS]])785; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[X]], [[Z]]786; CHECK-NEXT: call void @use_i32(i32 [[RHS]])787; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]788; CHECK-NEXT: ret i1 [[C]]789;790 %lhs = sub nuw i32 %x, %y791 call void @use_i32(i32 %lhs)792 %rhs = sub nuw i32 %x, %z793 call void @use_i32(i32 %rhs)794 %c = icmp ugt i32 %lhs, %rhs795 ret i1 %c796}797 798define i1 @shr_exact(i132 %x) {799; CHECK-LABEL: define i1 @shr_exact(800; CHECK-SAME: i132 [[X:%.*]]) {801; CHECK-NEXT: [[CMP:%.*]] = icmp eq i132 [[X]], 32802; CHECK-NEXT: ret i1 [[CMP]]803;804 %sh = ashr exact i132 %x, 4805 %cmp = icmp eq i132 %sh, 2806 ret i1 %cmp807}808 809define <2 x i1> @shr_exact_vec(<2 x i132> %x) {810; CHECK-LABEL: define <2 x i1> @shr_exact_vec(811; CHECK-SAME: <2 x i132> [[X:%.*]]) {812; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i132> [[X]], splat (i132 32)813; CHECK-NEXT: ret <2 x i1> [[CMP]]814;815 %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>816 %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>817 ret <2 x i1> %cmp818}819 820; PR9343 #3821define i1 @test41(i32 %X, i32 %Y) {822; CHECK-LABEL: define i1 @test41(823; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {824; CHECK-NEXT: ret i1 true825;826 %A = urem i32 %X, %Y827 %B = icmp ugt i32 %Y, %A828 ret i1 %B829}830 831define i1 @test42(i32 %X, i32 %Y) {832; CHECK-LABEL: define i1 @test42(833; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {834; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y]], -1835; CHECK-NEXT: ret i1 [[B]]836;837 %A = srem i32 %X, %Y838 %B = icmp slt i32 %A, %Y839 ret i1 %B840}841 842define i1 @test43(i32 %X, i32 %Y) {843; CHECK-LABEL: define i1 @test43(844; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {845; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y]], 0846; CHECK-NEXT: ret i1 [[B]]847;848 %A = srem i32 %X, %Y849 %B = icmp slt i32 %Y, %A850 ret i1 %B851}852 853define i1 @test44(i32 %X, i32 %Y) {854; CHECK-LABEL: define i1 @test44(855; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {856; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y]], -1857; CHECK-NEXT: ret i1 [[B]]858;859 %A = srem i32 %X, %Y860 %B = icmp slt i32 %A, %Y861 ret i1 %B862}863 864define i1 @test45(i32 %X, i32 %Y) {865; CHECK-LABEL: define i1 @test45(866; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {867; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y]], 0868; CHECK-NEXT: ret i1 [[B]]869;870 %A = srem i32 %X, %Y871 %B = icmp slt i32 %Y, %A872 ret i1 %B873}874 875; PR9343 #4876define i1 @test46(i32 %X, i32 %Y, i32 %Z) {877; CHECK-LABEL: define i1 @test46(878; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {879; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y]]880; CHECK-NEXT: ret i1 [[C]]881;882 %A = ashr exact i32 %X, %Z883 %B = ashr exact i32 %Y, %Z884 %C = icmp ult i32 %A, %B885 ret i1 %C886}887 888define i1 @test46_multiuse1(i32 %X, i32 %Y, i32 %Z) {889; CHECK-LABEL: define i1 @test46_multiuse1(890; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {891; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X]], [[Z]]892; CHECK-NEXT: call void @use_i32(i32 [[A]])893; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y]]894; CHECK-NEXT: ret i1 [[C]]895;896 %A = ashr exact i32 %X, %Z897 call void @use_i32(i32 %A)898 %B = ashr exact i32 %Y, %Z899 %C = icmp ult i32 %A, %B900 ret i1 %C901}902 903define i1 @test46_multiuse2(i32 %X, i32 %Y, i32 %Z) {904; CHECK-LABEL: define i1 @test46_multiuse2(905; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {906; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y]], [[Z]]907; CHECK-NEXT: call void @use_i32(i32 [[B]])908; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y]]909; CHECK-NEXT: ret i1 [[C]]910;911 %A = ashr exact i32 %X, %Z912 %B = ashr exact i32 %Y, %Z913 call void @use_i32(i32 %B)914 %C = icmp ult i32 %A, %B915 ret i1 %C916}917 918define i1 @test46_multiuse3(i32 %X, i32 %Y, i32 %Z) {919; CHECK-LABEL: define i1 @test46_multiuse3(920; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {921; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X]], [[Z]]922; CHECK-NEXT: call void @use_i32(i32 [[A]])923; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y]], [[Z]]924; CHECK-NEXT: call void @use_i32(i32 [[B]])925; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]]926; CHECK-NEXT: ret i1 [[C]]927;928 %A = ashr exact i32 %X, %Z929 call void @use_i32(i32 %A)930 %B = ashr exact i32 %Y, %Z931 call void @use_i32(i32 %B)932 %C = icmp ult i32 %A, %B933 ret i1 %C934}935 936; PR9343 #5937define i1 @test47(i32 %X, i32 %Y, i32 %Z) {938; CHECK-LABEL: define i1 @test47(939; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {940; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]941; CHECK-NEXT: ret i1 [[C]]942;943 %A = ashr exact i32 %X, %Z944 %B = ashr exact i32 %Y, %Z945 %C = icmp ugt i32 %A, %B946 ret i1 %C947}948 949; PR9343 #8950define i1 @test48(i32 %X, i32 %Y, i32 %Z) {951; CHECK-LABEL: define i1 @test48(952; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {953; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X]], [[Y]]954; CHECK-NEXT: ret i1 [[C]]955;956 %A = sdiv exact i32 %X, %Z957 %B = sdiv exact i32 %Y, %Z958 %C = icmp eq i32 %A, %B959 ret i1 %C960}961 962; The above transform only works for equality predicates.963 964define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {965; CHECK-LABEL: define i1 @PR32949(966; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {967; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 [[X]], [[Z]]968; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 [[Y]], [[Z]]969; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]970; CHECK-NEXT: ret i1 [[C]]971;972 %A = sdiv exact i32 %X, %Z973 %B = sdiv exact i32 %Y, %Z974 %C = icmp sgt i32 %A, %B975 ret i1 %C976}977 978define i1 @test_sdiv_pos_slt(i32 %x, i32 %y) {979; CHECK-LABEL: define i1 @test_sdiv_pos_slt(980; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {981; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], [[Y]]982; CHECK-NEXT: ret i1 [[CMP]]983;984 %divx = sdiv exact i32 %x, 40985 %divy = sdiv exact i32 %y, 40986 %cmp = icmp slt i32 %divx, %divy987 ret i1 %cmp988}989 990define i1 @test_sdiv_pos_sle(i32 %x, i32 %y) {991; CHECK-LABEL: define i1 @test_sdiv_pos_sle(992; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {993; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X]], [[Y]]994; CHECK-NEXT: ret i1 [[CMP]]995;996 %divx = sdiv exact i32 %x, 40997 %divy = sdiv exact i32 %y, 40998 %cmp = icmp sle i32 %divx, %divy999 ret i1 %cmp1000}1001 1002define i1 @test_sdiv_pos_sgt(i32 %x, i32 %y) {1003; CHECK-LABEL: define i1 @test_sdiv_pos_sgt(1004; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1005; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]1006; CHECK-NEXT: ret i1 [[CMP]]1007;1008 %divx = sdiv exact i32 %x, 401009 %divy = sdiv exact i32 %y, 401010 %cmp = icmp sgt i32 %divx, %divy1011 ret i1 %cmp1012}1013 1014define i1 @test_sdiv_pos_sge(i32 %x, i32 %y) {1015; CHECK-LABEL: define i1 @test_sdiv_pos_sge(1016; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1017; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X]], [[Y]]1018; CHECK-NEXT: ret i1 [[CMP]]1019;1020 %divx = sdiv exact i32 %x, 401021 %divy = sdiv exact i32 %y, 401022 %cmp = icmp sge i32 %divx, %divy1023 ret i1 %cmp1024}1025 1026define i1 @test_sdiv_pos_ult(i32 %x, i32 %y) {1027; CHECK-LABEL: define i1 @test_sdiv_pos_ult(1028; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1029; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]1030; CHECK-NEXT: ret i1 [[CMP]]1031;1032 %divx = sdiv exact i32 %x, 401033 %divy = sdiv exact i32 %y, 401034 %cmp = icmp ult i32 %divx, %divy1035 ret i1 %cmp1036}1037 1038define i1 @test_sdiv_pos_ule(i32 %x, i32 %y) {1039; CHECK-LABEL: define i1 @test_sdiv_pos_ule(1040; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1041; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[X]], [[Y]]1042; CHECK-NEXT: ret i1 [[CMP]]1043;1044 %divx = sdiv exact i32 %x, 401045 %divy = sdiv exact i32 %y, 401046 %cmp = icmp ule i32 %divx, %divy1047 ret i1 %cmp1048}1049 1050define i1 @test_sdiv_pos_ugt(i32 %x, i32 %y) {1051; CHECK-LABEL: define i1 @test_sdiv_pos_ugt(1052; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1053; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], [[Y]]1054; CHECK-NEXT: ret i1 [[CMP]]1055;1056 %divx = sdiv exact i32 %x, 401057 %divy = sdiv exact i32 %y, 401058 %cmp = icmp ugt i32 %divx, %divy1059 ret i1 %cmp1060}1061 1062define i1 @test_sdiv_pos_uge(i32 %x, i32 %y) {1063; CHECK-LABEL: define i1 @test_sdiv_pos_uge(1064; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1065; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X]], [[Y]]1066; CHECK-NEXT: ret i1 [[CMP]]1067;1068 %divx = sdiv exact i32 %x, 401069 %divy = sdiv exact i32 %y, 401070 %cmp = icmp uge i32 %divx, %divy1071 ret i1 %cmp1072}1073 1074define i1 @test_sdiv_neg_slt(i32 %x, i32 %y) {1075; CHECK-LABEL: define i1 @test_sdiv_neg_slt(1076; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1077; CHECK-NEXT: [[DIVX:%.*]] = sdiv exact i32 [[X]], -401078; CHECK-NEXT: [[DIVY:%.*]] = sdiv exact i32 [[Y]], -401079; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DIVX]], [[DIVY]]1080; CHECK-NEXT: ret i1 [[CMP]]1081;1082 %divx = sdiv exact i32 %x, -401083 %divy = sdiv exact i32 %y, -401084 %cmp = icmp slt i32 %divx, %divy1085 ret i1 %cmp1086}1087 1088; PR84691089define <2 x i1> @test49(<2 x i32> %i3) {1090; CHECK-LABEL: define <2 x i1> @test49(1091; CHECK-SAME: <2 x i32> [[I3:%.*]]) {1092; CHECK-NEXT: [[ENTRY:.*:]]1093; CHECK-NEXT: ret <2 x i1> splat (i1 true)1094;1095entry:1096 %i11 = and <2 x i32> %i3, <i32 3, i32 3>1097 %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>1098 ret <2 x i1> %cmp1099}1100 1101; PR9343 #71102define i1 @test50(i16 %X, i32 %Y) {1103; CHECK-LABEL: define i1 @test50(1104; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) {1105; CHECK-NEXT: ret i1 true1106;1107 %A = zext i16 %X to i321108 %B = srem i32 %A, %Y1109 %C = icmp sgt i32 %B, -11110 ret i1 %C1111}1112 1113define i1 @test51(i32 %X, i32 %Y) {1114; CHECK-LABEL: define i1 @test51(1115; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1116; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -21474836481117; CHECK-NEXT: [[B:%.*]] = srem i32 [[A]], [[Y]]1118; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[B]], -11119; CHECK-NEXT: ret i1 [[C]]1120;1121 %A = and i32 %X, 21474836481122 %B = srem i32 %A, %Y1123 %C = icmp sgt i32 %B, -11124 ret i1 %C1125}1126 1127define i1 @test52(i32 %x1) {1128; CHECK-LABEL: define i1 @test52(1129; CHECK-SAME: i32 [[X1:%.*]]) {1130; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1]], 167119351131; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[TMP1]], 49808631132; CHECK-NEXT: ret i1 [[A]]1133;1134 %conv = and i32 %x1, 2551135 %cmp = icmp eq i32 %conv, 1271136 %i2 = lshr i32 %x1, 161137 %i3 = trunc i32 %i2 to i81138 %cmp15 = icmp eq i8 %i3, 761139 1140 %A = and i1 %cmp, %cmp151141 ret i1 %A1142}1143 1144define i1 @test52_logical(i32 %x1) {1145; CHECK-LABEL: define i1 @test52_logical(1146; CHECK-SAME: i32 [[X1:%.*]]) {1147; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1]], 167119351148; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[TMP1]], 49808631149; CHECK-NEXT: ret i1 [[A]]1150;1151 %conv = and i32 %x1, 2551152 %cmp = icmp eq i32 %conv, 1271153 %i2 = lshr i32 %x1, 161154 %i3 = trunc i32 %i2 to i81155 %cmp15 = icmp eq i8 %i3, 761156 1157 %A = select i1 %cmp, i1 %cmp15, i1 false1158 ret i1 %A1159}1160 1161define i1 @test52b(i128 %x1) {1162; CHECK-LABEL: define i1 @test52b(1163; CHECK-SAME: i128 [[X1:%.*]]) {1164; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1]], 167119351165; CHECK-NEXT: [[A:%.*]] = icmp eq i128 [[TMP1]], 49808631166; CHECK-NEXT: ret i1 [[A]]1167;1168 %conv = and i128 %x1, 2551169 %cmp = icmp eq i128 %conv, 1271170 %i2 = lshr i128 %x1, 161171 %i3 = trunc i128 %i2 to i81172 %cmp15 = icmp eq i8 %i3, 761173 1174 %A = and i1 %cmp, %cmp151175 ret i1 %A1176}1177 1178define i1 @test52b_logical(i128 %x1) {1179; CHECK-LABEL: define i1 @test52b_logical(1180; CHECK-SAME: i128 [[X1:%.*]]) {1181; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1]], 167119351182; CHECK-NEXT: [[A:%.*]] = icmp eq i128 [[TMP1]], 49808631183; CHECK-NEXT: ret i1 [[A]]1184;1185 %conv = and i128 %x1, 2551186 %cmp = icmp eq i128 %conv, 1271187 %i2 = lshr i128 %x1, 161188 %i3 = trunc i128 %i2 to i81189 %cmp15 = icmp eq i8 %i3, 761190 1191 %A = select i1 %cmp, i1 %cmp15, i1 false1192 ret i1 %A1193}1194 1195; PR98381196define i1 @test53(i32 %a, i32 %b) {1197; CHECK-LABEL: define i1 @test53(1198; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {1199; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A]], 301200; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B]], 301201; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]1202; CHECK-NEXT: ret i1 [[Z]]1203;1204 %x = sdiv exact i32 %a, 301205 %y = sdiv i32 %b, 301206 %z = icmp eq i32 %x, %y1207 ret i1 %z1208}1209 1210define i1 @test54(i8 %a) {1211; CHECK-LABEL: define i1 @test54(1212; CHECK-SAME: i8 [[A:%.*]]) {1213; CHECK-NEXT: [[RET:%.*]] = icmp slt i8 [[A]], -641214; CHECK-NEXT: ret i1 [[RET]]1215;1216 %ext = zext i8 %a to i321217 %and = and i32 %ext, 1921218 %ret = icmp eq i32 %and, 1281219 ret i1 %ret1220}1221 1222define i1 @test55(i32 %a) {1223; CHECK-LABEL: define i1 @test55(1224; CHECK-SAME: i32 [[A:%.*]]) {1225; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], -1231226; CHECK-NEXT: ret i1 [[CMP]]1227;1228 %sub = sub i32 0, %a1229 %cmp = icmp eq i32 %sub, 1231230 ret i1 %cmp1231}1232 1233define <2 x i1> @test55vec(<2 x i32> %a) {1234; CHECK-LABEL: define <2 x i1> @test55vec(1235; CHECK-SAME: <2 x i32> [[A:%.*]]) {1236; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A]], splat (i32 -123)1237; CHECK-NEXT: ret <2 x i1> [[CMP]]1238;1239 %sub = sub <2 x i32> zeroinitializer, %a1240 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>1241 ret <2 x i1> %cmp1242}1243 1244define i1 @test56(i32 %a) {1245; CHECK-LABEL: define i1 @test56(1246; CHECK-SAME: i32 [[A:%.*]]) {1247; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], -1131248; CHECK-NEXT: ret i1 [[CMP]]1249;1250 %sub = sub i32 10, %a1251 %cmp = icmp eq i32 %sub, 1231252 ret i1 %cmp1253}1254 1255define <2 x i1> @test56vec(<2 x i32> %a) {1256; CHECK-LABEL: define <2 x i1> @test56vec(1257; CHECK-SAME: <2 x i32> [[A:%.*]]) {1258; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A]], splat (i32 -113)1259; CHECK-NEXT: ret <2 x i1> [[CMP]]1260;1261 %sub = sub <2 x i32> <i32 10, i32 10>, %a1262 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>1263 ret <2 x i1> %cmp1264}1265 1266; PR10267 Don't make icmps more expensive when no other inst is subsumed.1267define i1 @test57(i32 %a) {1268; CHECK-LABEL: define i1 @test57(1269; CHECK-SAME: i32 [[A:%.*]]) {1270; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], -21271; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 01272; CHECK-NEXT: call void @use_i32(i32 [[AND]])1273; CHECK-NEXT: ret i1 [[CMP]]1274;1275 %and = and i32 %a, -21276 %cmp = icmp ne i32 %and, 01277 call void @use_i32(i32 %and)1278 ret i1 %cmp1279}1280 1281; rdar://problem/104825091282define zeroext i1 @cmpabs1(i64 %val) {1283; CHECK-LABEL: define zeroext i1 @cmpabs1(1284; CHECK-SAME: i64 [[VAL:%.*]]) {1285; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL]], 01286; CHECK-NEXT: ret i1 [[TOBOOL]]1287;1288 %sub = sub nsw i64 0, %val1289 %cmp = icmp slt i64 %val, 01290 %sub.val = select i1 %cmp, i64 %sub, i64 %val1291 %tobool = icmp ne i64 %sub.val, 01292 ret i1 %tobool1293}1294 1295define zeroext i1 @cmpabs2(i64 %val) {1296; CHECK-LABEL: define zeroext i1 @cmpabs2(1297; CHECK-SAME: i64 [[VAL:%.*]]) {1298; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL]], 01299; CHECK-NEXT: ret i1 [[TOBOOL]]1300;1301 %sub = sub nsw i64 0, %val1302 %cmp = icmp slt i64 %val, 01303 %sub.val = select i1 %cmp, i64 %val, i64 %sub1304 %tobool = icmp ne i64 %sub.val, 01305 ret i1 %tobool1306}1307 1308define i1 @abs_intrin_eq_zero(i8 %x) {1309; CHECK-LABEL: define i1 @abs_intrin_eq_zero(1310; CHECK-SAME: i8 [[X:%.*]]) {1311; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X]], 01312; CHECK-NEXT: ret i1 [[CMP]]1313;1314 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)1315 %cmp = icmp eq i8 %abs, 01316 ret i1 %cmp1317}1318 1319define i1 @abs_intrin_ne_zero(i8 %x) {1320; CHECK-LABEL: define i1 @abs_intrin_ne_zero(1321; CHECK-SAME: i8 [[X:%.*]]) {1322; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X]], 01323; CHECK-NEXT: ret i1 [[CMP]]1324;1325 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)1326 %cmp = icmp ne i8 %abs, 01327 ret i1 %cmp1328}1329 1330define void @test58() {1331; CHECK-LABEL: define void @test58() {1332; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)1333; CHECK-NEXT: ret void1334;1335 %cast = bitcast <1 x i64> <i64 36029346783166592> to i641336 %call = call i32 @test58_d( i64 %cast)1337 ret void1338}1339declare i32 @test58_d(i64)1340 1341; Negative test: GEP inbounds may cross sign boundary.1342define i1 @test62(ptr %a) {1343; CHECK-LABEL: define i1 @test62(1344; CHECK-SAME: ptr [[A:%.*]]) {1345; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 11346; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 101347; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr [[ARRAYIDX1]], [[ARRAYIDX2]]1348; CHECK-NEXT: ret i1 [[CMP]]1349;1350 %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 11351 %arrayidx2 = getelementptr inbounds i8, ptr %a, i64 101352 %cmp = icmp slt ptr %arrayidx1, %arrayidx21353 ret i1 %cmp1354}1355 1356define i1 @test62_as1(ptr addrspace(1) %a) {1357; CHECK-LABEL: define i1 @test62_as1(1358; CHECK-SAME: ptr addrspace(1) [[A:%.*]]) {1359; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A]], i16 11360; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A]], i16 101361; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr addrspace(1) [[ARRAYIDX1]], [[ARRAYIDX2]]1362; CHECK-NEXT: ret i1 [[CMP]]1363;1364 %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 11365 %arrayidx2 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 101366 %cmp = icmp slt ptr addrspace(1) %arrayidx1, %arrayidx21367 ret i1 %cmp1368}1369 1370define i1 @low_mask_eq_zext(i8 %a, i32 %b) {1371; CHECK-LABEL: define i1 @low_mask_eq_zext(1372; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1373; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i81374; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]]1375; CHECK-NEXT: ret i1 [[C]]1376;1377 %z = zext i8 %a to i321378 %t = and i32 %b, 2551379 %c = icmp eq i32 %z, %t1380 ret i1 %c1381}1382 1383define i1 @low_mask_eq_zext_commute(i8 %a, i32 %b) {1384; CHECK-LABEL: define i1 @low_mask_eq_zext_commute(1385; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1386; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i81387; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]]1388; CHECK-NEXT: ret i1 [[C]]1389;1390 %t = and i32 %b, 2551391 %z = zext i8 %a to i321392 %c = icmp eq i32 %t, %z1393 ret i1 %c1394}1395 1396; negative test1397 1398define i1 @wrong_low_mask_eq_zext(i8 %a, i32 %b) {1399; CHECK-LABEL: define i1 @wrong_low_mask_eq_zext(1400; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1401; CHECK-NEXT: [[T:%.*]] = and i32 [[B]], 1271402; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A]] to i321403; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]]1404; CHECK-NEXT: ret i1 [[C]]1405;1406 %t = and i32 %b, 1271407 %z = zext i8 %a to i321408 %c = icmp eq i32 %t, %z1409 ret i1 %c1410}1411 1412; negative test1413 1414define i1 @wrong_low_mask_eq_zext2(i8 %a, i32 %b) {1415; CHECK-LABEL: define i1 @wrong_low_mask_eq_zext2(1416; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1417; CHECK-NEXT: [[T:%.*]] = and i32 [[B]], 2541418; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A]] to i321419; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]]1420; CHECK-NEXT: ret i1 [[C]]1421;1422 %t = and i32 %b, 2541423 %z = zext i8 %a to i321424 %c = icmp eq i32 %t, %z1425 ret i1 %c1426}1427 1428define i1 @low_mask_eq_zext_use1(i8 %a, i32 %b) {1429; CHECK-LABEL: define i1 @low_mask_eq_zext_use1(1430; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1431; CHECK-NEXT: [[T:%.*]] = and i32 [[B]], 2551432; CHECK-NEXT: call void @use_i32(i32 [[T]])1433; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i81434; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]]1435; CHECK-NEXT: ret i1 [[C]]1436;1437 %t = and i32 %b, 2551438 call void @use_i32(i32 %t)1439 %z = zext i8 %a to i321440 %c = icmp eq i32 %t, %z1441 ret i1 %c1442}1443 1444define i1 @low_mask_eq_zext_use2(i8 %a, i32 %b) {1445; CHECK-LABEL: define i1 @low_mask_eq_zext_use2(1446; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1447; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A]] to i321448; CHECK-NEXT: call void @use_i32(i32 [[Z]])1449; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i81450; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]]1451; CHECK-NEXT: ret i1 [[C]]1452;1453 %t = and i32 %b, 2551454 %z = zext i8 %a to i321455 call void @use_i32(i32 %z)1456 %c = icmp eq i32 %t, %z1457 ret i1 %c1458}1459 1460define i1 @low_mask_eq_zext_use3(i8 %a, i32 %b) {1461; CHECK-LABEL: define i1 @low_mask_eq_zext_use3(1462; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {1463; CHECK-NEXT: [[T:%.*]] = and i32 [[B]], 2551464; CHECK-NEXT: call void @use_i32(i32 [[T]])1465; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A]] to i321466; CHECK-NEXT: call void @use_i32(i32 [[Z]])1467; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]]1468; CHECK-NEXT: ret i1 [[C]]1469;1470 %t = and i32 %b, 2551471 call void @use_i32(i32 %t)1472 %z = zext i8 %a to i321473 call void @use_i32(i32 %z)1474 %c = icmp eq i32 %t, %z1475 ret i1 %c1476}1477 1478define <2 x i1> @low_mask_eq_zext_vec_splat(<2 x i8> %a, <2 x i32> %b) {1479; CHECK-LABEL: define <2 x i1> @low_mask_eq_zext_vec_splat(1480; CHECK-SAME: <2 x i8> [[A:%.*]], <2 x i32> [[B:%.*]]) {1481; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[B]] to <2 x i8>1482; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[A]], [[TMP1]]1483; CHECK-NEXT: ret <2 x i1> [[C]]1484;1485 %t = and <2 x i32> %b, <i32 255, i32 255>1486 %z = zext <2 x i8> %a to <2 x i32>1487 %c = icmp eq <2 x i32> %t, %z1488 ret <2 x i1> %c1489}1490 1491define i1 @test65(i64 %A, i64 %B) {1492; CHECK-LABEL: define i1 @test65(1493; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {1494; CHECK-NEXT: ret i1 true1495;1496 %s1 = add i64 %A, %B1497 %s2 = add i64 %A, %B1498 %cmp = icmp eq i64 %s1, %s21499 ret i1 %cmp1500}1501 1502define i1 @test66(i64 %A, i64 %B) {1503; CHECK-LABEL: define i1 @test66(1504; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {1505; CHECK-NEXT: ret i1 true1506;1507 %s1 = add i64 %A, %B1508 %s2 = add i64 %B, %A1509 %cmp = icmp eq i64 %s1, %s21510 ret i1 %cmp1511}1512 1513define i1 @test67(i32 %x) {1514; CHECK-LABEL: define i1 @test67(1515; CHECK-SAME: i32 [[X:%.*]]) {1516; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 961517; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 01518; CHECK-NEXT: ret i1 [[CMP]]1519;1520 %and = and i32 %x, 1271521 %cmp = icmp sgt i32 %and, 311522 ret i1 %cmp1523}1524 1525define i1 @test67inverse(i32 %x) {1526; CHECK-LABEL: define i1 @test67inverse(1527; CHECK-SAME: i32 [[X:%.*]]) {1528; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 961529; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 01530; CHECK-NEXT: ret i1 [[CMP]]1531;1532 %and = and i32 %x, 1271533 %cmp = icmp sle i32 %and, 311534 ret i1 %cmp1535}1536 1537; The test above relies on 3 different folds.1538; This test only checks the last of those (icmp ugt -> icmp ne).1539 1540define <2 x i1> @test67vec(<2 x i32> %x) {1541; CHECK-LABEL: define <2 x i1> @test67vec(1542; CHECK-SAME: <2 x i32> [[X:%.*]]) {1543; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], splat (i32 96)1544; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer1545; CHECK-NEXT: ret <2 x i1> [[CMP]]1546;1547 %and = and <2 x i32> %x, <i32 96, i32 96>1548 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>1549 ret <2 x i1> %cmp1550}1551 1552define <2 x i1> @test67vec2(<2 x i32> %x) {1553; CHECK-LABEL: define <2 x i1> @test67vec2(1554; CHECK-SAME: <2 x i32> [[X:%.*]]) {1555; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], splat (i32 96)1556; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer1557; CHECK-NEXT: ret <2 x i1> [[CMP]]1558;1559 %and = and <2 x i32> %x, <i32 127, i32 127>1560 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>1561 ret <2 x i1> %cmp1562}1563 1564define <2 x i1> @test67vecinverse(<2 x i32> %x) {1565; CHECK-LABEL: define <2 x i1> @test67vecinverse(1566; CHECK-SAME: <2 x i32> [[X:%.*]]) {1567; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], splat (i32 96)1568; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer1569; CHECK-NEXT: ret <2 x i1> [[CMP]]1570;1571 %and = and <2 x i32> %x, <i32 96, i32 96>1572 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>1573 ret <2 x i1> %cmp1574}1575 1576define i1 @test68(i32 %x) {1577; CHECK-LABEL: define i1 @test68(1578; CHECK-SAME: i32 [[X:%.*]]) {1579; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 1271580; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[AND]], 301581; CHECK-NEXT: ret i1 [[CMP]]1582;1583 %and = and i32 %x, 1271584 %cmp = icmp sgt i32 %and, 301585 ret i1 %cmp1586}1587 1588; PR159401589define i1 @test70(i32 %X) {1590; CHECK-LABEL: define i1 @test70(1591; CHECK-SAME: i32 [[X:%.*]]) {1592; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X]]1593; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 21594; CHECK-NEXT: ret i1 [[C]]1595;1596 %A = srem i32 5, %X1597 %B = add i32 %A, 21598 %C = icmp ne i32 %B, 41599 ret i1 %C1600}1601 1602define <2 x i1> @test70vec(<2 x i32> %X) {1603; CHECK-LABEL: define <2 x i1> @test70vec(1604; CHECK-SAME: <2 x i32> [[X:%.*]]) {1605; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X]], splat (i32 2)1606; CHECK-NEXT: ret <2 x i1> [[C]]1607;1608 %B = add <2 x i32> %X, <i32 2, i32 2>1609 %C = icmp ne <2 x i32> %B, <i32 4, i32 4>1610 ret <2 x i1> %C1611}1612 1613define i1 @icmp_sext16trunc(i32 %x) {1614; CHECK-LABEL: define i1 @icmp_sext16trunc(1615; CHECK-SAME: i32 [[X:%.*]]) {1616; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X]] to i161617; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 361618; CHECK-NEXT: ret i1 [[CMP]]1619;1620 %trunc = trunc i32 %x to i161621 %sext = sext i16 %trunc to i321622 %cmp = icmp slt i32 %sext, 361623 ret i1 %cmp1624}1625 1626define i1 @icmp_sext8trunc(i32 %x) {1627; CHECK-LABEL: define i1 @icmp_sext8trunc(1628; CHECK-SAME: i32 [[X:%.*]]) {1629; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X]] to i81630; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 361631; CHECK-NEXT: ret i1 [[CMP]]1632;1633 %trunc = trunc i32 %x to i81634 %sext = sext i8 %trunc to i321635 %cmp = icmp slt i32 %sext, 361636 ret i1 %cmp1637}1638 1639; Vectors should fold the same way.1640define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {1641; CHECK-LABEL: define <2 x i1> @icmp_sext8trunc_vec(1642; CHECK-SAME: <2 x i32> [[X:%.*]]) {1643; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X]] to <2 x i8>1644; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], splat (i8 36)1645; CHECK-NEXT: ret <2 x i1> [[CMP]]1646;1647 %trunc = trunc <2 x i32> %x to <2 x i8>1648 %sext = sext <2 x i8> %trunc to <2 x i32>1649 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>1650 ret <2 x i1> %cmp1651}1652 1653define i1 @icmp_shl16(i32 %x) {1654; CHECK-LABEL: define i1 @icmp_shl16(1655; CHECK-SAME: i32 [[X:%.*]]) {1656; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X]] to i161657; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 361658; CHECK-NEXT: ret i1 [[CMP]]1659;1660 %shl = shl i32 %x, 161661 %cmp = icmp slt i32 %shl, 23592961662 ret i1 %cmp1663}1664 1665; D25952: Don't create illegal types like i15 in InstCombine1666 1667define i1 @icmp_shl17(i32 %x) {1668; CHECK-LABEL: define i1 @icmp_shl17(1669; CHECK-SAME: i32 [[X:%.*]]) {1670; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X]], 171671; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 23592961672; CHECK-NEXT: ret i1 [[CMP]]1673;1674 %shl = shl i32 %x, 171675 %cmp = icmp slt i32 %shl, 23592961676 ret i1 %cmp1677}1678 1679define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {1680; CHECK-LABEL: define <2 x i1> @icmp_shl16_vec(1681; CHECK-SAME: <2 x i32> [[X:%.*]]) {1682; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X]] to <2 x i16>1683; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], splat (i16 36)1684; CHECK-NEXT: ret <2 x i1> [[CMP]]1685;1686 %shl = shl <2 x i32> %x, <i32 16, i32 16>1687 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>1688 ret <2 x i1> %cmp1689}1690 1691define i1 @icmp_shl24(i32 %x) {1692; CHECK-LABEL: define i1 @icmp_shl24(1693; CHECK-SAME: i32 [[X:%.*]]) {1694; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X]] to i81695; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 361696; CHECK-NEXT: ret i1 [[CMP]]1697;1698 %shl = shl i32 %x, 241699 %cmp = icmp slt i32 %shl, 6039797761700 ret i1 %cmp1701}1702 1703define i1 @icmp_shl_eq(i32 %x) {1704; CHECK-LABEL: define i1 @icmp_shl_eq(1705; CHECK-SAME: i32 [[X:%.*]]) {1706; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X]], 1342177271707; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 01708; CHECK-NEXT: ret i1 [[CMP]]1709;1710 %mul = shl i32 %x, 51711 %cmp = icmp eq i32 %mul, 01712 ret i1 %cmp1713}1714 1715define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {1716; CHECK-LABEL: define <2 x i1> @icmp_shl_eq_vec(1717; CHECK-SAME: <2 x i32> [[X:%.*]]) {1718; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X]], splat (i32 134217727)1719; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer1720; CHECK-NEXT: ret <2 x i1> [[CMP]]1721;1722 %mul = shl <2 x i32> %x, <i32 5, i32 5>1723 %cmp = icmp eq <2 x i32> %mul, zeroinitializer1724 ret <2 x i1> %cmp1725}1726 1727define i1 @icmp_shl_nsw_ne(i32 %x) {1728; CHECK-LABEL: define i1 @icmp_shl_nsw_ne(1729; CHECK-SAME: i32 [[X:%.*]]) {1730; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X]], 01731; CHECK-NEXT: ret i1 [[CMP]]1732;1733 %mul = shl nsw i32 %x, 71734 %cmp = icmp ne i32 %mul, 01735 ret i1 %cmp1736}1737 1738define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {1739; CHECK-LABEL: define <2 x i1> @icmp_shl_nsw_ne_vec(1740; CHECK-SAME: <2 x i32> [[X:%.*]]) {1741; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X]], zeroinitializer1742; CHECK-NEXT: ret <2 x i1> [[CMP]]1743;1744 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>1745 %cmp = icmp ne <2 x i32> %mul, zeroinitializer1746 ret <2 x i1> %cmp1747}1748 1749define i1 @icmp_shl_ne(i32 %x) {1750; CHECK-LABEL: define i1 @icmp_shl_ne(1751; CHECK-SAME: i32 [[X:%.*]]) {1752; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X]], 335544311753; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 01754; CHECK-NEXT: ret i1 [[CMP]]1755;1756 %mul = shl i32 %x, 71757 %cmp = icmp ne i32 %mul, 01758 ret i1 %cmp1759}1760 1761define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {1762; CHECK-LABEL: define <2 x i1> @icmp_shl_ne_vec(1763; CHECK-SAME: <2 x i32> [[X:%.*]]) {1764; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X]], splat (i32 33554431)1765; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer1766; CHECK-NEXT: ret <2 x i1> [[CMP]]1767;1768 %mul = shl <2 x i32> %x, <i32 7, i32 7>1769 %cmp = icmp ne <2 x i32> %mul, zeroinitializer1770 ret <2 x i1> %cmp1771}1772 1773define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {1774; CHECK-LABEL: define <2 x i1> @icmp_shl_nuw_ne_vec(1775; CHECK-SAME: <2 x i32> [[X:%.*]]) {1776; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X]], splat (i32 2)1777; CHECK-NEXT: ret <2 x i1> [[CMP]]1778;1779 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>1780 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>1781 ret <2 x i1> %cmp1782}1783 1784; If the (mul x, C) preserved the sign and this is sign test,1785; compare the LHS operand instead1786define i1 @icmp_mul_nsw(i32 %x) {1787; CHECK-LABEL: define i1 @icmp_mul_nsw(1788; CHECK-SAME: i32 [[X:%.*]]) {1789; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], 01790; CHECK-NEXT: ret i1 [[CMP]]1791;1792 %mul = mul nsw i32 %x, 121793 %cmp = icmp sgt i32 %mul, 01794 ret i1 %cmp1795}1796 1797define i1 @icmp_mul_nsw1(i32 %x) {1798; CHECK-LABEL: define i1 @icmp_mul_nsw1(1799; CHECK-SAME: i32 [[X:%.*]]) {1800; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 01801; CHECK-NEXT: ret i1 [[CMP]]1802;1803 %mul = mul nsw i32 %x, 121804 %cmp = icmp sle i32 %mul, -11805 ret i1 %cmp1806}1807 1808define i1 @icmp_mul_nsw_neg(i32 %x) {1809; CHECK-LABEL: define i1 @icmp_mul_nsw_neg(1810; CHECK-SAME: i32 [[X:%.*]]) {1811; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 11812; CHECK-NEXT: ret i1 [[CMP]]1813;1814 %mul = mul nsw i32 %x, -121815 %cmp = icmp sge i32 %mul, 01816 ret i1 %cmp1817}1818 1819define i1 @icmp_mul_nsw_neg1(i32 %x) {1820; CHECK-LABEL: define i1 @icmp_mul_nsw_neg1(1821; CHECK-SAME: i32 [[X:%.*]]) {1822; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 01823; CHECK-NEXT: ret i1 [[CMP]]1824;1825 %mul = mul nsw i32 %x, -121826 %cmp = icmp sge i32 %mul, 11827 ret i1 %cmp1828}1829 1830define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {1831; CHECK-LABEL: define <2 x i1> @icmp_mul_nsw_neg1_vec(1832; CHECK-SAME: <2 x i32> [[X:%.*]]) {1833; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer1834; CHECK-NEXT: ret <2 x i1> [[CMP]]1835;1836 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>1837 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>1838 ret <2 x i1> %cmp1839}1840 1841define i1 @icmp_mul_nsw_0(i32 %x) {1842; CHECK-LABEL: define i1 @icmp_mul_nsw_0(1843; CHECK-SAME: i32 [[X:%.*]]) {1844; CHECK-NEXT: ret i1 false1845;1846 %mul = mul nsw i32 %x, 01847 %cmp = icmp sgt i32 %mul, 01848 ret i1 %cmp1849}1850 1851define i1 @icmp_mul(i32 %x) {1852; CHECK-LABEL: define i1 @icmp_mul(1853; CHECK-SAME: i32 [[X:%.*]]) {1854; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X]], -121855; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -11856; CHECK-NEXT: ret i1 [[CMP]]1857;1858 %mul = mul i32 %x, -121859 %cmp = icmp sge i32 %mul, 01860 ret i1 %cmp1861}1862 1863; Checks for icmp (eq|ne) (mul x, C), 01864define i1 @icmp_mul_neq0(i32 %x) {1865; CHECK-LABEL: define i1 @icmp_mul_neq0(1866; CHECK-SAME: i32 [[X:%.*]]) {1867; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X]], 01868; CHECK-NEXT: ret i1 [[CMP]]1869;1870 %mul = mul nsw i32 %x, -121871 %cmp = icmp ne i32 %mul, 01872 ret i1 %cmp1873}1874 1875define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {1876; CHECK-LABEL: define <2 x i1> @icmp_mul_neq0_vec(1877; CHECK-SAME: <2 x i32> [[X:%.*]]) {1878; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X]], zeroinitializer1879; CHECK-NEXT: ret <2 x i1> [[CMP]]1880;1881 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>1882 %cmp = icmp ne <2 x i32> %mul, zeroinitializer1883 ret <2 x i1> %cmp1884}1885 1886define i1 @icmp_mul_eq0(i32 %x) {1887; CHECK-LABEL: define i1 @icmp_mul_eq0(1888; CHECK-SAME: i32 [[X:%.*]]) {1889; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 01890; CHECK-NEXT: ret i1 [[CMP]]1891;1892 %mul = mul nsw i32 %x, 121893 %cmp = icmp eq i32 %mul, 01894 ret i1 %cmp1895}1896 1897define i1 @icmp_mul0_eq0(i32 %x) {1898; CHECK-LABEL: define i1 @icmp_mul0_eq0(1899; CHECK-SAME: i32 [[X:%.*]]) {1900; CHECK-NEXT: ret i1 true1901;1902 %mul = mul i32 %x, 01903 %cmp = icmp eq i32 %mul, 01904 ret i1 %cmp1905}1906 1907define i1 @icmp_mul0_ne0(i32 %x) {1908; CHECK-LABEL: define i1 @icmp_mul0_ne0(1909; CHECK-SAME: i32 [[X:%.*]]) {1910; CHECK-NEXT: ret i1 false1911;1912 %mul = mul i32 %x, 01913 %cmp = icmp ne i32 %mul, 01914 ret i1 %cmp1915}1916 1917define i1 @icmp_add20_eq_add57(i32 %x, i32 %y) {1918; CHECK-LABEL: define i1 @icmp_add20_eq_add57(1919; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1920; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y]], 371921; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[TMP1]]1922; CHECK-NEXT: ret i1 [[CMP]]1923;1924 %1 = add i32 %x, 201925 %2 = add i32 %y, 571926 %cmp = icmp eq i32 %1, %21927 ret i1 %cmp1928}1929 1930define <2 x i1> @icmp_add20_eq_add57_splat(<2 x i32> %x, <2 x i32> %y) {1931; CHECK-LABEL: define <2 x i1> @icmp_add20_eq_add57_splat(1932; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {1933; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y]], splat (i32 37)1934; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X]], [[TMP1]]1935; CHECK-NEXT: ret <2 x i1> [[CMP]]1936;1937 %1 = add <2 x i32> %x, <i32 20, i32 20>1938 %2 = add <2 x i32> %y, <i32 57, i32 57>1939 %cmp = icmp eq <2 x i32> %1, %21940 ret <2 x i1> %cmp1941}1942 1943define <2 x i1> @icmp_add20_eq_add57_poison(<2 x i32> %x, <2 x i32> %y) {1944; CHECK-LABEL: define <2 x i1> @icmp_add20_eq_add57_poison(1945; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {1946; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y]], splat (i32 37)1947; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X]], [[TMP1]]1948; CHECK-NEXT: ret <2 x i1> [[CMP]]1949;1950 %1 = add <2 x i32> %x, <i32 20, i32 20>1951 %2 = add <2 x i32> %y, <i32 57, i32 poison>1952 %cmp = icmp eq <2 x i32> %1, %21953 ret <2 x i1> %cmp1954}1955 1956define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {1957; CHECK-LABEL: define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(1958; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {1959; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y]], <i32 37, i32 39>1960; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X]], [[TMP1]]1961; CHECK-NEXT: ret <2 x i1> [[CMP]]1962;1963 %1 = add <2 x i32> %x, <i32 20, i32 19>1964 %2 = add <2 x i32> %y, <i32 57, i32 58>1965 %cmp = icmp eq <2 x i32> %1, %21966 ret <2 x i1> %cmp1967}1968 1969define i1 @icmp_sub57_ne_sub20(i32 %x, i32 %y) {1970; CHECK-LABEL: define i1 @icmp_sub57_ne_sub20(1971; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {1972; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -371973; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[Y]]1974; CHECK-NEXT: ret i1 [[CMP]]1975;1976 %1 = add i32 %x, -571977 %2 = add i32 %y, -201978 %cmp = icmp ne i32 %1, %21979 ret i1 %cmp1980}1981 1982define <2 x i1> @icmp_sub57_ne_sub20_splat(<2 x i32> %x, <2 x i32> %y) {1983; CHECK-LABEL: define <2 x i1> @icmp_sub57_ne_sub20_splat(1984; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {1985; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 -37)1986; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y]]1987; CHECK-NEXT: ret <2 x i1> [[CMP]]1988;1989 %1 = add <2 x i32> %x, <i32 -57, i32 -57>1990 %2 = add <2 x i32> %y, <i32 -20, i32 -20>1991 %cmp = icmp ne <2 x i32> %1, %21992 ret <2 x i1> %cmp1993}1994 1995define <2 x i1> @icmp_sub57_ne_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) {1996; CHECK-LABEL: define <2 x i1> @icmp_sub57_ne_sub20_vec_poison(1997; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {1998; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 -37)1999; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y]]2000; CHECK-NEXT: ret <2 x i1> [[CMP]]2001;2002 %1 = add <2 x i32> %x, <i32 -57, i32 poison>2003 %2 = add <2 x i32> %y, <i32 -20, i32 poison>2004 %cmp = icmp ne <2 x i32> %1, %22005 ret <2 x i1> %cmp2006}2007 2008define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {2009; CHECK-LABEL: define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(2010; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2011; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y]], splat (i32 37)2012; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X]], [[TMP1]]2013; CHECK-NEXT: ret <2 x i1> [[CMP]]2014;2015 %1 = add <2 x i32> %x, <i32 -57, i32 -58>2016 %2 = add <2 x i32> %y, <i32 -20, i32 -21>2017 %cmp = icmp ne <2 x i32> %1, %22018 ret <2 x i1> %cmp2019}2020 2021define i1 @icmp_sub1_sge(i32 %x, i32 %y) {2022; CHECK-LABEL: define i1 @icmp_sub1_sge(2023; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2024; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]2025; CHECK-NEXT: ret i1 [[CMP]]2026;2027 %sub = add nsw i32 %x, -12028 %cmp = icmp sge i32 %sub, %y2029 ret i1 %cmp2030}2031 2032define i1 @icmp_add1_sgt(i32 %x, i32 %y) {2033; CHECK-LABEL: define i1 @icmp_add1_sgt(2034; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2035; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X]], [[Y]]2036; CHECK-NEXT: ret i1 [[CMP]]2037;2038 %add = add nsw i32 %x, 12039 %cmp = icmp sgt i32 %add, %y2040 ret i1 %cmp2041}2042 2043define i1 @icmp_sub1_slt(i32 %x, i32 %y) {2044; CHECK-LABEL: define i1 @icmp_sub1_slt(2045; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2046; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X]], [[Y]]2047; CHECK-NEXT: ret i1 [[CMP]]2048;2049 %sub = add nsw i32 %x, -12050 %cmp = icmp slt i32 %sub, %y2051 ret i1 %cmp2052}2053 2054define i1 @icmp_add1_sle(i32 %x, i32 %y) {2055; CHECK-LABEL: define i1 @icmp_add1_sle(2056; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2057; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], [[Y]]2058; CHECK-NEXT: ret i1 [[CMP]]2059;2060 %add = add nsw i32 %x, 12061 %cmp = icmp sle i32 %add, %y2062 ret i1 %cmp2063}2064 2065define i1 @icmp_slt_offset_with_common_divisor(i64 %x, i64 %y) {2066; CHECK-LABEL: define i1 @icmp_slt_offset_with_common_divisor(2067; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2068; CHECK-NEXT: [[SHLX:%.*]] = shl i64 [[X]], 42069; CHECK-NEXT: [[SHLY:%.*]] = shl i64 [[Y]], 42070; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[SHLX]], [[SHLY]]2071; CHECK-NEXT: ret i1 [[CMP]]2072;2073 %shlx = shl i64 %x, 42074 %shly = shl i64 %y, 42075 %shlx_offset = add nsw i64 %shlx, -162076 %cmp = icmp slt i64 %shlx_offset, %shly2077 ret i1 %cmp2078}2079 2080define i1 @icmp_slt_offset_with_smaller_common_divisor(i64 %x, i64 %y) {2081; CHECK-LABEL: define i1 @icmp_slt_offset_with_smaller_common_divisor(2082; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2083; CHECK-NEXT: [[SHLX:%.*]] = shl i64 [[X]], 42084; CHECK-NEXT: [[SHLY:%.*]] = shl i64 [[Y]], 42085; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[SHLX]], [[SHLY]]2086; CHECK-NEXT: ret i1 [[CMP]]2087;2088 %shlx = shl i64 %x, 42089 %shly = shl i64 %y, 42090 %shlx_offset = add nsw i64 %shlx, -82091 %cmp = icmp slt i64 %shlx_offset, %shly2092 ret i1 %cmp2093}2094 2095define i1 @icmp_sle_offset_with_common_divisor(i64 %x, i64 %y) {2096; CHECK-LABEL: define i1 @icmp_sle_offset_with_common_divisor(2097; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2098; CHECK-NEXT: [[SHLX:%.*]] = shl i64 [[X]], 42099; CHECK-NEXT: [[SHLY:%.*]] = shl i64 [[Y]], 42100; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[SHLX]], [[SHLY]]2101; CHECK-NEXT: ret i1 [[CMP]]2102;2103 %shlx = shl i64 %x, 42104 %shly = shl i64 %y, 42105 %shlx_offset = add nsw i64 %shlx, 162106 %cmp = icmp sle i64 %shlx_offset, %shly2107 ret i1 %cmp2108}2109 2110define i1 @icmp_ule_offset_with_common_divisor(i64 %x, i64 %y) {2111; CHECK-LABEL: define i1 @icmp_ule_offset_with_common_divisor(2112; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2113; CHECK-NEXT: [[SHLX:%.*]] = shl i64 [[X]], 42114; CHECK-NEXT: [[SHLY:%.*]] = shl i64 [[Y]], 42115; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHLX]], [[SHLY]]2116; CHECK-NEXT: ret i1 [[CMP]]2117;2118 %shlx = shl i64 %x, 42119 %shly = shl i64 %y, 42120 %shlx_offset = add nuw i64 %shlx, 162121 %cmp = icmp ule i64 %shlx_offset, %shly2122 ret i1 %cmp2123}2124 2125; TODO: Handle non-power-of-2 divisors2126define i1 @icmp_ule_offset_with_common_non_pow2_divisor(i64 %x, i64 %y) {2127; CHECK-LABEL: define i1 @icmp_ule_offset_with_common_non_pow2_divisor(2128; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2129; CHECK-NEXT: [[MULX:%.*]] = mul nuw i64 [[X]], 72130; CHECK-NEXT: [[MULY:%.*]] = mul nuw i64 [[Y]], 72131; CHECK-NEXT: [[MULX_OFFSET:%.*]] = add nuw i64 [[MULX]], 72132; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[MULX_OFFSET]], [[MULY]]2133; CHECK-NEXT: ret i1 [[CMP]]2134;2135 %mulx = mul nuw i64 %x, 72136 %muly = mul nuw i64 %y, 72137 %mulx_offset = add nuw i64 %mulx, 72138 %cmp = icmp ule i64 %mulx_offset, %muly2139 ret i1 %cmp2140}2141 2142define i1 @neg_icmp_slt_offset_without_common_divisor(i64 %x, i64 %y) {2143; CHECK-LABEL: define i1 @neg_icmp_slt_offset_without_common_divisor(2144; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2145; CHECK-NEXT: [[SHLX:%.*]] = shl i64 [[X]], 42146; CHECK-NEXT: [[SHLY:%.*]] = shl i64 [[Y]], 42147; CHECK-NEXT: [[SHLX_OFFSET:%.*]] = add nsw i64 [[SHLX]], -322148; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[SHLX_OFFSET]], [[SHLY]]2149; CHECK-NEXT: ret i1 [[CMP]]2150;2151 %shlx = shl i64 %x, 42152 %shly = shl i64 %y, 42153 %shlx_offset = add nsw i64 %shlx, -322154 %cmp = icmp slt i64 %shlx_offset, %shly2155 ret i1 %cmp2156}2157 2158define i1 @neg_icmp_slt_offset_with_wrong_sign(i64 %x, i64 %y) {2159; CHECK-LABEL: define i1 @neg_icmp_slt_offset_with_wrong_sign(2160; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {2161; CHECK-NEXT: [[SHLX:%.*]] = shl i64 [[X]], 42162; CHECK-NEXT: [[SHLY:%.*]] = shl i64 [[Y]], 42163; CHECK-NEXT: [[SHLX_OFFSET:%.*]] = add nsw i64 [[SHLX]], 162164; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[SHLX_OFFSET]], [[SHLY]]2165; CHECK-NEXT: ret i1 [[CMP]]2166;2167 %shlx = shl i64 %x, 42168 %shly = shl i64 %y, 42169 %shlx_offset = add nsw i64 %shlx, 162170 %cmp = icmp slt i64 %shlx_offset, %shly2171 ret i1 %cmp2172}2173 2174define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {2175; CHECK-LABEL: define i1 @icmp_add20_sge_add57(2176; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2177; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y]], 372178; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X]], [[TMP1]]2179; CHECK-NEXT: ret i1 [[CMP]]2180;2181 %1 = add nsw i32 %x, 202182 %2 = add nsw i32 %y, 572183 %cmp = icmp sge i32 %1, %22184 ret i1 %cmp2185}2186 2187define <2 x i1> @icmp_add20_sge_add57_splat(<2 x i32> %x, <2 x i32> %y) {2188; CHECK-LABEL: define <2 x i1> @icmp_add20_sge_add57_splat(2189; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2190; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[Y]], splat (i32 37)2191; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[X]], [[TMP1]]2192; CHECK-NEXT: ret <2 x i1> [[CMP]]2193;2194 %1 = add nsw <2 x i32> %x, <i32 20, i32 20>2195 %2 = add nsw <2 x i32> %y, <i32 57, i32 57>2196 %cmp = icmp sge <2 x i32> %1, %22197 ret <2 x i1> %cmp2198}2199 2200define <2 x i1> @icmp_add20_sge_add57_poison(<2 x i32> %x, <2 x i32> %y) {2201; CHECK-LABEL: define <2 x i1> @icmp_add20_sge_add57_poison(2202; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2203; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[Y]], splat (i32 37)2204; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[X]], [[TMP1]]2205; CHECK-NEXT: ret <2 x i1> [[CMP]]2206;2207 %1 = add nsw <2 x i32> %x, <i32 20, i32 20>2208 %2 = add nsw <2 x i32> %y, <i32 57, i32 poison>2209 %cmp = icmp sge <2 x i32> %1, %22210 ret <2 x i1> %cmp2211}2212 2213define <2 x i1> @icmp_add20_sge_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {2214; CHECK-LABEL: define <2 x i1> @icmp_add20_sge_add57_vec_nonsplat(2215; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2216; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X]], <i32 20, i32 19>2217; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i32> [[Y]], <i32 57, i32 58>2218; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]]2219; CHECK-NEXT: ret <2 x i1> [[CMP]]2220;2221 %1 = add nsw <2 x i32> %x, <i32 20, i32 19>2222 %2 = add nsw <2 x i32> %y, <i32 57, i32 58>2223 %cmp = icmp sge <2 x i32> %1, %22224 ret <2 x i1> %cmp2225}2226 2227define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {2228; CHECK-LABEL: define i1 @icmp_sub57_sge_sub20(2229; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2230; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X]], -372231; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y]]2232; CHECK-NEXT: ret i1 [[CMP]]2233;2234 %1 = add nsw i32 %x, -572235 %2 = add nsw i32 %y, -202236 %cmp = icmp sge i32 %1, %22237 ret i1 %cmp2238}2239 2240define <2 x i1> @icmp_sub57_sge_sub20_splat(<2 x i32> %x, <2 x i32> %y) {2241; CHECK-LABEL: define <2 x i1> @icmp_sub57_sge_sub20_splat(2242; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2243; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X]], splat (i32 -37)2244; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y]]2245; CHECK-NEXT: ret <2 x i1> [[CMP]]2246;2247 %1 = add nsw <2 x i32> %x, <i32 -57, i32 -57>2248 %2 = add nsw <2 x i32> %y, <i32 -20, i32 -20>2249 %cmp = icmp sge <2 x i32> %1, %22250 ret <2 x i1> %cmp2251}2252 2253define <2 x i1> @icmp_sub57_sge_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) {2254; CHECK-LABEL: define <2 x i1> @icmp_sub57_sge_sub20_vec_poison(2255; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2256; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X]], splat (i32 -37)2257; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y]]2258; CHECK-NEXT: ret <2 x i1> [[CMP]]2259;2260 %1 = add nsw <2 x i32> %x, <i32 -57, i32 poison>2261 %2 = add nsw <2 x i32> %y, <i32 -20, i32 poison>2262 %cmp = icmp sge <2 x i32> %1, %22263 ret <2 x i1> %cmp2264}2265 2266define <2 x i1> @icmp_sub57_sge_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {2267; CHECK-LABEL: define <2 x i1> @icmp_sub57_sge_sub20_vec_nonsplat(2268; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {2269; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X]], <i32 -57, i32 -58>2270; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i32> [[Y]], <i32 -20, i32 -21>2271; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]]2272; CHECK-NEXT: ret <2 x i1> [[CMP]]2273;2274 %1 = add nsw <2 x i32> %x, <i32 -57, i32 -58>2275 %2 = add nsw <2 x i32> %y, <i32 -20, i32 -21>2276 %cmp = icmp sge <2 x i32> %1, %22277 ret <2 x i1> %cmp2278}2279 2280define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {2281; CHECK-LABEL: define i1 @icmp_and_shl_neg_ne_0(2282; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {2283; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B]]2284; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A]]2285; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 02286; CHECK-NEXT: ret i1 [[CMP]]2287;2288 %neg = xor i32 %A, -12289 %shl = shl i32 1, %B2290 %and = and i32 %shl, %neg2291 %cmp = icmp ne i32 %and, 02292 ret i1 %cmp2293}2294 2295define i1 @icmp_and_shl_neg_ne_0_shl2_no_flags(i32 %A, i32 %B) {2296; CHECK-LABEL: define i1 @icmp_and_shl_neg_ne_0_shl2_no_flags(2297; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {2298; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[A]], -12299; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[B]]2300; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[NEG]]2301; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 02302; CHECK-NEXT: ret i1 [[CMP]]2303;2304 %neg = xor i32 %A, -12305 %shl = shl i32 2, %B2306 %and = and i32 %shl, %neg2307 %cmp = icmp ne i32 %and, 02308 ret i1 %cmp2309}2310 2311define i1 @icmp_and_shl_neg_ne_0_shl2_nuw(i32 %A, i32 %B) {2312; CHECK-LABEL: define i1 @icmp_and_shl_neg_ne_0_shl2_nuw(2313; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {2314; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 2, [[B]]2315; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A]]2316; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 02317; CHECK-NEXT: ret i1 [[CMP]]2318;2319 %neg = xor i32 %A, -12320 %shl = shl nuw i32 2, %B2321 %and = and i32 %shl, %neg2322 %cmp = icmp ne i32 %and, 02323 ret i1 %cmp2324}2325 2326define i1 @icmp_and_shl_neg_ne_0_shl2_nsw(i32 %A, i32 %B) {2327; CHECK-LABEL: define i1 @icmp_and_shl_neg_ne_0_shl2_nsw(2328; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {2329; CHECK-NEXT: [[SHL:%.*]] = shl nsw i32 2, [[B]]2330; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A]]2331; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 02332; CHECK-NEXT: ret i1 [[CMP]]2333;2334 %neg = xor i32 %A, -12335 %shl = shl nsw i32 2, %B2336 %and = and i32 %shl, %neg2337 %cmp = icmp ne i32 %and, 02338 ret i1 %cmp2339}2340 2341define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {2342; CHECK-LABEL: define i1 @icmp_and_shl_neg_eq_0(2343; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {2344; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B]]2345; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A]]2346; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 02347; CHECK-NEXT: ret i1 [[CMP]]2348;2349 %neg = xor i32 %A, -12350 %shl = shl i32 1, %B2351 %and = and i32 %shl, %neg2352 %cmp = icmp eq i32 %and, 02353 ret i1 %cmp2354}2355 2356define i1 @icmp_add_and_shr_ne_0(i32 %X) {2357; CHECK-LABEL: define i1 @icmp_add_and_shr_ne_0(2358; CHECK-SAME: i32 [[X:%.*]]) {2359; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], 2402360; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 2242361; CHECK-NEXT: ret i1 [[TOBOOL]]2362;2363 %shr = lshr i32 %X, 42364 %and = and i32 %shr, 152365 %add = add i32 %and, -142366 %tobool = icmp ne i32 %add, 02367 ret i1 %tobool2368}2369 2370define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {2371; CHECK-LABEL: define <2 x i1> @icmp_add_and_shr_ne_0_vec(2372; CHECK-SAME: <2 x i32> [[X:%.*]]) {2373; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 240)2374; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 224)2375; CHECK-NEXT: ret <2 x i1> [[TOBOOL]]2376;2377 %shr = lshr <2 x i32> %X, <i32 4, i32 4>2378 %and = and <2 x i32> %shr, <i32 15, i32 15>2379 %add = add <2 x i32> %and, <i32 -14, i32 -14>2380 %tobool = icmp ne <2 x i32> %add, zeroinitializer2381 ret <2 x i1> %tobool2382}2383 2384; Variation of the above with an extra use of the shift2385define i1 @icmp_and_shr_multiuse(i32 %X) {2386; CHECK-LABEL: define i1 @icmp_and_shr_multiuse(2387; CHECK-SAME: i32 [[X:%.*]]) {2388; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], 2402389; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 2242390; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 4962391; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 4322392; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]2393; CHECK-NEXT: ret i1 [[AND3]]2394;2395 %shr = lshr i32 %X, 42396 %and = and i32 %shr, 152397 %and2 = and i32 %shr, 31 ; second use of the shift2398 %tobool = icmp ne i32 %and, 142399 %tobool2 = icmp ne i32 %and2, 272400 %and3 = and i1 %tobool, %tobool22401 ret i1 %and32402}2403 2404define i1 @icmp_and_shr_multiuse_logical(i32 %X) {2405; CHECK-LABEL: define i1 @icmp_and_shr_multiuse_logical(2406; CHECK-SAME: i32 [[X:%.*]]) {2407; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], 2402408; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 2242409; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 4962410; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 4322411; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]2412; CHECK-NEXT: ret i1 [[AND3]]2413;2414 %shr = lshr i32 %X, 42415 %and = and i32 %shr, 152416 %and2 = and i32 %shr, 31 ; second use of the shift2417 %tobool = icmp ne i32 %and, 142418 %tobool2 = icmp ne i32 %and2, 272419 %and3 = select i1 %tobool, i1 %tobool2, i1 false2420 ret i1 %and32421}2422 2423; Variation of the above with an ashr2424define i1 @icmp_and_ashr_multiuse(i32 %X) {2425; CHECK-LABEL: define i1 @icmp_and_ashr_multiuse(2426; CHECK-SAME: i32 [[X:%.*]]) {2427; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], 2402428; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 2242429; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 4962430; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 4322431; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]2432; CHECK-NEXT: ret i1 [[AND3]]2433;2434 %shr = ashr i32 %X, 42435 %and = and i32 %shr, 152436 %and2 = and i32 %shr, 31 ; second use of the shift2437 %tobool = icmp ne i32 %and, 142438 %tobool2 = icmp ne i32 %and2, 272439 %and3 = and i1 %tobool, %tobool22440 ret i1 %and32441}2442 2443define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {2444; CHECK-LABEL: define i1 @icmp_and_ashr_multiuse_logical(2445; CHECK-SAME: i32 [[X:%.*]]) {2446; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], 2402447; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 2242448; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 4962449; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 4322450; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]2451; CHECK-NEXT: ret i1 [[AND3]]2452;2453 %shr = ashr i32 %X, 42454 %and = and i32 %shr, 152455 %and2 = and i32 %shr, 31 ; second use of the shift2456 %tobool = icmp ne i32 %and, 142457 %tobool2 = icmp ne i32 %and2, 272458 %and3 = select i1 %tobool, i1 %tobool2, i1 false2459 ret i1 %and32460}2461 2462define i1 @icmp_lshr_and_overshift(i8 %X) {2463; CHECK-LABEL: define i1 @icmp_lshr_and_overshift(2464; CHECK-SAME: i8 [[X:%.*]]) {2465; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X]], 312466; CHECK-NEXT: ret i1 [[TOBOOL]]2467;2468 %shr = lshr i8 %X, 52469 %and = and i8 %shr, 152470 %tobool = icmp ne i8 %and, 02471 ret i1 %tobool2472}2473 2474; We shouldn't simplify this because the and uses bits that are shifted in.2475define i1 @icmp_ashr_and_overshift(i8 %X) {2476; CHECK-LABEL: define i1 @icmp_ashr_and_overshift(2477; CHECK-SAME: i8 [[X:%.*]]) {2478; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X]], 52479; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 152480; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 02481; CHECK-NEXT: ret i1 [[TOBOOL]]2482;2483 %shr = ashr i8 %X, 52484 %and = and i8 %shr, 152485 %tobool = icmp ne i8 %and, 02486 ret i1 %tobool2487}2488 2489define i1 @icmp_and_ashr_neg_and_legal(i8 %x) {2490; CHECK-LABEL: define i1 @icmp_and_ashr_neg_and_legal(2491; CHECK-SAME: i8 [[X:%.*]]) {2492; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X]], 322493; CHECK-NEXT: ret i1 [[CMP]]2494;2495 %ashr = ashr i8 %x, 42496 %and = and i8 %ashr, -22497 %cmp = icmp slt i8 %and, 12498 ret i1 %cmp2499}2500 2501; Negative test.2502define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) {2503; CHECK-LABEL: define i1 @icmp_and_ashr_mixed_and_shiftout(2504; CHECK-SAME: i8 [[X:%.*]]) {2505; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 42506; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], 312507; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i8 [[AND]], 82508; CHECK-NEXT: ret i1 [[CMP]]2509;2510 %ashr = ashr i8 %x, 42511 %and = and i8 %ashr, 312512 %cmp = icmp ugt i8 %and, 82513 ret i1 %cmp2514}2515 2516define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) {2517; CHECK-LABEL: define i1 @icmp_and_ashr_neg_cmp_slt_legal(2518; CHECK-SAME: i8 [[X:%.*]]) {2519; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -322520; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], -642521; CHECK-NEXT: ret i1 [[CMP]]2522;2523 %ashr = ashr i8 %x, 42524 %and = and i8 %ashr, -22525 %cmp = icmp slt i8 %and, -42526 ret i1 %cmp2527}2528 2529; Negative test.2530define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) {2531; CHECK-LABEL: define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(2532; CHECK-SAME: i8 [[X:%.*]]) {2533; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 42534; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], -22535; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], -682536; CHECK-NEXT: ret i1 [[CMP]]2537;2538 %ashr = ashr i8 %x, 42539 %and = and i8 %ashr, -22540 %cmp = icmp slt i8 %and, -682541 ret i1 %cmp2542}2543 2544define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) {2545; CHECK-LABEL: define i1 @icmp_and_ashr_neg_cmp_eq_legal(2546; CHECK-SAME: i8 [[X:%.*]]) {2547; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -322548; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], -642549; CHECK-NEXT: ret i1 [[CMP]]2550;2551 %ashr = ashr i8 %x, 42552 %and = and i8 %ashr, -22553 %cmp = icmp eq i8 %and, -42554 ret i1 %cmp2555}2556 2557define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) {2558; CHECK-LABEL: define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(2559; CHECK-SAME: i8 [[X:%.*]]) {2560; CHECK-NEXT: ret i1 false2561;2562 %ashr = ashr i8 %x, 42563 %and = and i8 %ashr, -22564 %cmp = icmp eq i8 %and, -682565 ret i1 %cmp2566}2567 2568define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) {2569; CHECK-LABEL: define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(2570; CHECK-SAME: i8 [[X:%.*]]) {2571; CHECK-NEXT: ret i1 true2572;2573 %ashr = ashr i8 %x, 42574 %and = and i8 %ashr, -22575 %cmp = icmp ne i8 %and, -682576 ret i1 %cmp2577}2578 2579define i1 @icmp_shl_1_V_ult_32(i32 %V) {2580; CHECK-LABEL: define i1 @icmp_shl_1_V_ult_32(2581; CHECK-SAME: i32 [[V:%.*]]) {2582; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V]], 52583; CHECK-NEXT: ret i1 [[CMP]]2584;2585 %shl = shl i32 1, %V2586 %cmp = icmp ult i32 %shl, 322587 ret i1 %cmp2588}2589 2590define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {2591; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_ult_32_vec(2592; CHECK-SAME: <2 x i32> [[V:%.*]]) {2593; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V]], splat (i32 5)2594; CHECK-NEXT: ret <2 x i1> [[CMP]]2595;2596 %shl = shl <2 x i32> <i32 1, i32 1>, %V2597 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>2598 ret <2 x i1> %cmp2599}2600 2601define i1 @icmp_shl_1_V_eq_32(i32 %V) {2602; CHECK-LABEL: define i1 @icmp_shl_1_V_eq_32(2603; CHECK-SAME: i32 [[V:%.*]]) {2604; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 52605; CHECK-NEXT: ret i1 [[CMP]]2606;2607 %shl = shl i32 1, %V2608 %cmp = icmp eq i32 %shl, 322609 ret i1 %cmp2610}2611 2612define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {2613; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_eq_32_vec(2614; CHECK-SAME: <2 x i32> [[V:%.*]]) {2615; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V]], splat (i32 5)2616; CHECK-NEXT: ret <2 x i1> [[CMP]]2617;2618 %shl = shl <2 x i32> <i32 1, i32 1>, %V2619 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>2620 ret <2 x i1> %cmp2621}2622 2623define i1 @icmp_shl_1_V_ult_30(i32 %V) {2624; CHECK-LABEL: define i1 @icmp_shl_1_V_ult_30(2625; CHECK-SAME: i32 [[V:%.*]]) {2626; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V]], 52627; CHECK-NEXT: ret i1 [[CMP]]2628;2629 %shl = shl i32 1, %V2630 %cmp = icmp ult i32 %shl, 302631 ret i1 %cmp2632}2633 2634define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {2635; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_ult_30_vec(2636; CHECK-SAME: <2 x i32> [[V:%.*]]) {2637; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V]], splat (i32 5)2638; CHECK-NEXT: ret <2 x i1> [[CMP]]2639;2640 %shl = shl <2 x i32> <i32 1, i32 1>, %V2641 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>2642 ret <2 x i1> %cmp2643}2644 2645define i1 @icmp_shl_1_V_ugt_30(i32 %V) {2646; CHECK-LABEL: define i1 @icmp_shl_1_V_ugt_30(2647; CHECK-SAME: i32 [[V:%.*]]) {2648; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V]], 42649; CHECK-NEXT: ret i1 [[CMP]]2650;2651 %shl = shl i32 1, %V2652 %cmp = icmp ugt i32 %shl, 302653 ret i1 %cmp2654}2655 2656define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {2657; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_ugt_30_vec(2658; CHECK-SAME: <2 x i32> [[V:%.*]]) {2659; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V]], splat (i32 4)2660; CHECK-NEXT: ret <2 x i1> [[CMP]]2661;2662 %shl = shl <2 x i32> <i32 1, i32 1>, %V2663 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>2664 ret <2 x i1> %cmp2665}2666 2667define i1 @icmp_shl_1_V_ule_30(i32 %V) {2668; CHECK-LABEL: define i1 @icmp_shl_1_V_ule_30(2669; CHECK-SAME: i32 [[V:%.*]]) {2670; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V]], 52671; CHECK-NEXT: ret i1 [[CMP]]2672;2673 %shl = shl i32 1, %V2674 %cmp = icmp ule i32 %shl, 302675 ret i1 %cmp2676}2677 2678define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {2679; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_ule_30_vec(2680; CHECK-SAME: <2 x i32> [[V:%.*]]) {2681; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V]], splat (i32 5)2682; CHECK-NEXT: ret <2 x i1> [[CMP]]2683;2684 %shl = shl <2 x i32> <i32 1, i32 1>, %V2685 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>2686 ret <2 x i1> %cmp2687}2688 2689define i1 @icmp_shl_1_V_uge_30(i32 %V) {2690; CHECK-LABEL: define i1 @icmp_shl_1_V_uge_30(2691; CHECK-SAME: i32 [[V:%.*]]) {2692; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V]], 42693; CHECK-NEXT: ret i1 [[CMP]]2694;2695 %shl = shl i32 1, %V2696 %cmp = icmp uge i32 %shl, 302697 ret i1 %cmp2698}2699 2700define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {2701; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_uge_30_vec(2702; CHECK-SAME: <2 x i32> [[V:%.*]]) {2703; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V]], splat (i32 4)2704; CHECK-NEXT: ret <2 x i1> [[CMP]]2705;2706 %shl = shl <2 x i32> <i32 1, i32 1>, %V2707 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>2708 ret <2 x i1> %cmp2709}2710 2711define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {2712; CHECK-LABEL: define i1 @icmp_shl_1_V_uge_2147483648(2713; CHECK-SAME: i32 [[V:%.*]]) {2714; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 312715; CHECK-NEXT: ret i1 [[CMP]]2716;2717 %shl = shl i32 1, %V2718 %cmp = icmp uge i32 %shl, 21474836482719 ret i1 %cmp2720}2721 2722define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {2723; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(2724; CHECK-SAME: <2 x i32> [[V:%.*]]) {2725; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V]], splat (i32 31)2726; CHECK-NEXT: ret <2 x i1> [[CMP]]2727;2728 %shl = shl <2 x i32> <i32 1, i32 1>, %V2729 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>2730 ret <2 x i1> %cmp2731}2732 2733define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {2734; CHECK-LABEL: define i1 @icmp_shl_1_V_ult_2147483648(2735; CHECK-SAME: i32 [[V:%.*]]) {2736; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V]], 312737; CHECK-NEXT: ret i1 [[CMP]]2738;2739 %shl = shl i32 1, %V2740 %cmp = icmp ult i32 %shl, 21474836482741 ret i1 %cmp2742}2743 2744define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {2745; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(2746; CHECK-SAME: <2 x i32> [[V:%.*]]) {2747; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V]], splat (i32 31)2748; CHECK-NEXT: ret <2 x i1> [[CMP]]2749;2750 %shl = shl <2 x i32> <i32 1, i32 1>, %V2751 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>2752 ret <2 x i1> %cmp2753}2754 2755define i1 @icmp_shl_1_V_sle_0(i32 %V) {2756; CHECK-LABEL: define i1 @icmp_shl_1_V_sle_0(2757; CHECK-SAME: i32 [[V:%.*]]) {2758; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 312759; CHECK-NEXT: ret i1 [[CMP]]2760;2761 %shl = shl i32 1, %V2762 %cmp = icmp sle i32 %shl, 02763 ret i1 %cmp2764}2765 2766define <2 x i1> @icmp_shl_1_V_sle_0_vec(<2 x i32> %V) {2767; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_sle_0_vec(2768; CHECK-SAME: <2 x i32> [[V:%.*]]) {2769; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V]], splat (i32 31)2770; CHECK-NEXT: ret <2 x i1> [[CMP]]2771;2772 %shl = shl <2 x i32> <i32 1, i32 1>, %V2773 %cmp = icmp sle <2 x i32> %shl, <i32 0, i32 0>2774 ret <2 x i1> %cmp2775}2776 2777define i1 @icmp_shl_1_V_sle_negative(i32 %V) {2778; CHECK-LABEL: define i1 @icmp_shl_1_V_sle_negative(2779; CHECK-SAME: i32 [[V:%.*]]) {2780; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 312781; CHECK-NEXT: ret i1 [[CMP]]2782;2783 %shl = shl i32 1, %V2784 %cmp = icmp sle i32 %shl, -422785 ret i1 %cmp2786}2787 2788define <2 x i1> @icmp_shl_1_V_sle_0_negative(<2 x i32> %V) {2789; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_sle_0_negative(2790; CHECK-SAME: <2 x i32> [[V:%.*]]) {2791; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V]], splat (i32 31)2792; CHECK-NEXT: ret <2 x i1> [[CMP]]2793;2794 %shl = shl <2 x i32> <i32 1, i32 1>, %V2795 %cmp = icmp sle <2 x i32> %shl, <i32 -2147483647, i32 -2147483647>2796 ret <2 x i1> %cmp2797}2798 2799define i1 @icmp_shl_1_V_sgt_0(i32 %V) {2800; CHECK-LABEL: define i1 @icmp_shl_1_V_sgt_0(2801; CHECK-SAME: i32 [[V:%.*]]) {2802; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V]], 312803; CHECK-NEXT: ret i1 [[CMP]]2804;2805 %shl = shl i32 1, %V2806 %cmp = icmp sgt i32 %shl, 02807 ret i1 %cmp2808}2809 2810define <2 x i1> @icmp_shl_1_V_sgt_0_vec(<2 x i32> %V) {2811; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_sgt_0_vec(2812; CHECK-SAME: <2 x i32> [[V:%.*]]) {2813; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V]], splat (i32 31)2814; CHECK-NEXT: ret <2 x i1> [[CMP]]2815;2816 %shl = shl <2 x i32> <i32 1, i32 1>, %V2817 %cmp = icmp sgt <2 x i32> %shl, <i32 0, i32 0>2818 ret <2 x i1> %cmp2819}2820 2821define i1 @icmp_shl_1_V_sgt_negative(i32 %V) {2822; CHECK-LABEL: define i1 @icmp_shl_1_V_sgt_negative(2823; CHECK-SAME: i32 [[V:%.*]]) {2824; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V]], 312825; CHECK-NEXT: ret i1 [[CMP]]2826;2827 %shl = shl i32 1, %V2828 %cmp = icmp sgt i32 %shl, -123452829 ret i1 %cmp2830}2831 2832define <2 x i1> @icmp_shl_1_V_sgt_negative_vec(<2 x i32> %V) {2833; CHECK-LABEL: define <2 x i1> @icmp_shl_1_V_sgt_negative_vec(2834; CHECK-SAME: <2 x i32> [[V:%.*]]) {2835; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V]], splat (i32 31)2836; CHECK-NEXT: ret <2 x i1> [[CMP]]2837;2838 %shl = shl <2 x i32> <i32 1, i32 1>, %V2839 %cmp = icmp sgt <2 x i32> %shl, <i32 -2, i32 -2>2840 ret <2 x i1> %cmp2841}2842 2843define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {2844; CHECK-LABEL: define i1 @or_icmp_eq_B_0_icmp_ult_A_B(2845; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2846; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B]], -12847; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A]]2848; CHECK-NEXT: ret i1 [[TMP2]]2849;2850 %1 = icmp eq i64 %b, 02851 %2 = icmp ult i64 %a, %b2852 %3 = or i1 %1, %22853 ret i1 %32854}2855 2856define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {2857; CHECK-LABEL: define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(2858; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2859; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A]]2860; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -12861; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i64 [[TMP2]], [[TMP1]]2862; CHECK-NEXT: ret i1 [[TMP3]]2863;2864 %1 = icmp eq i64 %b, 02865 %2 = icmp ult i64 %a, %b2866 %3 = select i1 %1, i1 true, i1 %22867 ret i1 %32868}2869 2870define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {2871; CHECK-LABEL: define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(2872; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {2873; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B]], splat (i64 -1)2874; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A]]2875; CHECK-NEXT: ret <2 x i1> [[TMP2]]2876;2877 %1 = icmp eq <2 x i64> %b, zeroinitializer2878 %2 = icmp ult <2 x i64> %a, %b2879 %3 = or <2 x i1> %1, %22880 ret <2 x i1> %32881}2882 2883define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_poison(<2 x i64> %a, <2 x i64> %b) {2884; CHECK-LABEL: define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_poison(2885; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {2886; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B]], splat (i64 -1)2887; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A]]2888; CHECK-NEXT: ret <2 x i1> [[TMP2]]2889;2890 %1 = icmp eq <2 x i64> %b, <i64 0, i64 poison>2891 %2 = icmp ult <2 x i64> %a, %b2892 %3 = or <2 x i1> %1, %22893 ret <2 x i1> %32894}2895 2896define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {2897; CHECK-LABEL: define i1 @or_icmp_ne_A_0_icmp_ne_B_0(2898; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2899; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A]], [[B]]2900; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 02901; CHECK-NEXT: ret i1 [[TMP2]]2902;2903 %1 = icmp ne i64 %a, 02904 %2 = icmp ne i64 %b, 02905 %3 = or i1 %1, %22906 ret i1 %32907}2908 2909define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {2910; CHECK-LABEL: define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(2911; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2912; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[A]], 02913; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[B]], 02914; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]2915; CHECK-NEXT: ret i1 [[TMP3]]2916;2917 %1 = icmp ne i64 %a, 02918 %2 = icmp ne i64 %b, 02919 %3 = select i1 %1, i1 true, i1 %22920 ret i1 %32921}2922 2923define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {2924; CHECK-LABEL: define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(2925; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {2926; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A]], [[B]]2927; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer2928; CHECK-NEXT: ret <2 x i1> [[TMP2]]2929;2930 %1 = icmp ne <2 x i64> %a, zeroinitializer2931 %2 = icmp ne <2 x i64> %b, zeroinitializer2932 %3 = or <2 x i1> %1, %22933 ret <2 x i1> %32934}2935 2936define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_poison(<2 x i64> %a, <2 x i64> %b) {2937; CHECK-LABEL: define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_poison(2938; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {2939; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A]], [[B]]2940; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer2941; CHECK-NEXT: ret <2 x i1> [[TMP2]]2942;2943 %1 = icmp ne <2 x i64> %a, <i64 0, i64 poison>2944 %2 = icmp ne <2 x i64> %b, <i64 0, i64 poison>2945 %3 = or <2 x i1> %1, %22946 ret <2 x i1> %32947}2948 2949define i1 @and_icmp_ne_B_0_icmp_uge_A_B(i64 %a, i64 %b) {2950; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B(2951; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2952; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B]], -12953; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A]]2954; CHECK-NEXT: ret i1 [[TMP2]]2955;2956 %1 = icmp ne i64 %b, 02957 %2 = icmp uge i64 %a, %b2958 %3 = and i1 %1, %22959 ret i1 %32960}2961 2962define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(i64 %a, i64 %b) {2963; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(2964; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2965; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B]], -12966; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A]]2967; CHECK-NEXT: ret i1 [[TMP2]]2968;2969 %1 = icmp uge i64 %a, %b2970 %2 = icmp ne i64 %b, 02971 %3 = and i1 %1, %22972 ret i1 %32973}2974 2975define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(i64 %a, i64 %b) {2976; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(2977; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2978; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B]], -12979; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A]]2980; CHECK-NEXT: ret i1 [[TMP2]]2981;2982 %1 = icmp ne i64 %b, 02983 %2 = icmp ule i64 %b, %a2984 %3 = and i1 %1, %22985 ret i1 %32986}2987 2988define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(i64 %a, i64 %b) {2989; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(2990; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {2991; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B]], -12992; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A]]2993; CHECK-NEXT: ret i1 [[TMP2]]2994;2995 %1 = icmp uge i64 %a, %b2996 %2 = icmp ne i64 %b, 02997 %3 = select i1 %1, i1 %2, i1 false2998 ret i1 %32999}3000 3001define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(i64 %a, i64 %b) {3002; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(3003; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3004; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A]]3005; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -13006; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]3007; CHECK-NEXT: ret i1 [[TMP3]]3008;3009 %1 = icmp ne i64 %b, 03010 %2 = icmp ule i64 %b, %a3011 %3 = select i1 %1, i1 %2, i1 false3012 ret i1 %33013}3014 3015define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(i64 %a, i64 %b) {3016; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(3017; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3018; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B]], 03019; CHECK-NEXT: call void @use_i1(i1 [[TMP1]])3020; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -13021; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A]]3022; CHECK-NEXT: ret i1 [[TMP3]]3023;3024 %1 = icmp ne i64 %b, 03025 call void @use_i1(i1 %1)3026 %2 = icmp uge i64 %a, %b3027 %3 = and i1 %1, %23028 ret i1 %33029}3030 3031define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(i64 %a, i64 %b) {3032; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(3033; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3034; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[A]], [[B]]3035; CHECK-NEXT: call void @use_i1(i1 [[TMP1]])3036; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -13037; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A]]3038; CHECK-NEXT: ret i1 [[TMP3]]3039;3040 %1 = icmp ne i64 %b, 03041 %2 = icmp uge i64 %a, %b3042 call void @use_i1(i1 %2)3043 %3 = and i1 %1, %23044 ret i1 %33045}3046 3047define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(i64 %a, i64 %b) {3048; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(3049; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3050; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B]], 03051; CHECK-NEXT: call void @use_i1(i1 [[TMP1]])3052; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A]], [[B]]3053; CHECK-NEXT: call void @use_i1(i1 [[TMP2]])3054; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]3055; CHECK-NEXT: ret i1 [[TMP3]]3056;3057 %1 = icmp ne i64 %b, 03058 call void @use_i1(i1 %1)3059 %2 = icmp uge i64 %a, %b3060 call void @use_i1(i1 %2)3061 %3 = and i1 %1, %23062 ret i1 %33063}3064 3065define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(i64 %a, i64 %b) {3066; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(3067; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3068; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[B]], 03069; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A]], [[B]]3070; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]3071; CHECK-NEXT: ret i1 [[TMP3]]3072;3073 %1 = icmp sgt i64 %b, 03074 %2 = icmp uge i64 %a, %b3075 %3 = and i1 %1, %23076 ret i1 %33077}3078 3079define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(i64 %a, i64 %b) {3080; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(3081; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3082; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B]], 03083; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[A]], [[B]]3084; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]3085; CHECK-NEXT: ret i1 [[TMP3]]3086;3087 %1 = icmp ne i64 %b, 03088 %2 = icmp ugt i64 %a, %b3089 %3 = and i1 %1, %23090 ret i1 %33091}3092 3093define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(i64 %a, i64 %b) {3094; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(3095; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3096; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B]], 13097; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A]], [[B]]3098; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]3099; CHECK-NEXT: ret i1 [[TMP3]]3100;3101 %1 = icmp ne i64 %b, 13102 %2 = icmp uge i64 %a, %b3103 %3 = and i1 %1, %23104 ret i1 %33105}3106 3107define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(i64 %a, i64 %b, i64 %c) {3108; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(3109; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) {3110; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B]], 03111; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A]], [[C]]3112; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]3113; CHECK-NEXT: ret i1 [[TMP3]]3114;3115 %1 = icmp ne i64 %b, 03116 %2 = icmp uge i64 %a, %c3117 %3 = and i1 %1, %23118 ret i1 %33119}3120 3121define i1 @and_icmp_ne_B_0_icmp_uge_A_B_logical(i64 %a, i64 %b) {3122; CHECK-LABEL: define i1 @and_icmp_ne_B_0_icmp_uge_A_B_logical(3123; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3124; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A]]3125; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -13126; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]3127; CHECK-NEXT: ret i1 [[TMP3]]3128;3129 %1 = icmp ne i64 %b, 03130 %2 = icmp uge i64 %a, %b3131 %3 = select i1 %1, i1 %2, i1 false3132 ret i1 %33133}3134 3135define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {3136; CHECK-LABEL: define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_uniform(3137; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {3138; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B]], splat (i64 -1)3139; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A]]3140; CHECK-NEXT: ret <2 x i1> [[TMP2]]3141;3142 %1 = icmp ne <2 x i64> %b, zeroinitializer3143 %2 = icmp uge <2 x i64> %a, %b3144 %3 = and <2 x i1> %1, %23145 ret <2 x i1> %33146}3147 3148define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_poison(<2 x i64> %a, <2 x i64> %b) {3149; CHECK-LABEL: define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_poison(3150; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {3151; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B]], splat (i64 -1)3152; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A]]3153; CHECK-NEXT: ret <2 x i1> [[TMP2]]3154;3155 %1 = icmp ne <2 x i64> %b, <i64 0, i64 poison>3156 %2 = icmp uge <2 x i64> %a, %b3157 %3 = and <2 x i1> %1, %23158 ret <2 x i1> %33159}3160 3161define i1 @icmp_add_ult_2(i32 %X) {3162; CHECK-LABEL: define i1 @icmp_add_ult_2(3163; CHECK-SAME: i32 [[X:%.*]]) {3164; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -23165; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 143166; CHECK-NEXT: ret i1 [[CMP]]3167;3168 %add = add i32 %X, -143169 %cmp = icmp ult i32 %add, 23170 ret i1 %cmp3171}3172 3173define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {3174; CHECK-LABEL: define <2 x i1> @icmp_add_X_-14_ult_2_vec(3175; CHECK-SAME: <2 x i32> [[X:%.*]]) {3176; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 -2)3177; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 14)3178; CHECK-NEXT: ret <2 x i1> [[CMP]]3179;3180 %add = add <2 x i32> %X, <i32 -14, i32 -14>3181 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>3182 ret <2 x i1> %cmp3183}3184 3185define i1 @icmp_sub_3_X_ult_2(i32 %X) {3186; CHECK-LABEL: define i1 @icmp_sub_3_X_ult_2(3187; CHECK-SAME: i32 [[X:%.*]]) {3188; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -23189; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 23190; CHECK-NEXT: ret i1 [[CMP]]3191;3192 %add = sub i32 3, %X3193 %cmp = icmp ult i32 %add, 23194 ret i1 %cmp3195}3196 3197define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {3198; CHECK-LABEL: define <2 x i1> @icmp_sub_3_X_ult_2_vec(3199; CHECK-SAME: <2 x i32> [[X:%.*]]) {3200; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 -2)3201; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 2)3202; CHECK-NEXT: ret <2 x i1> [[CMP]]3203;3204 %add = sub <2 x i32> <i32 3, i32 3>, %X3205 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>3206 ret <2 x i1> %cmp3207}3208 3209define i1 @icmp_add_X_-14_uge_2(i32 %X) {3210; CHECK-LABEL: define i1 @icmp_add_X_-14_uge_2(3211; CHECK-SAME: i32 [[X:%.*]]) {3212; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -23213; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 143214; CHECK-NEXT: ret i1 [[CMP]]3215;3216 %add = add i32 %X, -143217 %cmp = icmp uge i32 %add, 23218 ret i1 %cmp3219}3220 3221define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {3222; CHECK-LABEL: define <2 x i1> @icmp_add_X_-14_uge_2_vec(3223; CHECK-SAME: <2 x i32> [[X:%.*]]) {3224; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 -2)3225; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 14)3226; CHECK-NEXT: ret <2 x i1> [[CMP]]3227;3228 %add = add <2 x i32> %X, <i32 -14, i32 -14>3229 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>3230 ret <2 x i1> %cmp3231}3232 3233define i1 @icmp_sub_3_X_uge_2(i32 %X) {3234; CHECK-LABEL: define i1 @icmp_sub_3_X_uge_2(3235; CHECK-SAME: i32 [[X:%.*]]) {3236; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -23237; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 23238; CHECK-NEXT: ret i1 [[CMP]]3239;3240 %add = sub i32 3, %X3241 %cmp = icmp uge i32 %add, 23242 ret i1 %cmp3243}3244 3245define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {3246; CHECK-LABEL: define <2 x i1> @icmp_sub_3_X_uge_2_vec(3247; CHECK-SAME: <2 x i32> [[X:%.*]]) {3248; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 -2)3249; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 2)3250; CHECK-NEXT: ret <2 x i1> [[CMP]]3251;3252 %add = sub <2 x i32> <i32 3, i32 3>, %X3253 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>3254 ret <2 x i1> %cmp3255}3256 3257define i1 @icmp_and_X_-16_eq-16(i32 %X) {3258; CHECK-LABEL: define i1 @icmp_and_X_-16_eq-16(3259; CHECK-SAME: i32 [[X:%.*]]) {3260; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], -173261; CHECK-NEXT: ret i1 [[CMP]]3262;3263 %and = and i32 %X, -163264 %cmp = icmp eq i32 %and, -163265 ret i1 %cmp3266}3267 3268define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {3269; CHECK-LABEL: define <2 x i1> @icmp_and_X_-16_eq-16_vec(3270; CHECK-SAME: <2 x i32> [[X:%.*]]) {3271; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X]], splat (i32 -17)3272; CHECK-NEXT: ret <2 x i1> [[CMP]]3273;3274 %and = and <2 x i32> %X, <i32 -16, i32 -16>3275 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>3276 ret <2 x i1> %cmp3277}3278 3279define i1 @icmp_and_X_-16_ne-16(i32 %X) {3280; CHECK-LABEL: define i1 @icmp_and_X_-16_ne-16(3281; CHECK-SAME: i32 [[X:%.*]]) {3282; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], -163283; CHECK-NEXT: ret i1 [[CMP]]3284;3285 %and = and i32 %X, -163286 %cmp = icmp ne i32 %and, -163287 ret i1 %cmp3288}3289 3290define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {3291; CHECK-LABEL: define <2 x i1> @icmp_and_X_-16_ne-16_vec(3292; CHECK-SAME: <2 x i32> [[X:%.*]]) {3293; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X]], splat (i32 -16)3294; CHECK-NEXT: ret <2 x i1> [[CMP]]3295;3296 %and = and <2 x i32> %X, <i32 -16, i32 -16>3297 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>3298 ret <2 x i1> %cmp3299}3300 3301; PR32524: https://bugs.llvm.org/show_bug.cgi?id=325243302; X | C == C --> X <=u C (when C+1 is PowerOf2).3303 3304define i1 @or1_eq1(i32 %x) {3305; CHECK-LABEL: define i1 @or1_eq1(3306; CHECK-SAME: i32 [[X:%.*]]) {3307; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X]], 23308; CHECK-NEXT: ret i1 [[T1]]3309;3310 %t0 = or i32 %x, 13311 %t1 = icmp eq i32 %t0, 13312 ret i1 %t13313}3314 3315define <2 x i1> @or1_eq1_vec(<2 x i32> %x) {3316; CHECK-LABEL: define <2 x i1> @or1_eq1_vec(3317; CHECK-SAME: <2 x i32> [[X:%.*]]) {3318; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i32> [[X]], splat (i32 2)3319; CHECK-NEXT: ret <2 x i1> [[T1]]3320;3321 %t0 = or <2 x i32> %x, splat (i32 1)3322 %t1 = icmp eq <2 x i32> %t0, splat (i32 1)3323 ret <2 x i1> %t13324}3325 3326define <2 x i1> @or_eq_vec_nonsplat(<2 x i32> %x) {3327; CHECK-LABEL: define <2 x i1> @or_eq_vec_nonsplat(3328; CHECK-SAME: <2 x i32> [[X:%.*]]) {3329; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 -2, i32 -3>3330; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer3331; CHECK-NEXT: ret <2 x i1> [[T1]]3332;3333 %t0 = or <2 x i32> %x, <i32 1, i32 2>3334 %t1 = icmp eq <2 x i32> %t0, <i32 1, i32 2>3335 ret <2 x i1> %t13336}3337 3338define void @or_eq_vec_multiple_nonsplat(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z, ptr %ptr0, ptr %ptr1, ptr %ptr2) {3339; CHECK-LABEL: define void @or_eq_vec_multiple_nonsplat(3340; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[Z:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]], ptr [[PTR2:%.*]]) {3341; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 -2, i32 -3>3342; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer3343; CHECK-NEXT: store <2 x i1> [[CMP0]], ptr [[PTR0]], align 13344; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[Y]], <i32 -2, i32 -3>3345; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer3346; CHECK-NEXT: store <2 x i1> [[CMP1]], ptr [[PTR1]], align 13347; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[Z]], <i32 -2, i32 -3>3348; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[TMP3]], zeroinitializer3349; CHECK-NEXT: store <2 x i1> [[CMP2]], ptr [[PTR2]], align 13350; CHECK-NEXT: ret void3351;3352 %t0 = or <2 x i32> %x, <i32 1, i32 2>3353 %cmp0 = icmp eq <2 x i32> %t0, <i32 1, i32 2>3354 store <2 x i1> %cmp0, ptr %ptr03355 3356 %t1 = or <2 x i32> %y, <i32 1, i32 2>3357 %cmp1 = icmp eq <2 x i32> %t1, <i32 1, i32 2>3358 store <2 x i1> %cmp1, ptr %ptr13359 3360 %t2 = or <2 x i32> %z, <i32 1, i32 2>3361 %cmp2 = icmp eq <2 x i32> %t2, <i32 1, i32 2>3362 store <2 x i1> %cmp2, ptr %ptr23363 ret void3364}3365 3366; Make sure use count of 1 doesn't matter3367define i1 @or1_eq1_multiple(i32 %x, i32 %y, i32 %z, ptr %ptr0, ptr %ptr1) {3368; CHECK-LABEL: define i1 @or1_eq1_multiple(3369; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]]) {3370; CHECK-NEXT: [[CMP0:%.*]] = icmp ult i32 [[X]], 23371; CHECK-NEXT: store i1 [[CMP0]], ptr [[PTR0]], align 13372; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[Y]], 23373; CHECK-NEXT: store i1 [[CMP1]], ptr [[PTR1]], align 13374; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Z]], 23375; CHECK-NEXT: ret i1 [[CMP2]]3376;3377 %t0 = or i32 %x, 13378 %cmp0 = icmp eq i32 %t0, 13379 store i1 %cmp0, ptr %ptr03380 3381 %t1 = or i32 %y, 13382 %cmp1 = icmp eq i32 %t1, 13383 store i1 %cmp1, ptr %ptr13384 3385 %t2 = or i32 %z, 13386 %cmp2 = icmp eq i32 %t2, 13387 ret i1 %cmp23388}3389 3390define <2 x i1> @or1_eq1_multiple_vec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z, ptr %ptr0, ptr %ptr1) {3391; CHECK-LABEL: define <2 x i1> @or1_eq1_multiple_vec(3392; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[Z:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]]) {3393; CHECK-NEXT: [[CMP0:%.*]] = icmp ult <2 x i32> [[X]], splat (i32 2)3394; CHECK-NEXT: store <2 x i1> [[CMP0]], ptr [[PTR0]], align 13395; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[Y]], splat (i32 2)3396; CHECK-NEXT: store <2 x i1> [[CMP1]], ptr [[PTR1]], align 13397; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[Z]], splat (i32 2)3398; CHECK-NEXT: ret <2 x i1> [[CMP2]]3399;3400 %t0 = or <2 x i32> %x, splat (i32 1)3401 %cmp0 = icmp eq <2 x i32> %t0, splat (i32 1)3402 store <2 x i1> %cmp0, ptr %ptr03403 3404 %t1 = or <2 x i32> %y, splat (i32 1)3405 %cmp1 = icmp eq <2 x i32> %t1, splat (i32 1)3406 store <2 x i1> %cmp1, ptr %ptr13407 3408 %t2 = or <2 x i32> %z, splat (i32 1)3409 %cmp2 = icmp eq <2 x i32> %t2, splat (i32 1)3410 ret <2 x i1> %cmp23411}3412 3413; X | C == C --> X <=u C (when C+1 is PowerOf2).3414 3415define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {3416; CHECK-LABEL: define <2 x i1> @or3_eq3_vec(3417; CHECK-SAME: <2 x i8> [[X:%.*]]) {3418; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X]], splat (i8 4)3419; CHECK-NEXT: ret <2 x i1> [[T1]]3420;3421 %t0 = or <2 x i8> %x, <i8 3, i8 3>3422 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>3423 ret <2 x i1> %t13424}3425 3426; X | C != C --> X >u C (when C+1 is PowerOf2).3427 3428define i1 @or7_ne7(i32 %x) {3429; CHECK-LABEL: define i1 @or7_ne7(3430; CHECK-SAME: i32 [[X:%.*]]) {3431; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X]], 73432; CHECK-NEXT: ret i1 [[T1]]3433;3434 %t0 = or i32 %x, 73435 %t1 = icmp ne i32 %t0, 73436 ret i1 %t13437}3438 3439; X | C != C --> X >u C (when C+1 is PowerOf2).3440 3441define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {3442; CHECK-LABEL: define <2 x i1> @or63_ne63_vec(3443; CHECK-SAME: <2 x i8> [[X:%.*]]) {3444; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X]], splat (i8 63)3445; CHECK-NEXT: ret <2 x i1> [[T1]]3446;3447 %t0 = or <2 x i8> %x, <i8 63, i8 63>3448 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>3449 ret <2 x i1> %t13450}3451 3452; PR40611: https://bugs.llvm.org/show_bug.cgi?id=406113453; X | C == C --> (X & ~C) == 03454 3455define i1 @orC_eqC(i32 %x) {3456; CHECK-LABEL: define i1 @orC_eqC(3457; CHECK-SAME: i32 [[X:%.*]]) {3458; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -433459; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 03460; CHECK-NEXT: ret i1 [[T1]]3461;3462 %t0 = or i32 %x, 423463 %t1 = icmp eq i32 %t0, 423464 ret i1 %t13465}3466 3467; X | C == C --> (X & ~C) == 03468 3469define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {3470; CHECK-LABEL: define <2 x i1> @orC_eqC_vec(3471; CHECK-SAME: <2 x i8> [[X:%.*]]) {3472; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -44)3473; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer3474; CHECK-NEXT: ret <2 x i1> [[T1]]3475;3476 %t0 = or <2 x i8> %x, <i8 43, i8 43>3477 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>3478 ret <2 x i1> %t13479}3480 3481; X | C != C --> (X & ~C) != 03482 3483define i1 @orC_neC(i32 %x) {3484; CHECK-LABEL: define i1 @orC_neC(3485; CHECK-SAME: i32 [[X:%.*]]) {3486; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], 413487; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 03488; CHECK-NEXT: ret i1 [[T1]]3489;3490 %t0 = or i32 %x, -423491 %t1 = icmp ne i32 %t0, -423492 ret i1 %t13493}3494 3495; X | C != C --> (X & ~C) != 03496 3497define <2 x i1> @orC_neC_vec(<2 x i8> %x) {3498; CHECK-LABEL: define <2 x i1> @orC_neC_vec(3499; CHECK-SAME: <2 x i8> [[X:%.*]]) {3500; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 42)3501; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer3502; CHECK-NEXT: ret <2 x i1> [[T1]]3503;3504 %t0 = or <2 x i8> %x, <i8 -43, i8 -43>3505 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>3506 ret <2 x i1> %t13507}3508 3509define i1 @shrink_constant(i32 %X) {3510; CHECK-LABEL: define i1 @shrink_constant(3511; CHECK-SAME: i32 [[X:%.*]]) {3512; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], -123513; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 43514; CHECK-NEXT: ret i1 [[CMP]]3515;3516 %xor = xor i32 %X, -93517 %cmp = icmp ult i32 %xor, 43518 ret i1 %cmp3519}3520 3521define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {3522; CHECK-LABEL: define <2 x i1> @shrink_constant_vec(3523; CHECK-SAME: <2 x i32> [[X:%.*]]) {3524; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X]], splat (i32 -12)3525; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], splat (i32 4)3526; CHECK-NEXT: ret <2 x i1> [[CMP]]3527;3528 %xor = xor <2 x i32> %X, <i32 -9, i32 -9>3529 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>3530 ret <2 x i1> %cmp3531}3532 3533; This test requires 3 different transforms to get to the result.3534define i1 @icmp_sub_-1_X_ult_4(i32 %X) {3535; CHECK-LABEL: define i1 @icmp_sub_-1_X_ult_4(3536; CHECK-SAME: i32 [[X:%.*]]) {3537; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], -53538; CHECK-NEXT: ret i1 [[CMP]]3539;3540 %sub = sub i32 -1, %X3541 %cmp = icmp ult i32 %sub, 43542 ret i1 %cmp3543}3544 3545define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {3546; CHECK-LABEL: define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(3547; CHECK-SAME: <2 x i32> [[X:%.*]]) {3548; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X]], splat (i32 -5)3549; CHECK-NEXT: ret <2 x i1> [[CMP]]3550;3551 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>3552 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>3553 ret <2 x i1> %cmp3554}3555 3556define i1 @icmp_sub_-1_X_uge_4(i32 %X) {3557; CHECK-LABEL: define i1 @icmp_sub_-1_X_uge_4(3558; CHECK-SAME: i32 [[X:%.*]]) {3559; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], -43560; CHECK-NEXT: ret i1 [[CMP]]3561;3562 %sub = sub i32 -1, %X3563 %cmp = icmp uge i32 %sub, 43564 ret i1 %cmp3565}3566 3567define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {3568; CHECK-LABEL: define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(3569; CHECK-SAME: <2 x i32> [[X:%.*]]) {3570; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X]], splat (i32 -4)3571; CHECK-NEXT: ret <2 x i1> [[CMP]]3572;3573 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>3574 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>3575 ret <2 x i1> %cmp3576}3577 3578define <2 x i1> @xor_ult(<2 x i8> %x) {3579; CHECK-LABEL: define <2 x i1> @xor_ult(3580; CHECK-SAME: <2 x i8> [[X:%.*]]) {3581; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X]], splat (i8 3)3582; CHECK-NEXT: ret <2 x i1> [[R]]3583;3584 %xor = xor <2 x i8> %x, <i8 -4, i8 -4>3585 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>3586 ret <2 x i1> %r3587}3588 3589define i1 @xor_ult_extra_use(i8 %x, ptr %p) {3590; CHECK-LABEL: define i1 @xor_ult_extra_use(3591; CHECK-SAME: i8 [[X:%.*]], ptr [[P:%.*]]) {3592; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], -323593; CHECK-NEXT: store i8 [[XOR]], ptr [[P]], align 13594; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 313595; CHECK-NEXT: ret i1 [[R]]3596;3597 %xor = xor i8 %x, -323598 store i8 %xor, ptr %p3599 %r = icmp ult i8 %xor, -323600 ret i1 %r3601}3602 3603define <2 x i1> @xor_ugt(<2 x i8> %x) {3604; CHECK-LABEL: define <2 x i1> @xor_ugt(3605; CHECK-SAME: <2 x i8> [[X:%.*]]) {3606; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X]], splat (i8 7)3607; CHECK-NEXT: ret <2 x i1> [[R]]3608;3609 %xor = xor <2 x i8> %x, <i8 7, i8 7>3610 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>3611 ret <2 x i1> %r3612}3613 3614define i1 @xor_ugt_extra_use(i8 %x, ptr %p) {3615; CHECK-LABEL: define i1 @xor_ugt_extra_use(3616; CHECK-SAME: i8 [[X:%.*]], ptr [[P:%.*]]) {3617; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], 633618; CHECK-NEXT: store i8 [[XOR]], ptr [[P]], align 13619; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 633620; CHECK-NEXT: ret i1 [[R]]3621;3622 %xor = xor i8 %x, 633623 store i8 %xor, ptr %p3624 %r = icmp ugt i8 %xor, 633625 ret i1 %r3626}3627 3628define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {3629; CHECK-LABEL: define i1 @icmp_lshr_lshr_eq(3630; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {3631; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A]], [[B]]3632; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 10737418243633; CHECK-NEXT: ret i1 [[Z]]3634;3635 %x = lshr i32 %a, 303636 %y = lshr i32 %b, 303637 %z = icmp eq i32 %x, %y3638 ret i1 %z3639}3640 3641define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {3642; CHECK-LABEL: define i1 @icmp_ashr_ashr_ne(3643; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {3644; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A]], [[B]]3645; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 2553646; CHECK-NEXT: ret i1 [[Z]]3647;3648 %x = ashr i32 %a, 83649 %y = ashr i32 %b, 83650 %z = icmp ne i32 %x, %y3651 ret i1 %z3652}3653 3654define i1 @icmp_neg_cst_slt(i32 %a) {3655; CHECK-LABEL: define i1 @icmp_neg_cst_slt(3656; CHECK-SAME: i32 [[A:%.*]]) {3657; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A]], 103658; CHECK-NEXT: ret i1 [[TMP1]]3659;3660 %1 = sub nsw i32 0, %a3661 %2 = icmp slt i32 %1, -103662 ret i1 %23663}3664 3665define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {3666; CHECK-LABEL: define i1 @icmp_and_or_lshr(3667; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3668; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y]]3669; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 13670; CHECK-NEXT: [[AND3:%.*]] = and i32 [[X]], [[OR2]]3671; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 03672; CHECK-NEXT: ret i1 [[RET]]3673;3674 %shf = lshr i32 %x, %y3675 %or = or i32 %shf, %x3676 %and = and i32 %or, 13677 %ret = icmp ne i32 %and, 03678 ret i1 %ret3679}3680 3681define i1 @icmp_and_or_lshr_samesign(i32 %x, i32 %y) {3682; CHECK-LABEL: define i1 @icmp_and_or_lshr_samesign(3683; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3684; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y]]3685; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 13686; CHECK-NEXT: [[AND3:%.*]] = and i32 [[X]], [[OR2]]3687; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 03688; CHECK-NEXT: ret i1 [[RET]]3689;3690 %shf = lshr i32 %x, %y3691 %or = or i32 %shf, %x3692 %and = and i32 %or, 13693 %ret = icmp samesign ne i32 %and, 03694 ret i1 %ret3695}3696 3697define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {3698; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_vec(3699; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {3700; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y]]3701; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]3702; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>3703; CHECK-NEXT: ret <2 x i1> [[RET]]3704;3705 %shf = lshr <2 x i32> %x, %y3706 %or = or <2 x i32> %shf, %x3707 %and = and <2 x i32> %or, <i32 1, i32 1>3708 %ret = icmp ne <2 x i32> %and, zeroinitializer3709 ret <2 x i1> %ret3710}3711 3712define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {3713; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_vec_commute(3714; CHECK-SAME: <2 x i32> [[XP:%.*]], <2 x i32> [[Y:%.*]]) {3715; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP]], splat (i32 42)3716; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y]]3717; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]3718; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>3719; CHECK-NEXT: ret <2 x i1> [[RET]]3720;3721 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization3722 %shf = lshr <2 x i32> %x, %y3723 %or = or <2 x i32> %x, %shf3724 %and = and <2 x i32> %or, <i32 1, i32 1>3725 %ret = icmp ne <2 x i32> %and, zeroinitializer3726 ret <2 x i1> %ret3727}3728 3729define i1 @icmp_and_or_lshr_cst(i32 %x) {3730; CHECK-LABEL: define i1 @icmp_and_or_lshr_cst(3731; CHECK-SAME: i32 [[X:%.*]]) {3732; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X]], 33733; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 03734; CHECK-NEXT: ret i1 [[RET]]3735;3736 %shf = lshr i32 %x, 13737 %or = or i32 %shf, %x3738 %and = and i32 %or, 13739 %ret = icmp ne i32 %and, 03740 ret i1 %ret3741}3742 3743define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {3744; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_cst_vec(3745; CHECK-SAME: <2 x i32> [[X:%.*]]) {3746; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 3)3747; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer3748; CHECK-NEXT: ret <2 x i1> [[RET]]3749;3750 %shf = lshr <2 x i32> %x, <i32 1, i32 1>3751 %or = or <2 x i32> %shf, %x3752 %and = and <2 x i32> %or, <i32 1, i32 1>3753 %ret = icmp ne <2 x i32> %and, zeroinitializer3754 ret <2 x i1> %ret3755}3756 3757define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) {3758; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(3759; CHECK-SAME: <2 x i32> [[X:%.*]]) {3760; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>3761; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer3762; CHECK-NEXT: ret <2 x i1> [[RET]]3763;3764 %shf = lshr <2 x i32> %x, <i32 1, i32 2>3765 %or = or <2 x i32> %shf, %x3766 %and = and <2 x i32> %or, <i32 1, i32 1>3767 %ret = icmp ne <2 x i32> %and, zeroinitializer3768 ret <2 x i1> %ret3769}3770 3771define <2 x i1> @icmp_and_or_lshr_cst_vec_poison(<2 x i32> %x) {3772; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_cst_vec_poison(3773; CHECK-SAME: <2 x i32> [[X:%.*]]) {3774; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>3775; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer3776; CHECK-NEXT: ret <2 x i1> [[RET]]3777;3778 %shf = lshr <2 x i32> %x, <i32 1, i32 poison>3779 %or = or <2 x i32> %shf, %x3780 %and = and <2 x i32> %or, <i32 1, i32 1>3781 %ret = icmp ne <2 x i32> %and, zeroinitializer3782 ret <2 x i1> %ret3783}3784 3785define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {3786; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(3787; CHECK-SAME: <2 x i32> [[XP:%.*]]) {3788; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP]], splat (i32 42)3789; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 3)3790; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer3791; CHECK-NEXT: ret <2 x i1> [[RET]]3792;3793 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization3794 %shf = lshr <2 x i32> %x, <i32 1, i32 1>3795 %or = or <2 x i32> %x, %shf3796 %and = and <2 x i32> %or, <i32 1, i32 1>3797 %ret = icmp ne <2 x i32> %and, zeroinitializer3798 ret <2 x i1> %ret3799}3800 3801define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) {3802; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(3803; CHECK-SAME: <2 x i32> [[XP:%.*]]) {3804; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP]], splat (i32 42)3805; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>3806; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer3807; CHECK-NEXT: ret <2 x i1> [[RET]]3808;3809 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization3810 %shf = lshr <2 x i32> %x, <i32 1, i32 2>3811 %or = or <2 x i32> %x, %shf3812 %and = and <2 x i32> %or, <i32 1, i32 1>3813 %ret = icmp ne <2 x i32> %and, zeroinitializer3814 ret <2 x i1> %ret3815}3816 3817define <2 x i1> @icmp_and_or_lshr_cst_vec_poison_commute(<2 x i32> %xp) {3818; CHECK-LABEL: define <2 x i1> @icmp_and_or_lshr_cst_vec_poison_commute(3819; CHECK-SAME: <2 x i32> [[XP:%.*]]) {3820; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP]], splat (i32 42)3821; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>3822; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer3823; CHECK-NEXT: ret <2 x i1> [[RET]]3824;3825 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization3826 %shf = lshr <2 x i32> %x, <i32 1, i32 poison>3827 %or = or <2 x i32> %x, %shf3828 %and = and <2 x i32> %or, <i32 1, i32 1>3829 %ret = icmp ne <2 x i32> %and, zeroinitializer3830 ret <2 x i1> %ret3831}3832 3833define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {3834; CHECK-LABEL: define i1 @shl_ap1_zero_ap2_non_zero_2(3835; CHECK-SAME: i32 [[A:%.*]]) {3836; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], 293837; CHECK-NEXT: ret i1 [[CMP]]3838;3839 %shl = shl i32 4, %a3840 %cmp = icmp eq i32 %shl, 03841 ret i1 %cmp3842}3843 3844define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {3845; CHECK-LABEL: define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(3846; CHECK-SAME: <2 x i32> [[A:%.*]]) {3847; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A]], splat (i32 29)3848; CHECK-NEXT: ret <2 x i1> [[CMP]]3849;3850 %shl = shl <2 x i32> <i32 4, i32 4>, %a3851 %cmp = icmp eq <2 x i32> %shl, zeroinitializer3852 ret <2 x i1> %cmp3853}3854 3855define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) {3856; CHECK-LABEL: define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(3857; CHECK-SAME: <2 x i32> [[A:%.*]]) {3858; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A]]3859; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer3860; CHECK-NEXT: ret <2 x i1> [[CMP]]3861;3862 %shl = shl <2 x i32> <i32 4, i32 5>, %a3863 %cmp = icmp eq <2 x i32> %shl, zeroinitializer3864 ret <2 x i1> %cmp3865}3866 3867define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {3868; CHECK-LABEL: define i1 @shl_ap1_zero_ap2_non_zero_4(3869; CHECK-SAME: i32 [[A:%.*]]) {3870; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], 303871; CHECK-NEXT: ret i1 [[CMP]]3872;3873 %shl = shl i32 -2, %a3874 %cmp = icmp eq i32 %shl, 03875 ret i1 %cmp3876}3877 3878define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {3879; CHECK-LABEL: define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(3880; CHECK-SAME: i32 [[A:%.*]]) {3881; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 03882; CHECK-NEXT: ret i1 [[CMP]]3883;3884 %shl = shl i32 50, %a3885 %cmp = icmp eq i32 %shl, 503886 ret i1 %cmp3887}3888 3889define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {3890; CHECK-LABEL: define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(3891; CHECK-SAME: i32 [[A:%.*]]) {3892; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 03893; CHECK-NEXT: ret i1 [[CMP]]3894;3895 %shl = shl i32 -50, %a3896 %cmp = icmp eq i32 %shl, -503897 ret i1 %cmp3898}3899 3900define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {3901; CHECK-LABEL: define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(3902; CHECK-SAME: i32 [[A:%.*]]) {3903; CHECK-NEXT: ret i1 false3904;3905 %shl = shl i32 50, %a3906 %cmp = icmp eq i32 %shl, 253907 ret i1 %cmp3908}3909 3910define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {3911; CHECK-LABEL: define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(3912; CHECK-SAME: i32 [[A:%.*]]) {3913; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 13914; CHECK-NEXT: ret i1 [[CMP]]3915;3916 %shl = shl i32 25, %a3917 %cmp = icmp eq i32 %shl, 503918 ret i1 %cmp3919}3920 3921define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {3922; CHECK-LABEL: define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(3923; CHECK-SAME: i32 [[A:%.*]]) {3924; CHECK-NEXT: ret i1 false3925;3926 %shl = shl i32 26, %a3927 %cmp = icmp eq i32 %shl, 503928 ret i1 %cmp3929}3930 3931define i1 @icmp_sgt_zero_add_nsw(i32 %a) {3932; CHECK-LABEL: define i1 @icmp_sgt_zero_add_nsw(3933; CHECK-SAME: i32 [[A:%.*]]) {3934; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -13935; CHECK-NEXT: ret i1 [[CMP]]3936;3937 %add = add nsw i32 %a, 13938 %cmp = icmp sgt i32 %add, 03939 ret i1 %cmp3940}3941 3942define i1 @icmp_sge_zero_add_nsw(i32 %a) {3943; CHECK-LABEL: define i1 @icmp_sge_zero_add_nsw(3944; CHECK-SAME: i32 [[A:%.*]]) {3945; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -23946; CHECK-NEXT: ret i1 [[CMP]]3947;3948 %add = add nsw i32 %a, 13949 %cmp = icmp sge i32 %add, 03950 ret i1 %cmp3951}3952 3953define i1 @icmp_sle_zero_add_nsw(i32 %a) {3954; CHECK-LABEL: define i1 @icmp_sle_zero_add_nsw(3955; CHECK-SAME: i32 [[A:%.*]]) {3956; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 03957; CHECK-NEXT: ret i1 [[CMP]]3958;3959 %add = add nsw i32 %a, 13960 %cmp = icmp sle i32 %add, 03961 ret i1 %cmp3962}3963 3964define zeroext i1 @icmp_cmpxchg_strong(ptr %sc, i32 %old_val, i32 %new_val) {3965; CHECK-LABEL: define zeroext i1 @icmp_cmpxchg_strong(3966; CHECK-SAME: ptr [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]]) {3967; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg ptr [[SC]], i32 [[OLD_VAL]], i32 [[NEW_VAL]] seq_cst seq_cst, align 43968; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 13969; CHECK-NEXT: ret i1 [[ICMP]]3970;3971 %xchg = cmpxchg ptr %sc, i32 %old_val, i32 %new_val seq_cst seq_cst3972 %xtrc = extractvalue { i32, i1 } %xchg, 03973 %icmp = icmp eq i32 %xtrc, %old_val3974 ret i1 %icmp3975}3976 3977define i1 @f1(i64 %a, i64 %b) {3978; CHECK-LABEL: define i1 @f1(3979; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {3980; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A]], [[B]]3981; CHECK-NEXT: ret i1 [[V]]3982;3983 %t = sub nsw i64 %a, %b3984 %v = icmp sge i64 %t, 03985 ret i1 %v3986}3987 3988define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {3989; CHECK-LABEL: define <2 x i1> @f1_vec(3990; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {3991; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A]], [[B]]3992; CHECK-NEXT: ret <2 x i1> [[V]]3993;3994 %t = sub nsw <2 x i64> %a, %b3995 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>3996 ret <2 x i1> %v3997}3998 3999define i1 @f2(i64 %a, i64 %b) {4000; CHECK-LABEL: define i1 @f2(4001; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {4002; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A]], [[B]]4003; CHECK-NEXT: ret i1 [[V]]4004;4005 %t = sub nsw i64 %a, %b4006 %v = icmp sgt i64 %t, 04007 ret i1 %v4008}4009 4010define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {4011; CHECK-LABEL: define <2 x i1> @f2_vec(4012; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {4013; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A]], [[B]]4014; CHECK-NEXT: ret <2 x i1> [[V]]4015;4016 %t = sub nsw <2 x i64> %a, %b4017 %v = icmp sgt <2 x i64> %t, zeroinitializer4018 ret <2 x i1> %v4019}4020 4021define i1 @f3(i64 %a, i64 %b) {4022; CHECK-LABEL: define i1 @f3(4023; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {4024; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A]], [[B]]4025; CHECK-NEXT: ret i1 [[V]]4026;4027 %t = sub nsw i64 %a, %b4028 %v = icmp slt i64 %t, 04029 ret i1 %v4030}4031 4032define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {4033; CHECK-LABEL: define <2 x i1> @f3_vec(4034; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {4035; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A]], [[B]]4036; CHECK-NEXT: ret <2 x i1> [[V]]4037;4038 %t = sub nsw <2 x i64> %a, %b4039 %v = icmp slt <2 x i64> %t, zeroinitializer4040 ret <2 x i1> %v4041}4042 4043define i1 @f4(i64 %a, i64 %b) {4044; CHECK-LABEL: define i1 @f4(4045; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {4046; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A]], [[B]]4047; CHECK-NEXT: ret i1 [[V]]4048;4049 %t = sub nsw i64 %a, %b4050 %v = icmp sle i64 %t, 04051 ret i1 %v4052}4053 4054define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {4055; CHECK-LABEL: define <2 x i1> @f4_vec(4056; CHECK-SAME: <2 x i64> [[A:%.*]], <2 x i64> [[B:%.*]]) {4057; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A]], [[B]]4058; CHECK-NEXT: ret <2 x i1> [[V]]4059;4060 %t = sub nsw <2 x i64> %a, %b4061 %v = icmp slt <2 x i64> %t, <i64 1, i64 1>4062 ret <2 x i1> %v4063}4064 4065define i32 @f5(i8 %a, i8 %b) {4066; CHECK-LABEL: define i32 @f5(4067; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4068; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A]] to i324069; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B]] to i324070; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]4071; CHECK-NEXT: [[SUB7_SUB:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)4072; CHECK-NEXT: ret i32 [[SUB7_SUB]]4073;4074 %conv = zext i8 %a to i324075 %conv3 = zext i8 %b to i324076 %sub = sub nsw i32 %conv, %conv34077 %cmp4 = icmp slt i32 %sub, 04078 %sub7 = sub nsw i32 0, %sub4079 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub4080 ret i32 %sub7.sub4081}4082 4083define i32 @f6(i32 %a, i32 %b) {4084; CHECK-LABEL: define i32 @f6(4085; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {4086; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A]], [[B]]4087; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 2554088; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 04089; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 04090; CHECK-NEXT: ret i32 [[S]]4091;4092 %sext = shl i32 %a, 244093 %conv = ashr i32 %sext, 244094 %sext6 = shl i32 %b, 244095 %conv4 = ashr i32 %sext6, 244096 %cmp = icmp eq i32 %conv, %conv44097 %s = select i1 %cmp, i32 10000, i32 04098 ret i32 %s4099}4100 4101define i32 @f7(i32 %a, i32 %b) {4102; CHECK-LABEL: define i32 @f7(4103; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {4104; CHECK-NEXT: [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A]], [[B]]4105; CHECK-NEXT: [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 5114106; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 04107; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 100004108; CHECK-NEXT: ret i32 [[S]]4109;4110 %sext = shl i32 %a, 234111 %sext6 = shl i32 %b, 234112 %cmp = icmp ne i32 %sext, %sext64113 %s = select i1 %cmp, i32 10000, i32 04114 ret i32 %s4115}4116 4117define i1 @f8(i32 %val, i32 %lim) {4118; CHECK-LABEL: define i1 @f8(4119; CHECK-SAME: i32 [[VAL:%.*]], i32 [[LIM:%.*]]) {4120; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM]], 04121; CHECK-NEXT: ret i1 [[R]]4122;4123 %lim.sub = add i32 %lim, -14124 %val.and = and i32 %val, %lim.sub4125 %r = icmp ult i32 %val.and, %lim4126 ret i1 %r4127}4128 4129define i1 @f9(i32 %val, i32 %lim) {4130; CHECK-LABEL: define i1 @f9(4131; CHECK-SAME: i32 [[VAL:%.*]], i32 [[LIM:%.*]]) {4132; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM]], 04133; CHECK-NEXT: ret i1 [[R]]4134;4135 %lim.sub = sub i32 %lim, 14136 %val.and = and i32 %val, %lim.sub4137 %r = icmp ult i32 %val.and, %lim4138 ret i1 %r4139}4140 4141define i1 @f10(i16 %p) {4142; CHECK-LABEL: define i1 @f10(4143; CHECK-SAME: i16 [[P:%.*]]) {4144; CHECK-NEXT: [[EXT1:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i164145; CHECK-NEXT: [[EXT2:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i164146; CHECK-NEXT: [[MUL:%.*]] = mul nuw i16 [[EXT1]], [[EXT2]]4147; CHECK-NEXT: [[CMP580:%.*]] = icmp ule i16 [[MUL]], [[P]]4148; CHECK-NEXT: ret i1 [[CMP580]]4149;4150 %ext1 = zext i8 ptrtoint (ptr @f10 to i8) to i164151 %ext2 = zext i8 ptrtoint (ptr @f10 to i8) to i164152 %mul = mul i16 %ext1, %ext24153 %cmp580 = icmp ule i16 %mul, %p4154 ret i1 %cmp5804155}4156 4157; Note: fptosi is used in various tests below to ensure that operand complexity4158; canonicalization does not kick in, which would make some of the tests4159; equivalent to one another.4160 4161define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {4162; CHECK-LABEL: define i1 @cmp_sgt_rhs_dec(4163; CHECK-SAME: float [[X:%.*]], i32 [[I:%.*]]) {4164; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324165; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[I]], [[CONV]]4166; CHECK-NEXT: ret i1 [[CMP]]4167;4168 %conv = fptosi float %x to i324169 %dec = sub nsw i32 %i, 14170 %cmp = icmp sgt i32 %conv, %dec4171 ret i1 %cmp4172}4173 4174define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {4175; CHECK-LABEL: define i1 @cmp_sle_rhs_dec(4176; CHECK-SAME: float [[X:%.*]], i32 [[I:%.*]]) {4177; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324178; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[I]], [[CONV]]4179; CHECK-NEXT: ret i1 [[CMP]]4180;4181 %conv = fptosi float %x to i324182 %dec = sub nsw i32 %i, 14183 %cmp = icmp sle i32 %conv, %dec4184 ret i1 %cmp4185}4186 4187define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {4188; CHECK-LABEL: define i1 @cmp_sge_rhs_inc(4189; CHECK-SAME: float [[X:%.*]], i32 [[I:%.*]]) {4190; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324191; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[CONV]]4192; CHECK-NEXT: ret i1 [[CMP]]4193;4194 %conv = fptosi float %x to i324195 %inc = add nsw i32 %i, 14196 %cmp = icmp sge i32 %conv, %inc4197 ret i1 %cmp4198}4199 4200define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {4201; CHECK-LABEL: define i1 @cmp_slt_rhs_inc(4202; CHECK-SAME: float [[X:%.*]], i32 [[I:%.*]]) {4203; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324204; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[I]], [[CONV]]4205; CHECK-NEXT: ret i1 [[CMP]]4206;4207 %conv = fptosi float %x to i324208 %inc = add nsw i32 %i, 14209 %cmp = icmp slt i32 %conv, %inc4210 ret i1 %cmp4211}4212 4213define i1 @PR26407(i32 %x, i32 %y) {4214; CHECK-LABEL: define i1 @PR26407(4215; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4216; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X]], 21474836474217; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y]], 21474836474218; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]4219; CHECK-NEXT: ret i1 [[CMP]]4220;4221 %addx = add i32 %x, 21474836474222 %addy = add i32 %y, 21474836474223 %cmp = icmp uge i32 %addx, %addy4224 ret i1 %cmp4225}4226 4227define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {4228; CHECK-LABEL: define i1 @cmp_inverse_mask_bits_set_eq(4229; CHECK-SAME: i32 [[X:%.*]]) {4230; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -434231; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -434232; CHECK-NEXT: ret i1 [[CMP]]4233;4234 %or = or i32 %x, 424235 %cmp = icmp eq i32 %or, -14236 ret i1 %cmp4237}4238 4239define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {4240; CHECK-LABEL: define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(4241; CHECK-SAME: <2 x i32> [[X:%.*]]) {4242; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 -43)4243; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 -43)4244; CHECK-NEXT: ret <2 x i1> [[CMP]]4245;4246 %or = or <2 x i32> %x, <i32 42, i32 42>4247 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>4248 ret <2 x i1> %cmp4249}4250 4251define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {4252; CHECK-LABEL: define i1 @cmp_inverse_mask_bits_set_ne(4253; CHECK-SAME: i32 [[X:%.*]]) {4254; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X]], -434255; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -434256; CHECK-NEXT: ret i1 [[CMP]]4257;4258 %or = or i32 %x, 424259 %cmp = icmp ne i32 %or, -14260 ret i1 %cmp4261}4262 4263; When canonicalizing to 'gt/lt', make sure the constant is correct.4264 4265define i1 @PR27792(i128 %a) {4266; CHECK-LABEL: define i1 @PR27792(4267; CHECK-SAME: i128 [[A:%.*]]) {4268; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A]], -14269; CHECK-NEXT: ret i1 [[CMP]]4270;4271 %cmp = icmp sge i128 %a, 04272 ret i1 %cmp4273}4274 4275define i1 @PR27792_2(i128 %a) {4276; CHECK-LABEL: define i1 @PR27792_2(4277; CHECK-SAME: i128 [[A:%.*]]) {4278; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A]], 04279; CHECK-NEXT: ret i1 [[B]]4280;4281 %b = icmp uge i128 %a, 14282 ret i1 %b4283}4284 4285define i1 @ugtMaxSignedVal(i8 %a) {4286; CHECK-LABEL: define i1 @ugtMaxSignedVal(4287; CHECK-SAME: i8 [[A:%.*]]) {4288; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 04289; CHECK-NEXT: ret i1 [[CMP]]4290;4291 %cmp = icmp ugt i8 %a, 1274292 ret i1 %cmp4293}4294 4295define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {4296; CHECK-LABEL: define <2 x i1> @ugtMaxSignedValVec(4297; CHECK-SAME: <2 x i8> [[A:%.*]]) {4298; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], zeroinitializer4299; CHECK-NEXT: ret <2 x i1> [[CMP]]4300;4301 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>4302 ret <2 x i1> %cmp4303}4304 4305define i1 @ugtKnownBits(i8 %a) {4306; CHECK-LABEL: define i1 @ugtKnownBits(4307; CHECK-SAME: i8 [[A:%.*]]) {4308; CHECK-NEXT: [[B:%.*]] = and i8 [[A]], 174309; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 174310; CHECK-NEXT: ret i1 [[CMP]]4311;4312 %b = and i8 %a, 174313 %cmp = icmp ugt i8 %b, 164314 ret i1 %cmp4315}4316 4317define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {4318; CHECK-LABEL: define <2 x i1> @ugtKnownBitsVec(4319; CHECK-SAME: <2 x i8> [[A:%.*]]) {4320; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A]], splat (i8 17)4321; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], splat (i8 17)4322; CHECK-NEXT: ret <2 x i1> [[CMP]]4323;4324 %b = and <2 x i8> %a, <i8 17, i8 17>4325 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>4326 ret <2 x i1> %cmp4327}4328 4329define i1 @or_ptrtoint_mismatch(ptr %p, ptr %q) {4330; CHECK-LABEL: define i1 @or_ptrtoint_mismatch(4331; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {4332; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[P]], null4333; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[Q]], null4334; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]4335; CHECK-NEXT: ret i1 [[B]]4336;4337 4338 %pp = ptrtoint ptr %p to i644339 %qq = ptrtoint ptr %q to i644340 %o = or i64 %pp, %qq4341 %b = icmp eq i64 %o, 04342 ret i1 %b4343}4344 4345define i1 @icmp_add1_ugt(i32 %x, i32 %y) {4346; CHECK-LABEL: define i1 @icmp_add1_ugt(4347; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4348; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X]], [[Y]]4349; CHECK-NEXT: ret i1 [[CMP]]4350;4351 %add = add nuw i32 %x, 14352 %cmp = icmp ugt i32 %add, %y4353 ret i1 %cmp4354}4355 4356define i1 @icmp_add1_ule(i32 %x, i32 %y) {4357; CHECK-LABEL: define i1 @icmp_add1_ule(4358; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4359; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]4360; CHECK-NEXT: ret i1 [[CMP]]4361;4362 %add = add nuw i32 %x, 14363 %cmp = icmp ule i32 %add, %y4364 ret i1 %cmp4365}4366 4367define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {4368; CHECK-LABEL: define i1 @cmp_uge_rhs_inc(4369; CHECK-SAME: float [[X:%.*]], i32 [[I:%.*]]) {4370; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324371; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[I]], [[CONV]]4372; CHECK-NEXT: ret i1 [[CMP]]4373;4374 %conv = fptosi float %x to i324375 %inc = add nuw i32 %i, 14376 %cmp = icmp uge i32 %conv, %inc4377 ret i1 %cmp4378}4379 4380define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {4381; CHECK-LABEL: define i1 @cmp_ult_rhs_inc(4382; CHECK-SAME: float [[X:%.*]], i32 [[I:%.*]]) {4383; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324384; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[I]], [[CONV]]4385; CHECK-NEXT: ret i1 [[CMP]]4386;4387 %conv = fptosi float %x to i324388 %inc = add nuw i32 %i, 14389 %cmp = icmp ult i32 %conv, %inc4390 ret i1 %cmp4391}4392 4393define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {4394; CHECK-LABEL: define i1 @cmp_sge_lhs_inc(4395; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4396; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X]], 14397; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y]]4398; CHECK-NEXT: ret i1 [[CMP]]4399;4400 %inc = add nsw i32 %x, 14401 %cmp = icmp sge i32 %inc, %y4402 ret i1 %cmp4403}4404 4405define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {4406; CHECK-LABEL: define i1 @cmp_uge_lhs_inc(4407; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4408; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X]], 14409; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y]]4410; CHECK-NEXT: ret i1 [[CMP]]4411;4412 %inc = add nuw i32 %x, 14413 %cmp = icmp uge i32 %inc, %y4414 ret i1 %cmp4415}4416 4417define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {4418; CHECK-LABEL: define i1 @cmp_sgt_lhs_dec(4419; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4420; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X]], -14421; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y]]4422; CHECK-NEXT: ret i1 [[CMP]]4423;4424 %dec = sub nsw i32 %x, 14425 %cmp = icmp sgt i32 %dec, %y4426 ret i1 %cmp4427}4428 4429define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {4430; CHECK-LABEL: define i1 @cmp_ugt_lhs_dec(4431; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4432; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X]], -14433; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y]]4434; CHECK-NEXT: ret i1 [[CMP]]4435;4436 %dec = sub nuw i32 %x, 14437 %cmp = icmp ugt i32 %dec, %y4438 ret i1 %cmp4439}4440 4441define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {4442; CHECK-LABEL: define i1 @cmp_sle_rhs_inc(4443; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {4444; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324445; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y]], 14446; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]4447; CHECK-NEXT: ret i1 [[CMP]]4448;4449 %conv = fptosi float %x to i324450 %inc = add nsw i32 %y, 14451 %cmp = icmp sle i32 %conv, %inc4452 ret i1 %cmp4453}4454 4455define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {4456; CHECK-LABEL: define i1 @cmp_ule_rhs_inc(4457; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {4458; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324459; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y]], 14460; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]4461; CHECK-NEXT: ret i1 [[CMP]]4462;4463 %conv = fptosi float %x to i324464 %inc = add nuw i32 %y, 14465 %cmp = icmp ule i32 %conv, %inc4466 ret i1 %cmp4467}4468 4469define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {4470; CHECK-LABEL: define i1 @cmp_slt_rhs_dec(4471; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {4472; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324473; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y]], -14474; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]4475; CHECK-NEXT: ret i1 [[CMP]]4476;4477 %conv = fptosi float %x to i324478 %dec = sub nsw i32 %y, 14479 %cmp = icmp slt i32 %conv, %dec4480 ret i1 %cmp4481}4482 4483define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {4484; CHECK-LABEL: define i1 @cmp_ult_rhs_dec(4485; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {4486; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X]] to i324487; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y]], -14488; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]4489; CHECK-NEXT: ret i1 [[CMP]]4490;4491 %conv = fptosi float %x to i324492 %dec = sub nuw i32 %y, 14493 %cmp = icmp ult i32 %conv, %dec4494 ret i1 %cmp4495}4496 4497define i1 @eq_add_constants(i32 %x, i32 %y) {4498; CHECK-LABEL: define i1 @eq_add_constants(4499; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4500; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X]], [[Y]]4501; CHECK-NEXT: ret i1 [[C]]4502;4503 %A = add i32 %x, 54504 %B = add i32 %y, 54505 %C = icmp eq i32 %A, %B4506 ret i1 %C4507}4508 4509declare i32 @llvm.bswap.i32(i32)4510 4511define i1 @bswap_ne(i32 %x, i32 %y) {4512; CHECK-LABEL: define i1 @bswap_ne(4513; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4514; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X]], [[Y]]4515; CHECK-NEXT: ret i1 [[CMP]]4516;4517 %swapx = call i32 @llvm.bswap.i32(i32 %x)4518 %swapy = call i32 @llvm.bswap.i32(i32 %y)4519 %cmp = icmp ne i32 %swapx, %swapy4520 ret i1 %cmp4521}4522 4523declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)4524 4525define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {4526; CHECK-LABEL: define <8 x i1> @bswap_vec_eq(4527; CHECK-SAME: <8 x i16> [[X:%.*]], <8 x i16> [[Y:%.*]]) {4528; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X]], [[Y]]4529; CHECK-NEXT: ret <8 x i1> [[CMP]]4530;4531 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)4532 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)4533 %cmp = icmp eq <8 x i16> %swapx, %swapy4534 ret <8 x i1> %cmp4535}4536 4537declare i64 @llvm.bitreverse.i64(i64)4538 4539define i1 @bitreverse_eq(i64 %x, i64 %y) {4540; CHECK-LABEL: define i1 @bitreverse_eq(4541; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {4542; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X]], [[Y]]4543; CHECK-NEXT: ret i1 [[CMP]]4544;4545 %revx = call i64 @llvm.bitreverse.i64(i64 %x)4546 %revy = call i64 @llvm.bitreverse.i64(i64 %y)4547 %cmp = icmp eq i64 %revx, %revy4548 ret i1 %cmp4549}4550 4551declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)4552 4553define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {4554; CHECK-LABEL: define <8 x i1> @bitreverse_vec_ne(4555; CHECK-SAME: <8 x i16> [[X:%.*]], <8 x i16> [[Y:%.*]]) {4556; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X]], [[Y]]4557; CHECK-NEXT: ret <8 x i1> [[CMP]]4558;4559 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)4560 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)4561 %cmp = icmp ne <8 x i16> %revx, %revy4562 ret <8 x i1> %cmp4563}4564 4565; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.4566; They should all simplify to equality compares.4567define i1 @knownbits1(i8 %a, i8 %b) {4568; CHECK-LABEL: define i1 @knownbits1(4569; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4570; CHECK-NEXT: [[A1:%.*]] = and i8 [[A]], 14571; CHECK-NEXT: [[B1:%.*]] = and i8 [[B]], 24572; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 14573; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]]4574; CHECK-NEXT: ret i1 [[C]]4575;4576 %a1 = and i8 %a, 54577 %a2 = or i8 %a1, 44578 %b1 = and i8 %b, 74579 %b2 = or i8 %b1, 54580 %c = icmp uge i8 %a2, %b24581 ret i1 %c4582}4583 4584define i1 @knownbits2(i8 %a, i8 %b) {4585; CHECK-LABEL: define i1 @knownbits2(4586; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4587; CHECK-NEXT: [[A1:%.*]] = and i8 [[A]], 14588; CHECK-NEXT: [[B1:%.*]] = and i8 [[B]], 24589; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 14590; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]]4591; CHECK-NEXT: ret i1 [[C]]4592;4593 %a1 = and i8 %a, 54594 %a2 = or i8 %a1, 44595 %b1 = and i8 %b, 74596 %b2 = or i8 %b1, 54597 %c = icmp ult i8 %a2, %b24598 ret i1 %c4599}4600 4601define i1 @knownbits3(i8 %a, i8 %b) {4602; CHECK-LABEL: define i1 @knownbits3(4603; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4604; CHECK-NEXT: [[A1:%.*]] = and i8 [[A]], 14605; CHECK-NEXT: [[B1:%.*]] = and i8 [[B]], 24606; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 14607; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A1]]4608; CHECK-NEXT: ret i1 [[C]]4609;4610 %a1 = and i8 %a, 54611 %a2 = or i8 %a1, 44612 %b1 = and i8 %b, 74613 %b2 = or i8 %b1, 54614 %c = icmp ule i8 %b2, %a24615 ret i1 %c4616}4617 4618define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {4619; CHECK-LABEL: define <2 x i1> @knownbits4(4620; CHECK-SAME: <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {4621; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A]], splat (i8 1)4622; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B]], splat (i8 2)4623; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1)4624; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], [[A1]]4625; CHECK-NEXT: ret <2 x i1> [[C]]4626;4627 %a1 = and <2 x i8> %a, <i8 5, i8 5>4628 %a2 = or <2 x i8> %a1, <i8 4, i8 4>4629 %b1 = and <2 x i8> %b, <i8 7, i8 7>4630 %b2 = or <2 x i8> %b1, <i8 5, i8 5>4631 %c = icmp ugt <2 x i8> %b2, %a24632 ret <2 x i1> %c4633}4634 4635; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.4636; The other is known to be a value 5-7. These should simplify to equality comparisons.4637define i1 @knownbits5(i8 %a, i8 %b) {4638; CHECK-LABEL: define i1 @knownbits5(4639; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4640; CHECK-NEXT: [[A1:%.*]] = and i8 [[A]], -1274641; CHECK-NEXT: [[B1:%.*]] = and i8 [[B]], 24642; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 14643; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]]4644; CHECK-NEXT: ret i1 [[C]]4645;4646 %a1 = and i8 %a, 1334647 %a2 = or i8 %a1, 44648 %b1 = and i8 %b, 74649 %b2 = or i8 %b1, 54650 %c = icmp sge i8 %a2, %b24651 ret i1 %c4652}4653 4654define i1 @knownbits6(i8 %a, i8 %b) {4655; CHECK-LABEL: define i1 @knownbits6(4656; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4657; CHECK-NEXT: [[A1:%.*]] = and i8 [[A]], -1274658; CHECK-NEXT: [[B1:%.*]] = and i8 [[B]], 24659; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 14660; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]]4661; CHECK-NEXT: ret i1 [[C]]4662;4663 %a1 = and i8 %a, 1334664 %a2 = or i8 %a1, 44665 %b1 = and i8 %b, 74666 %b2 = or i8 %b1, 54667 %c = icmp slt i8 %a2, %b24668 ret i1 %c4669}4670 4671define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {4672; CHECK-LABEL: define <2 x i1> @knownbits7(4673; CHECK-SAME: <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {4674; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A]], splat (i8 -127)4675; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B]], splat (i8 2)4676; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1)4677; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[TMP1]], [[A1]]4678; CHECK-NEXT: ret <2 x i1> [[C]]4679;4680 %a1 = and <2 x i8> %a, <i8 133, i8 133>4681 %a2 = or <2 x i8> %a1, <i8 4, i8 4>4682 %b1 = and <2 x i8> %b, <i8 7, i8 7>4683 %b2 = or <2 x i8> %b1, <i8 5, i8 5>4684 %c = icmp sle <2 x i8> %b2, %a24685 ret <2 x i1> %c4686}4687 4688define i1 @knownbits8(i8 %a, i8 %b) {4689; CHECK-LABEL: define i1 @knownbits8(4690; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {4691; CHECK-NEXT: [[A1:%.*]] = and i8 [[A]], -1274692; CHECK-NEXT: [[B1:%.*]] = and i8 [[B]], 24693; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 14694; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], [[A1]]4695; CHECK-NEXT: ret i1 [[C]]4696;4697 %a1 = and i8 %a, 1334698 %a2 = or i8 %a1, 44699 %b1 = and i8 %b, 74700 %b2 = or i8 %b1, 54701 %c = icmp sgt i8 %b2, %a24702 ret i1 %c4703}4704 4705; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom4706define i32 @abs_preserve(i32 %x) {4707; CHECK-LABEL: define i32 @abs_preserve(4708; CHECK-SAME: i32 [[X:%.*]]) {4709; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X]], 14710; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false)4711; CHECK-NEXT: ret i32 [[ABS]]4712;4713 %a = mul nsw i32 %x, 24714 %c = icmp sge i32 %a, 04715 %nega = sub i32 0, %a4716 %abs = select i1 %c, i32 %a, i32 %nega4717 ret i32 %abs4718}4719 4720; Don't crash by assuming the compared values are integers.4721 4722declare void @llvm.assume(i1)4723define i1 @PR35794(ptr %a) {4724; CHECK-LABEL: define i1 @PR35794(4725; CHECK-SAME: ptr [[A:%.*]]) {4726; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq ptr [[A]], null4727; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])4728; CHECK-NEXT: ret i1 true4729;4730 %cmp = icmp sgt ptr %a, inttoptr (i64 -1 to ptr)4731 %maskcond = icmp eq ptr %a, null4732 tail call void @llvm.assume(i1 %maskcond)4733 ret i1 %cmp4734}4735 4736; Don't crash by assuming the compared values are integers.4737define <2 x i1> @PR36583(<2 x ptr>) {4738; CHECK-LABEL: define <2 x i1> @PR36583(4739; CHECK-SAME: <2 x ptr> [[TMP0:%.*]]) {4740; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x ptr> [[TMP0]], zeroinitializer4741; CHECK-NEXT: ret <2 x i1> [[RES]]4742;4743 %cast = ptrtoint <2 x ptr> %0 to <2 x i64>4744 %res = icmp eq <2 x i64> %cast, zeroinitializer4745 ret <2 x i1> %res4746}4747 4748; fold (icmp pred (sub (0, X)) C1) for vec type4749define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {4750; CHECK-LABEL: define <2 x i32> @Op1Negated_Vec(4751; CHECK-SAME: <2 x i32> [[X:%.*]]) {4752; CHECK-NEXT: [[COND:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X]], i1 true)4753; CHECK-NEXT: ret <2 x i32> [[COND]]4754;4755 %sub = sub nsw <2 x i32> zeroinitializer, %x4756 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>4757 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x4758 ret <2 x i32> %cond4759}4760 4761define i1 @signbit_bitcast_fpext(float %x) {4762; CHECK-LABEL: define i1 @signbit_bitcast_fpext(4763; CHECK-SAME: float [[X:%.*]]) {4764; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X]] to i324765; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 04766; CHECK-NEXT: ret i1 [[R]]4767;4768 %f = fpext float %x to double4769 %b = bitcast double %f to i644770 %r = icmp slt i64 %b, 04771 ret i1 %r4772}4773 4774define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) {4775; CHECK-LABEL: define <2 x i1> @signbit_bitcast_fpext_vec(4776; CHECK-SAME: <2 x half> [[X:%.*]]) {4777; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x half> [[X]] to <2 x i16>4778; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer4779; CHECK-NEXT: ret <2 x i1> [[R]]4780;4781 %f = fpext <2 x half> %x to <2 x float>4782 %b = bitcast <2 x float> %f to <2 x i32>4783 %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647>4784 ret <2 x i1> %r4785}4786 4787define i1 @signbit_bitcast_fptrunc(float %x) {4788; CHECK-LABEL: define i1 @signbit_bitcast_fptrunc(4789; CHECK-SAME: float [[X:%.*]]) {4790; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X]] to i324791; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -14792; CHECK-NEXT: ret i1 [[R]]4793;4794 %f = fptrunc float %x to half4795 %b = bitcast half %f to i164796 %r = icmp ult i16 %b, 327684797 ret i1 %r4798}4799 4800define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) {4801; CHECK-LABEL: define <2 x i1> @signbit_bitcast_fptrunc_vec(4802; CHECK-SAME: <2 x double> [[X:%.*]]) {4803; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X]] to <2 x i64>4804; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], splat (i64 -1)4805; CHECK-NEXT: ret <2 x i1> [[R]]4806;4807 %f = fptrunc <2 x double> %x to <2 x half>4808 %b = bitcast <2 x half> %f to <2 x i16>4809 %r = icmp sge <2 x i16> %b, zeroinitializer4810 ret <2 x i1> %r4811}4812 4813define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) {4814; CHECK-LABEL: define i1 @signbit_bitcast_fpext_wrong_cmp(4815; CHECK-SAME: float [[X:%.*]]) {4816; CHECK-NEXT: [[F:%.*]] = fpext float [[X]] to double4817; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i644818; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 14819; CHECK-NEXT: ret i1 [[R]]4820;4821 %f = fpext float %x to double4822 %b = bitcast double %f to i644823 %r = icmp slt i64 %b, 14824 ret i1 %r4825}4826 4827define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) {4828; CHECK-LABEL: define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(4829; CHECK-SAME: <2 x half> [[X:%.*]]) {4830; CHECK-NEXT: [[F:%.*]] = fpext <2 x half> [[X]] to <2 x float>4831; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16>4832; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i16> [[B]], splat (i16 -1)4833; CHECK-NEXT: ret <4 x i1> [[R]]4834;4835 %f = fpext <2 x half> %x to <2 x float>4836 %b = bitcast <2 x float> %f to <4 x i16>4837 %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1>4838 ret <4 x i1> %r4839}4840 4841define i1 @signbit_bitcast_fpext_extra_use(float %x, ptr %p) {4842; CHECK-LABEL: define i1 @signbit_bitcast_fpext_extra_use(4843; CHECK-SAME: float [[X:%.*]], ptr [[P:%.*]]) {4844; CHECK-NEXT: [[F:%.*]] = fpext float [[X]] to double4845; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i644846; CHECK-NEXT: call void @use_i64(i64 [[B]])4847; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 04848; CHECK-NEXT: ret i1 [[R]]4849;4850 %f = fpext float %x to double4851 %b = bitcast double %f to i644852 call void @use_i64(i64 %b)4853 %r = icmp slt i64 %b, 04854 ret i1 %r4855}4856 4857define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) {4858; CHECK-LABEL: define i1 @signbit_bitcast_fpext_ppc_fp128(4859; CHECK-SAME: float [[X:%.*]]) {4860; CHECK-NEXT: [[S2:%.*]] = fpext float [[X]] to ppc_fp1284861; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i1284862; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 04863; CHECK-NEXT: ret i1 [[S4]]4864;4865 %s2 = fpext float %x to ppc_fp1284866 %s3 = bitcast ppc_fp128 %s2 to i1284867 %s4 = icmp slt i128 %s3, 04868 ret i1 %s44869}4870 4871define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) {4872; CHECK-LABEL: define i1 @signbit_bitcast_fptrunc_ppc_fp128(4873; CHECK-SAME: ppc_fp128 [[X:%.*]]) {4874; CHECK-NEXT: [[S2:%.*]] = fptrunc ppc_fp128 [[X]] to float4875; CHECK-NEXT: [[S3:%.*]] = bitcast float [[S2]] to i324876; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[S3]], 04877; CHECK-NEXT: ret i1 [[S4]]4878;4879 %s2 = fptrunc ppc_fp128 %x to float4880 %s3 = bitcast float %s2 to i324881 %s4 = icmp slt i32 %s3, 04882 ret i1 %s44883}4884 4885@x = external dso_local local_unnamed_addr global i32, align 44886@y = external dso_local local_unnamed_addr global i32, align 44887define i1 @pr47997(i32 %arg) {4888; CHECK-LABEL: define i1 @pr47997(4889; CHECK-SAME: i32 [[ARG:%.*]]) {4890; CHECK-NEXT: [[BB:.*:]]4891; CHECK-NEXT: [[I:%.*]] = add nsw i32 [[ARG]], -14892; CHECK-NEXT: store i32 [[I]], ptr @x, align 44893; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]]4894; CHECK-NEXT: store i32 [[I1]], ptr @y, align 44895; CHECK-NEXT: ret i1 true4896;4897bb:4898 %i = add nsw i32 %arg, -14899 store i32 %i, ptr @x4900 %i1 = sub nsw i32 1, %arg4901 store i32 %i1, ptr @y4902 %i2 = sub nsw i32 0, %i14903 %i3 = icmp eq i32 %i, %i24904 ret i1 %i34905}4906 4907; PR509444908 4909define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) {4910; CHECK-LABEL: define i1 @thread_cmp_over_select_with_poison_trueval(4911; CHECK-SAME: i1 [[B:%.*]]) {4912; CHECK-NEXT: ret i1 false4913;4914 %s = select i1 %b, i32 poison, i32 04915 %tobool = icmp ne i32 %s, 04916 ret i1 %tobool4917}4918 4919define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {4920; CHECK-LABEL: define i1 @thread_cmp_over_select_with_poison_falseval(4921; CHECK-SAME: i1 [[B:%.*]]) {4922; CHECK-NEXT: ret i1 true4923;4924 %s = select i1 %b, i32 1, i32 poison4925 %tobool = icmp ne i32 %s, 04926 ret i1 %tobool4927}4928 4929define i1 @signbit_true_logic(i8 %x) {4930; CHECK-LABEL: define i1 @signbit_true_logic(4931; CHECK-SAME: i8 [[X:%.*]]) {4932; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], 04933; CHECK-NEXT: ret i1 [[R]]4934;4935 %dec = add i8 %x, -14936 %not = xor i8 %x, -14937 %and = and i8 %dec, %not4938 %r = icmp slt i8 %and, 04939 ret i1 %r4940}4941 4942define <2 x i1> @signbit_false_logic(<2 x i5> %x) {4943; CHECK-LABEL: define <2 x i1> @signbit_false_logic(4944; CHECK-SAME: <2 x i5> [[X:%.*]]) {4945; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X]], zeroinitializer4946; CHECK-NEXT: ret <2 x i1> [[R]]4947;4948 %dec = add <2 x i5> %x, <i5 -1, i5 poison>4949 %not = xor <2 x i5> %x, <i5 -1, i5 -1>4950 %and = and <2 x i5> %dec, %not4951 %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1>4952 ret <2 x i1> %r4953}4954 4955; Confirm that complexity canonicalization works for commuted pattern.4956 4957define i1 @signbit_true_logic_uses_commute(i64 %x) {4958; CHECK-LABEL: define i1 @signbit_true_logic_uses_commute(4959; CHECK-SAME: i64 [[X:%.*]]) {4960; CHECK-NEXT: [[DEC:%.*]] = add i64 [[X]], -14961; CHECK-NEXT: call void @use_i64(i64 [[DEC]])4962; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[X]], -14963; CHECK-NEXT: call void @use_i64(i64 [[NOT]])4964; CHECK-NEXT: [[AND:%.*]] = and i64 [[DEC]], [[NOT]]4965; CHECK-NEXT: call void @use_i64(i64 [[AND]])4966; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X]], 04967; CHECK-NEXT: ret i1 [[R]]4968;4969 %dec = add i64 %x, -14970 call void @use_i64(i64 %dec)4971 %not = xor i64 %x, -14972 call void @use_i64(i64 %not)4973 %and = and i64 %not, %dec4974 call void @use_i64(i64 %and)4975 %r = icmp slt i64 %and, 04976 ret i1 %r4977}4978 4979define i1 @redundant_sign_bit_count_ult_1_2(i32 %x) {4980; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_1_2(4981; CHECK-SAME: i32 [[X:%.*]]) {4982; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 44983; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 84984; CHECK-NEXT: ret i1 [[C]]4985;4986 %y = ashr i32 %x, 14987 %z = xor i32 %y, %x4988 %c = icmp ult i32 %z, 44989 ret i1 %c4990}4991 4992define i1 @redundant_sign_bit_count_ult_1_30(i32 %x) {4993; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_1_30(4994; CHECK-SAME: i32 [[X:%.*]]) {4995; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 10737418244996; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -14997; CHECK-NEXT: ret i1 [[C]]4998;4999 %y = ashr i32 %x, 15000 %z = xor i32 %y, %x5001 %c = icmp ult i32 %z, 10737418245002 ret i1 %c5003}5004 5005define i1 @redundant_sign_bit_count_ult_31_2(i32 %x) {5006; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_31_2(5007; CHECK-SAME: i32 [[X:%.*]]) {5008; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 45009; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 85010; CHECK-NEXT: ret i1 [[C]]5011;5012 %y = ashr i32 %x, 315013 %z = xor i32 %y, %x5014 %c = icmp ult i32 %z, 45015 ret i1 %c5016}5017 5018define i1 @redundant_sign_bit_count_ult_31_30(i32 %x) {5019; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_31_30(5020; CHECK-SAME: i32 [[X:%.*]]) {5021; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 10737418245022; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -15023; CHECK-NEXT: ret i1 [[C]]5024;5025 %y = ashr i32 %x, 315026 %z = xor i32 %y, %x5027 %c = icmp ult i32 %z, 10737418245028 ret i1 %c5029}5030 5031define i1 @redundant_sign_bit_count_ult_31_30_extra_use_ashr(i32 %x) {5032; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_31_30_extra_use_ashr(5033; CHECK-SAME: i32 [[X:%.*]]) {5034; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X]], 315035; CHECK-NEXT: call void @use_i32(i32 [[Y]])5036; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 10737418245037; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -15038; CHECK-NEXT: ret i1 [[C]]5039;5040 %y = ashr i32 %x, 315041 call void @use_i32(i32 %y)5042 %z = xor i32 %y, %x5043 %c = icmp ult i32 %z, 10737418245044 ret i1 %c5045}5046 5047define i1 @redundant_sign_bit_count_ult_31_30_extra_use_xor(i32 %x) {5048; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_31_30_extra_use_xor(5049; CHECK-SAME: i32 [[X:%.*]]) {5050; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X]], 315051; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[X]]5052; CHECK-NEXT: call void @use_i32(i32 [[Z]])5053; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[Z]], 10737418245054; CHECK-NEXT: ret i1 [[C]]5055;5056 %y = ashr i32 %x, 315057 %z = xor i32 %y, %x5058 call void @use_i32(i32 %z)5059 %c = icmp ult i32 %z, 10737418245060 ret i1 %c5061}5062 5063define i1 @not_redundant_sign_bit_count_ult(i32 %w, i32 %x) {5064; CHECK-LABEL: define i1 @not_redundant_sign_bit_count_ult(5065; CHECK-SAME: i32 [[W:%.*]], i32 [[X:%.*]]) {5066; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X]], 315067; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[W]]5068; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[Z]], 10737418245069; CHECK-NEXT: ret i1 [[C]]5070;5071 %y = ashr i32 %x, 315072 %z = xor i32 %y, %w5073 %c = icmp ult i32 %z, 10737418245074 ret i1 %c5075}5076 5077define i1 @wrong_shift_opcode_i8(i8 %x) {5078; CHECK-LABEL: define i1 @wrong_shift_opcode_i8(5079; CHECK-SAME: i8 [[X:%.*]]) {5080; CHECK-NEXT: [[Y:%.*]] = lshr i8 [[X]], 55081; CHECK-NEXT: [[Z:%.*]] = xor i8 [[Y]], [[X]]5082; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[Z]], 25083; CHECK-NEXT: ret i1 [[C]]5084;5085 %y = lshr i8 %x, 55086 %z = xor i8 %y, %x5087 %c = icmp ult i8 %z, 25088 ret i1 %c5089}5090 5091define i1 @redundant_sign_bit_count_ult_31_30_commute(i32 %xsrc) {5092; CHECK-LABEL: define i1 @redundant_sign_bit_count_ult_31_30_commute(5093; CHECK-SAME: i32 [[XSRC:%.*]]) {5094; CHECK-NEXT: [[X:%.*]] = mul i32 [[XSRC]], 135095; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 10737418245096; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -15097; CHECK-NEXT: ret i1 [[C]]5098;5099 %x = mul i32 %xsrc, 13 ; thwart complexity-based canonicalization5100 %y = ashr i32 %x, 315101 %z = xor i32 %x, %y5102 %c = icmp ult i32 %z, 10737418245103 ret i1 %c5104}5105 5106define i1 @redundant_sign_bit_count_i8(i8 %x) {5107; CHECK-LABEL: define i1 @redundant_sign_bit_count_i8(5108; CHECK-SAME: i8 [[X:%.*]]) {5109; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], 25110; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[TMP1]], 45111; CHECK-NEXT: ret i1 [[C]]5112;5113 %y = ashr i8 %x, 55114 %z = xor i8 %y, %x5115 %c = icmp ult i8 %z, 25116 ret i1 %c5117}5118 5119define <2 x i1> @redundant_sign_bit_count_ult_31_30_vector(<2 x i32> %xsrc) {5120; CHECK-LABEL: define <2 x i1> @redundant_sign_bit_count_ult_31_30_vector(5121; CHECK-SAME: <2 x i32> [[XSRC:%.*]]) {5122; CHECK-NEXT: [[X:%.*]] = mul <2 x i32> [[XSRC]], splat (i32 13)5123; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 1073741824)5124; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[TMP1]], splat (i32 -1)5125; CHECK-NEXT: ret <2 x i1> [[C]]5126;5127 %x = mul <2 x i32> %xsrc, <i32 13, i32 13> ; thwart complexity-based canonicalization5128 %y = ashr <2 x i32> %x, <i32 31, i32 31>5129 %z = xor <2 x i32> %x, %y5130 %c = icmp ult <2 x i32> %z, <i32 1073741824, i32 1073741824>5131 ret <2 x i1> %c5132}5133 5134define i1 @redundant_sign_bit_count_ugt_1_2(i32 %x) {5135; CHECK-LABEL: define i1 @redundant_sign_bit_count_ugt_1_2(5136; CHECK-SAME: i32 [[X:%.*]]) {5137; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -45138; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -85139; CHECK-NEXT: ret i1 [[C]]5140;5141 %y = ashr i32 %x, 15142 %z = xor i32 %y, %x5143 %c = icmp ugt i32 %z, 35144 ret i1 %c5145}5146 5147define i1 @redundant_sign_bit_count_ugt_1_30(i32 %x) {5148; CHECK-LABEL: define i1 @redundant_sign_bit_count_ugt_1_30(5149; CHECK-SAME: i32 [[X:%.*]]) {5150; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 10737418245151; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 05152; CHECK-NEXT: ret i1 [[C]]5153;5154 %y = ashr i32 %x, 15155 %z = xor i32 %y, %x5156 %c = icmp ugt i32 %z, 10737418235157 ret i1 %c5158}5159 5160define i1 @redundant_sign_bit_count_ugt_31_2(i32 %x) {5161; CHECK-LABEL: define i1 @redundant_sign_bit_count_ugt_31_2(5162; CHECK-SAME: i32 [[X:%.*]]) {5163; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -45164; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -85165; CHECK-NEXT: ret i1 [[C]]5166;5167 %y = ashr i32 %x, 315168 %z = xor i32 %y, %x5169 %c = icmp ugt i32 %z, 35170 ret i1 %c5171}5172 5173define i1 @redundant_sign_bit_count_ugt_31_30(i32 %x) {5174; CHECK-LABEL: define i1 @redundant_sign_bit_count_ugt_31_30(5175; CHECK-SAME: i32 [[X:%.*]]) {5176; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 10737418245177; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 05178; CHECK-NEXT: ret i1 [[C]]5179;5180 %y = ashr i32 %x, 315181 %z = xor i32 %y, %x5182 %c = icmp ugt i32 %z, 10737418235183 ret i1 %c5184}5185 5186define i1 @zext_bool_and_eq0(i1 %x, i8 %y) {5187; CHECK-LABEL: define i1 @zext_bool_and_eq0(5188; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {5189; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], 15190; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 05191; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X]], true5192; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]5193; CHECK-NEXT: ret i1 [[R]]5194;5195 %zx = zext i1 %x to i85196 %a = and i8 %zx, %y5197 %r = icmp eq i8 %a, 05198 ret i1 %r5199}5200 5201define <2 x i1> @zext_bool_and_eq0_commute(<2 x i1> %x, <2 x i8> %p) {5202; CHECK-LABEL: define <2 x i1> @zext_bool_and_eq0_commute(5203; CHECK-SAME: <2 x i1> [[X:%.*]], <2 x i8> [[P:%.*]]) {5204; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[P]], splat (i8 1)5205; CHECK-NEXT: [[R1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer5206; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X]], splat (i1 true)5207; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_X]], <2 x i1> splat (i1 true), <2 x i1> [[R1]]5208; CHECK-NEXT: ret <2 x i1> [[R]]5209;5210 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization5211 %zx = zext <2 x i1> %x to <2 x i8>5212 %a = and <2 x i8> %y, %zx5213 %r = icmp eq <2 x i8> %a, zeroinitializer5214 ret <2 x i1> %r5215}5216 5217define i1 @zext_bool_and_ne0(i1 %x, i8 %y) {5218; CHECK-LABEL: define i1 @zext_bool_and_ne0(5219; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {5220; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], 15221; CHECK-NEXT: [[R1:%.*]] = icmp ne i8 [[TMP1]], 05222; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i1 [[R1]], i1 false5223; CHECK-NEXT: ret i1 [[R]]5224;5225 %zx = zext i1 %x to i85226 %a = and i8 %zx, %y5227 %r = icmp ne i8 %a, 05228 ret i1 %r5229}5230 5231define i1 @zext_bool_and_ne1(i1 %x, i8 %y) {5232; CHECK-LABEL: define i1 @zext_bool_and_ne1(5233; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {5234; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], 15235; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 05236; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X]], true5237; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]5238; CHECK-NEXT: ret i1 [[R]]5239;5240 %zx = zext i1 %x to i85241 %a = and i8 %zx, %y5242 %r = icmp ne i8 %a, 15243 ret i1 %r5244}5245 5246define <2 x i1> @zext_bool_and_eq1(<2 x i1> %x, <2 x i8> %y) {5247; CHECK-LABEL: define <2 x i1> @zext_bool_and_eq1(5248; CHECK-SAME: <2 x i1> [[X:%.*]], <2 x i8> [[Y:%.*]]) {5249; CHECK-NEXT: [[R1:%.*]] = trunc <2 x i8> [[Y]] to <2 x i1>5250; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X]], <2 x i1> [[R1]], <2 x i1> zeroinitializer5251; CHECK-NEXT: ret <2 x i1> [[R]]5252;5253 %zx = zext <2 x i1> %x to <2 x i8>5254 %a = and <2 x i8> %zx, %y5255 %r = icmp eq <2 x i8> %a, <i8 1, i8 1>5256 ret <2 x i1> %r5257}5258 5259; negative test - wrong logic op5260 5261define i1 @zext_bool_or_eq0(i1 %x, i8 %y) {5262; CHECK-LABEL: define i1 @zext_bool_or_eq0(5263; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {5264; CHECK-NEXT: [[ZX:%.*]] = zext i1 [[X]] to i85265; CHECK-NEXT: [[A:%.*]] = or i8 [[Y]], [[ZX]]5266; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[A]], 05267; CHECK-NEXT: ret i1 [[R]]5268;5269 %zx = zext i1 %x to i85270 %a = or i8 %zx, %y5271 %r = icmp eq i8 %a, 05272 ret i1 %r5273}5274 5275; negative test - extra use5276 5277define i1 @zext_bool_and_eq0_use(i1 %x, i64 %y) {5278; CHECK-LABEL: define i1 @zext_bool_and_eq0_use(5279; CHECK-SAME: i1 [[X:%.*]], i64 [[Y:%.*]]) {5280; CHECK-NEXT: [[ZX:%.*]] = zext i1 [[X]] to i645281; CHECK-NEXT: call void @use_i64(i64 [[ZX]])5282; CHECK-NEXT: [[A:%.*]] = and i64 [[Y]], [[ZX]]5283; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[A]], 05284; CHECK-NEXT: ret i1 [[R]]5285;5286 %zx = zext i1 %x to i645287 call void @use_i64(i64 %zx)5288 %a = and i64 %zx, %y5289 %r = icmp eq i64 %a, 05290 ret i1 %r5291}5292 5293; negative test - extra use5294 5295define i1 @zext_bool_and_ne0_use(i1 %x, i64 %y) {5296; CHECK-LABEL: define i1 @zext_bool_and_ne0_use(5297; CHECK-SAME: i1 [[X:%.*]], i64 [[Y:%.*]]) {5298; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[Y]], 15299; CHECK-NEXT: [[A:%.*]] = select i1 [[X]], i64 [[TMP1]], i64 05300; CHECK-NEXT: call void @use_i64(i64 [[A]])5301; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[A]], 05302; CHECK-NEXT: ret i1 [[R]]5303;5304 %zx = zext i1 %x to i645305 %a = and i64 %zx, %y5306 call void @use_i64(i64 %a)5307 %r = icmp ne i64 %a, 05308 ret i1 %r5309}5310 5311; negative test - must zext from i15312 5313define i1 @zext_notbool_and_ne0(i2 %x, i8 %y) {5314; CHECK-LABEL: define i1 @zext_notbool_and_ne0(5315; CHECK-SAME: i2 [[X:%.*]], i8 [[Y:%.*]]) {5316; CHECK-NEXT: [[ZX:%.*]] = zext i2 [[X]] to i85317; CHECK-NEXT: [[A:%.*]] = and i8 [[Y]], [[ZX]]5318; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[A]], 05319; CHECK-NEXT: ret i1 [[R]]5320;5321 %zx = zext i2 %x to i85322 %a = and i8 %zx, %y5323 %r = icmp ne i8 %a, 05324 ret i1 %r5325}5326 5327; fold icmp(X | OrC, C) --> icmp(X, 0)5328 5329define i1 @or_positive_sgt_zero(i8 %a) {5330; CHECK-LABEL: define i1 @or_positive_sgt_zero(5331; CHECK-SAME: i8 [[A:%.*]]) {5332; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -15333; CHECK-NEXT: ret i1 [[CMP]]5334;5335 %b = or i8 %a, 245336 %cmp = icmp sgt i8 %b, 05337 ret i1 %cmp5338}5339 5340define <2 x i1> @or_postive_sgt_zero_vec(<2 x i8> %a) {5341; CHECK-LABEL: define <2 x i1> @or_postive_sgt_zero_vec(5342; CHECK-SAME: <2 x i8> [[A:%.*]]) {5343; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A]], splat (i8 -1)5344; CHECK-NEXT: ret <2 x i1> [[CMP]]5345;5346 5347 %b = or <2 x i8> %a, <i8 24, i8 24>5348 %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0>5349 ret <2 x i1> %cmp5350}5351 5352define <2 x i1> @or_poison_vec_sgt_zero_vec(<2 x i8> %a) {5353; CHECK-LABEL: define <2 x i1> @or_poison_vec_sgt_zero_vec(5354; CHECK-SAME: <2 x i8> [[A:%.*]]) {5355; CHECK-NEXT: ret <2 x i1> poison5356;5357 5358 %b = or <2 x i8> %a, <i8 poison, i8 poison>5359 %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0>5360 ret <2 x i1> %cmp5361}5362 5363define i1 @or_positive_sge_zero(i8 %a) {5364; CHECK-LABEL: define i1 @or_positive_sge_zero(5365; CHECK-SAME: i8 [[A:%.*]]) {5366; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -15367; CHECK-NEXT: ret i1 [[CMP]]5368;5369 %b = or i8 %a, 245370 %cmp = icmp sge i8 %b, 05371 ret i1 %cmp5372}5373 5374define <2 x i1> @or_postive_sge_zero_vec(<2 x i8> %a) {5375; CHECK-LABEL: define <2 x i1> @or_postive_sge_zero_vec(5376; CHECK-SAME: <2 x i8> [[A:%.*]]) {5377; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A]], splat (i8 -1)5378; CHECK-NEXT: ret <2 x i1> [[CMP]]5379;5380 5381 %b = or <2 x i8> %a, <i8 24, i8 24>5382 %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0>5383 ret <2 x i1> %cmp5384}5385 5386define <2 x i1> @or_poison_vec_sge_zero_vec(<2 x i8> %a) {5387; CHECK-LABEL: define <2 x i1> @or_poison_vec_sge_zero_vec(5388; CHECK-SAME: <2 x i8> [[A:%.*]]) {5389; CHECK-NEXT: ret <2 x i1> poison5390;5391 5392 %b = or <2 x i8> %a, <i8 poison, i8 poison>5393 %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0>5394 ret <2 x i1> %cmp5395}5396 5397define i1 @or_positive_sge_postive(i8 %a) {5398; CHECK-LABEL: define i1 @or_positive_sge_postive(5399; CHECK-SAME: i8 [[A:%.*]]) {5400; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -15401; CHECK-NEXT: ret i1 [[CMP]]5402;5403 %b = or i8 %a, 245404 %cmp = icmp sge i8 %b, 245405 ret i1 %cmp5406}5407 5408define <2 x i1> @or_postive_sge_positive_vec(<2 x i8> %a) {5409; CHECK-LABEL: define <2 x i1> @or_postive_sge_positive_vec(5410; CHECK-SAME: <2 x i8> [[A:%.*]]) {5411; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A]], splat (i8 -1)5412; CHECK-NEXT: ret <2 x i1> [[CMP]]5413;5414 5415 %b = or <2 x i8> %a, <i8 24, i8 24>5416 %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24>5417 ret <2 x i1> %cmp5418}5419 5420define <2 x i1> @or_poison_vec_sge_positive_vec(<2 x i8> %a) {5421; CHECK-LABEL: define <2 x i1> @or_poison_vec_sge_positive_vec(5422; CHECK-SAME: <2 x i8> [[A:%.*]]) {5423; CHECK-NEXT: ret <2 x i1> poison5424;5425 5426 %b = or <2 x i8> %a, <i8 poison, i8 poison>5427 %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24>5428 ret <2 x i1> %cmp5429}5430 5431define i1 @or_positive_sle_zero(i8 %a) {5432; CHECK-LABEL: define i1 @or_positive_sle_zero(5433; CHECK-SAME: i8 [[A:%.*]]) {5434; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 05435; CHECK-NEXT: ret i1 [[CMP]]5436;5437 %b = or i8 %a, 245438 %cmp = icmp sle i8 %b, 05439 ret i1 %cmp5440}5441 5442define <2 x i1> @or_postive_sle_zero_vec(<2 x i8> %a) {5443; CHECK-LABEL: define <2 x i1> @or_postive_sle_zero_vec(5444; CHECK-SAME: <2 x i8> [[A:%.*]]) {5445; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], zeroinitializer5446; CHECK-NEXT: ret <2 x i1> [[CMP]]5447;5448 5449 %b = or <2 x i8> %a, <i8 24, i8 24>5450 %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0>5451 ret <2 x i1> %cmp5452}5453 5454define <2 x i1> @or_poison_vec_sle_zero_vec(<2 x i8> %a) {5455; CHECK-LABEL: define <2 x i1> @or_poison_vec_sle_zero_vec(5456; CHECK-SAME: <2 x i8> [[A:%.*]]) {5457; CHECK-NEXT: ret <2 x i1> poison5458;5459 5460 %b = or <2 x i8> %a, <i8 poison, i8 poison>5461 %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0>5462 ret <2 x i1> %cmp5463}5464 5465define i1 @or_positive_slt_zero(i8 %a) {5466; CHECK-LABEL: define i1 @or_positive_slt_zero(5467; CHECK-SAME: i8 [[A:%.*]]) {5468; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 05469; CHECK-NEXT: ret i1 [[CMP]]5470;5471 %b = or i8 %a, 245472 %cmp = icmp slt i8 %b, 05473 ret i1 %cmp5474}5475 5476define <2 x i1> @or_postive_slt_zero_vec(<2 x i8> %a) {5477; CHECK-LABEL: define <2 x i1> @or_postive_slt_zero_vec(5478; CHECK-SAME: <2 x i8> [[A:%.*]]) {5479; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], zeroinitializer5480; CHECK-NEXT: ret <2 x i1> [[CMP]]5481;5482 5483 %b = or <2 x i8> %a, <i8 24, i8 24>5484 %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0>5485 ret <2 x i1> %cmp5486}5487 5488define <2 x i1> @or_poison_vec_slt_zero_vec(<2 x i8> %a) {5489; CHECK-LABEL: define <2 x i1> @or_poison_vec_slt_zero_vec(5490; CHECK-SAME: <2 x i8> [[A:%.*]]) {5491; CHECK-NEXT: ret <2 x i1> poison5492;5493 5494 %b = or <2 x i8> %a, <i8 poison, i8 poison>5495 %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0>5496 ret <2 x i1> %cmp5497}5498 5499define i1 @or_positive_slt_postive(i8 %a) {5500; CHECK-LABEL: define i1 @or_positive_slt_postive(5501; CHECK-SAME: i8 [[A:%.*]]) {5502; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 05503; CHECK-NEXT: ret i1 [[CMP]]5504;5505 %b = or i8 %a, 245506 %cmp = icmp slt i8 %b, 245507 ret i1 %cmp5508}5509 5510define <2 x i1> @or_postive_slt_positive_vec(<2 x i8> %a) {5511; CHECK-LABEL: define <2 x i1> @or_postive_slt_positive_vec(5512; CHECK-SAME: <2 x i8> [[A:%.*]]) {5513; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], zeroinitializer5514; CHECK-NEXT: ret <2 x i1> [[CMP]]5515;5516 5517 %b = or <2 x i8> %a, <i8 24, i8 24>5518 %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24>5519 ret <2 x i1> %cmp5520}5521 5522define <2 x i1> @or_poison_vec_slt_positive_vec(<2 x i8> %a) {5523; CHECK-LABEL: define <2 x i1> @or_poison_vec_slt_positive_vec(5524; CHECK-SAME: <2 x i8> [[A:%.*]]) {5525; CHECK-NEXT: ret <2 x i1> poison5526;5527 5528 %b = or <2 x i8> %a, <i8 poison, i8 poison>5529 %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24>5530 ret <2 x i1> %cmp5531}5532 5533; negative tests for icmp(X | OrC, C) --> icmp(X, 0)5534 5535define i1 @or_positive_sgt_neg(i8 %a) {5536; CHECK-LABEL: define i1 @or_positive_sgt_neg(5537; CHECK-SAME: i8 [[A:%.*]]) {5538; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -15539; CHECK-NEXT: ret i1 [[CMP]]5540;5541 %b = or i8 %a, 245542 %cmp = icmp sgt i8 %b, -15543 ret i1 %cmp5544}5545 5546define <2 x i1> @or_postive_sgt_neg_vec(<2 x i8> %a) {5547; CHECK-LABEL: define <2 x i1> @or_postive_sgt_neg_vec(5548; CHECK-SAME: <2 x i8> [[A:%.*]]) {5549; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A]], splat (i8 -1)5550; CHECK-NEXT: ret <2 x i1> [[CMP]]5551;5552 5553 %b = or <2 x i8> %a, <i8 24, i8 24>5554 %cmp = icmp sgt <2 x i8> %b, <i8 -1, i8 -1>5555 ret <2 x i1> %cmp5556}5557 5558define i1 @mul_or_positive_sge_neg(i8 %a) {5559; CHECK-LABEL: define i1 @mul_or_positive_sge_neg(5560; CHECK-SAME: i8 [[A:%.*]]) {5561; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 245562; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], -25563; CHECK-NEXT: ret i1 [[CMP]]5564;5565 %b = or i8 %a, 245566 %cmp = icmp sge i8 %b, -15567 ret i1 %cmp5568}5569 5570define <2 x i1> @or_postive_sge_neg_vec(<2 x i8> %a) {5571; CHECK-LABEL: define <2 x i1> @or_postive_sge_neg_vec(5572; CHECK-SAME: <2 x i8> [[A:%.*]]) {5573; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A]], splat (i8 24)5574; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 -2)5575; CHECK-NEXT: ret <2 x i1> [[CMP]]5576;5577 5578 %b = or <2 x i8> %a, <i8 24, i8 24>5579 %cmp = icmp sge <2 x i8> %b, <i8 -1, i8 -1>5580 ret <2 x i1> %cmp5581}5582 5583define i1 @mul_or_small_sge_large(i8 %a) {5584; CHECK-LABEL: define i1 @mul_or_small_sge_large(5585; CHECK-SAME: i8 [[A:%.*]]) {5586; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 245587; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 245588; CHECK-NEXT: ret i1 [[CMP]]5589;5590 %b = or i8 %a, 245591 %cmp = icmp sge i8 %b, 255592 ret i1 %cmp5593}5594 5595define <2 x i1> @or_small_sge_large_vec(<2 x i8> %a) {5596; CHECK-LABEL: define <2 x i1> @or_small_sge_large_vec(5597; CHECK-SAME: <2 x i8> [[A:%.*]]) {5598; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A]], splat (i8 24)5599; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 24)5600; CHECK-NEXT: ret <2 x i1> [[CMP]]5601;5602 5603 %b = or <2 x i8> %a, <i8 24, i8 24>5604 %cmp = icmp sge <2 x i8> %b, <i8 25, i8 25>5605 ret <2 x i1> %cmp5606}5607 5608define i1 @or_positive_sle_neg(i8 %a) {5609; CHECK-LABEL: define i1 @or_positive_sle_neg(5610; CHECK-SAME: i8 [[A:%.*]]) {5611; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 05612; CHECK-NEXT: ret i1 [[CMP]]5613;5614 %b = or i8 %a, 245615 %cmp = icmp sle i8 %b, -15616 ret i1 %cmp5617}5618 5619define <2 x i1> @or_sle_neg_vec(<2 x i8> %a) {5620; CHECK-LABEL: define <2 x i1> @or_sle_neg_vec(5621; CHECK-SAME: <2 x i8> [[A:%.*]]) {5622; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], zeroinitializer5623; CHECK-NEXT: ret <2 x i1> [[CMP]]5624;5625 5626 %b = or <2 x i8> %a, <i8 24, i8 24>5627 %cmp = icmp sle <2 x i8> %b, <i8 -1, i8 -1>5628 ret <2 x i1> %cmp5629}5630 5631define i1 @or_positive_slt_neg(i8 %a) {5632; CHECK-LABEL: define i1 @or_positive_slt_neg(5633; CHECK-SAME: i8 [[A:%.*]]) {5634; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 245635; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], -15636; CHECK-NEXT: ret i1 [[CMP]]5637;5638 %b = or i8 %a, 245639 %cmp = icmp slt i8 %b, -15640 ret i1 %cmp5641}5642 5643define <2 x i1> @or_postive_slt_neg_vec(<2 x i8> %a) {5644; CHECK-LABEL: define <2 x i1> @or_postive_slt_neg_vec(5645; CHECK-SAME: <2 x i8> [[A:%.*]]) {5646; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A]], splat (i8 24)5647; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 -1)5648; CHECK-NEXT: ret <2 x i1> [[CMP]]5649;5650 5651 %b = or <2 x i8> %a, <i8 24, i8 24>5652 %cmp = icmp slt <2 x i8> %b, <i8 -1, i8 -1>5653 ret <2 x i1> %cmp5654}5655 5656define i1 @or_small_slt_large(i8 %a) {5657; CHECK-LABEL: define i1 @or_small_slt_large(5658; CHECK-SAME: i8 [[A:%.*]]) {5659; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 245660; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 255661; CHECK-NEXT: ret i1 [[CMP]]5662;5663 %b = or i8 %a, 245664 %cmp = icmp slt i8 %b, 255665 ret i1 %cmp5666}5667 5668define <2 x i1> @or_small_slt_large_vec(<2 x i8> %a) {5669; CHECK-LABEL: define <2 x i1> @or_small_slt_large_vec(5670; CHECK-SAME: <2 x i8> [[A:%.*]]) {5671; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A]], splat (i8 24)5672; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 25)5673; CHECK-NEXT: ret <2 x i1> [[CMP]]5674;5675 5676 %b = or <2 x i8> %a, <i8 24, i8 24>5677 %cmp = icmp slt <2 x i8> %b, <i8 25, i8 25>5678 ret <2 x i1> %cmp5679}5680 5681define i1 @or_positive_sgt_zero_multi_use(i8 %a) {5682; CHECK-LABEL: define i1 @or_positive_sgt_zero_multi_use(5683; CHECK-SAME: i8 [[A:%.*]]) {5684; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 245685; CHECK-NEXT: call void @use_i8(i8 [[B]])5686; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -15687; CHECK-NEXT: ret i1 [[CMP]]5688;5689 %b = or i8 %a, 245690 call void @use_i8(i8 %b)5691 %cmp = icmp sgt i8 %b, 05692 ret i1 %cmp5693}5694 5695 5696define i1 @disjoint_or_sgt_1(i8 %a, i8 %b) {5697; CHECK-LABEL: define i1 @disjoint_or_sgt_1(5698; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5699; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B]], 25700; CHECK-NEXT: [[ICMP_:%.*]] = icmp sge i8 [[A]], [[B1]]5701; CHECK-NEXT: ret i1 [[ICMP_]]5702;5703 %a1 = or disjoint i8 %a, 15704 %b1 = add nsw i8 %b, 25705 %icmp_ = icmp sgt i8 %a1, %b15706 ret i1 %icmp_5707}5708 5709define i1 @disjoint_or_sgt_2(i8 %a, i8 %b) {5710; CHECK-LABEL: define i1 @disjoint_or_sgt_2(5711; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5712; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A]], 25713; CHECK-NEXT: [[B1:%.*]] = add i8 [[B]], 15714; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]]5715; CHECK-NEXT: ret i1 [[ICMP_]]5716;5717 %a1 = or disjoint i8 %a, 25718 %b1 = add i8 %b, 15719 %icmp_ = icmp sgt i8 %a1, %b15720 ret i1 %icmp_5721}5722 5723define i1 @disjoint_or_sgt_3(i8 %a, i8 %b) {5724; CHECK-LABEL: define i1 @disjoint_or_sgt_3(5725; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5726; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A]], 25727; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B]], 15728; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]]5729; CHECK-NEXT: ret i1 [[ICMP_]]5730;5731 %a1 = or disjoint i8 %a, 25732 %b1 = add nuw i8 %b, 15733 %icmp_ = icmp sgt i8 %a1, %b15734 ret i1 %icmp_5735}5736 5737define i1 @disjoint_or_ugt_1(i8 %a, i8 %b) {5738; CHECK-LABEL: define i1 @disjoint_or_ugt_1(5739; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5740; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B]], 25741; CHECK-NEXT: [[ICMP_:%.*]] = icmp uge i8 [[A]], [[B1]]5742; CHECK-NEXT: ret i1 [[ICMP_]]5743;5744 %a1 = or disjoint i8 %a, 15745 %b1 = add nsw i8 %b, 25746 %icmp_ = icmp ugt i8 %a1, %b15747 ret i1 %icmp_5748}5749 5750define i1 @disjoint_or_ugt_2(i8 %a, i8 %b) {5751; CHECK-LABEL: define i1 @disjoint_or_ugt_2(5752; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5753; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A]], 25754; CHECK-NEXT: [[B1:%.*]] = add i8 [[B]], 15755; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]]5756; CHECK-NEXT: ret i1 [[ICMP_]]5757;5758 %a1 = or disjoint i8 %a, 25759 %b1 = add i8 %b, 15760 %icmp_ = icmp ugt i8 %a1, %b15761 ret i1 %icmp_5762}5763 5764define i1 @disjoint_or_ugt_3(i8 %a, i8 %b) {5765; CHECK-LABEL: define i1 @disjoint_or_ugt_3(5766; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5767; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A]], 25768; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B]], 15769; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]]5770; CHECK-NEXT: ret i1 [[ICMP_]]5771;5772 %a1 = or disjoint i8 %a, 25773 %b1 = add nuw i8 %b, 15774 %icmp_ = icmp ugt i8 %a1, %b15775 ret i1 %icmp_5776}5777 5778define i1 @deduce_nuw_flag_1(i8 %a, i8 %b) {5779; CHECK-LABEL: define i1 @deduce_nuw_flag_1(5780; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5781; CHECK-NEXT: [[ENTRY:.*:]]5782; CHECK-NEXT: [[TMP0:%.*]] = add nuw i8 [[B]], 15783; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A]]5784; CHECK-NEXT: ret i1 [[CMP]]5785;5786entry:5787 %add1 = add nuw i8 %b, 25788 %add2 = add i8 %a, 15789 %cmp = icmp eq i8 %add1, %add25790 ret i1 %cmp5791}5792 5793define i1 @deduce_nuw_flag_2(i8 %a, i8 %b) {5794; CHECK-LABEL: define i1 @deduce_nuw_flag_2(5795; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5796; CHECK-NEXT: [[ENTRY:.*:]]5797; CHECK-NEXT: [[TMP0:%.*]] = add nuw i8 [[B]], 15798; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[TMP0]]5799; CHECK-NEXT: ret i1 [[CMP]]5800;5801entry:5802 %add1 = add nuw i8 %b, 25803 %add2 = add i8 %a, 15804 %cmp = icmp eq i8 %add2, %add15805 ret i1 %cmp5806}5807 5808define i1 @dont_deduce_nuw_flag_1(i8 %a, i8 %b) {5809; CHECK-LABEL: define i1 @dont_deduce_nuw_flag_1(5810; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5811; CHECK-NEXT: [[ENTRY:.*:]]5812; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[B]], -15813; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A]]5814; CHECK-NEXT: ret i1 [[CMP]]5815;5816entry:5817 %add1 = add nuw i8 %b, -25818 %add2 = add i8 %a, -15819 %cmp = icmp eq i8 %add1, %add25820 ret i1 %cmp5821}5822 5823define i1 @dont_deduce_nuw_flag_2(i8 %a, i8 %b) {5824; CHECK-LABEL: define i1 @dont_deduce_nuw_flag_2(5825; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {5826; CHECK-NEXT: [[ENTRY:.*:]]5827; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[B]], -15828; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[TMP0]]5829; CHECK-NEXT: ret i1 [[CMP]]5830;5831entry:5832 %add1 = add nuw i8 %b, -25833 %add2 = add i8 %a, -15834 %cmp = icmp eq i8 %add2, %add15835 ret i1 %cmp5836}5837 5838define i1 @icmp_freeze_sext(i16 %x, i16 %y) {5839; CHECK-LABEL: define i1 @icmp_freeze_sext(5840; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {5841; CHECK-NEXT: [[Y_FR:%.*]] = freeze i16 [[Y]]5842; CHECK-NEXT: [[X_FR:%.*]] = freeze i16 [[X]]5843; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i16 [[X_FR]], [[Y_FR]]5844; CHECK-NEXT: ret i1 [[CMP2]]5845;5846 %cmp1 = icmp uge i16 %x, %y5847 %ext = sext i1 %cmp1 to i165848 %ext.fr = freeze i16 %ext5849 %cmp2 = icmp uge i16 %ext.fr, %y5850 ret i1 %cmp25851}5852 5853define i1 @test_icmp_shl(i64 %x) {5854; CHECK-LABEL: define i1 @test_icmp_shl(5855; CHECK-SAME: i64 [[X:%.*]]) {5856; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X]] to i325857; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], 35858; CHECK-NEXT: ret i1 [[CMP]]5859;5860 %shl = shl i64 %x, 325861 %cmp = icmp ult i64 %shl, 85899345935862 ret i1 %cmp5863}5864 5865define i1 @test_icmp_shl_multiuse(i64 %x) {5866; CHECK-LABEL: define i1 @test_icmp_shl_multiuse(5867; CHECK-SAME: i64 [[X:%.*]]) {5868; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X]], 325869; CHECK-NEXT: call void @use_i64(i64 [[SHL]])5870; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 85899345935871; CHECK-NEXT: ret i1 [[CMP]]5872;5873 %shl = shl i64 %x, 325874 call void @use_i64(i64 %shl)5875 %cmp = icmp ult i64 %shl, 85899345935876 ret i1 %cmp5877}5878 5879define i1 @test_icmp_shl_illegal_length(i64 %x) {5880; CHECK-LABEL: define i1 @test_icmp_shl_illegal_length(5881; CHECK-SAME: i64 [[X:%.*]]) {5882; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X]], 315883; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 85899345935884; CHECK-NEXT: ret i1 [[CMP]]5885;5886 %shl = shl i64 %x, 315887 %cmp = icmp ult i64 %shl, 85899345935888 ret i1 %cmp5889}5890 5891define i1 @test_icmp_shl_invalid_rhsc(i64 %x) {5892; CHECK-LABEL: define i1 @test_icmp_shl_invalid_rhsc(5893; CHECK-SAME: i64 [[X:%.*]]) {5894; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X]], 325895; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 85899345955896; CHECK-NEXT: ret i1 [[CMP]]5897;5898 %shl = shl i64 %x, 325899 %cmp = icmp ult i64 %shl, 85899345955900 ret i1 %cmp5901}5902 5903define i1 @test_icmp_shl_nuw(i64 %x) {5904; CHECK-LABEL: define i1 @test_icmp_shl_nuw(5905; CHECK-SAME: i64 [[X:%.*]]) {5906; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X]], 35907; CHECK-NEXT: ret i1 [[CMP]]5908;5909 %shl = shl nuw i64 %x, 325910 %cmp = icmp ult i64 %shl, 85899345935911 ret i1 %cmp5912}5913 5914define i1 @test_icmp_shl_nuw_i31(i31 %x) {5915; CHECK-LABEL: define i1 @test_icmp_shl_nuw_i31(5916; CHECK-SAME: i31 [[X:%.*]]) {5917; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i31 [[X]], 2505918; CHECK-NEXT: ret i1 [[CMP]]5919;5920 %shl = shl nuw i31 %x, 235921 %cmp = icmp ugt i31 %shl, -503316485922 ret i1 %cmp5923}5924 5925define i1 @test_icmp_shl_nsw(i64 %x) {5926; CHECK-LABEL: define i1 @test_icmp_shl_nsw(5927; CHECK-SAME: i64 [[X:%.*]]) {5928; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X]], 35929; CHECK-NEXT: ret i1 [[CMP]]5930;5931 %shl = shl nsw i64 %x, 325932 %cmp = icmp ult i64 %shl, 85899345935933 ret i1 %cmp5934}5935 5936define i1 @test_icmp_shl_nsw_i31(i31 %x) {5937; CHECK-LABEL: define i1 @test_icmp_shl_nsw_i31(5938; CHECK-SAME: i31 [[X:%.*]]) {5939; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i31 [[X]] to i85940; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[TMP1]], -65941; CHECK-NEXT: ret i1 [[CMP]]5942;5943 %shl = shl nsw i31 %x, 235944 %cmp = icmp ugt i31 %shl, -503316485945 ret i1 %cmp5946}5947 5948define <2 x i1> @test_icmp_shl_vec(<2 x i64> %x) {5949; CHECK-LABEL: define <2 x i1> @test_icmp_shl_vec(5950; CHECK-SAME: <2 x i64> [[X:%.*]]) {5951; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i64> [[X]] to <2 x i32>5952; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3)5953; CHECK-NEXT: ret <2 x i1> [[CMP]]5954;5955 %shl = shl <2 x i64> %x, splat(i64 32)5956 %cmp = icmp ult <2 x i64> %shl, splat(i64 8589934593)5957 ret <2 x i1> %cmp5958}5959 5960define i1 @test_icmp_shl_eq(i64 %x) {5961; CHECK-LABEL: define i1 @test_icmp_shl_eq(5962; CHECK-SAME: i64 [[X:%.*]]) {5963; CHECK-NEXT: ret i1 false5964;5965 %shl = shl i64 %x, 325966 %cmp = icmp eq i64 %shl, 85899345935967 ret i1 %cmp5968}5969 5970define i1 @test_icmp_shl_sgt(i64 %x) {5971; CHECK-LABEL: define i1 @test_icmp_shl_sgt(5972; CHECK-SAME: i64 [[X:%.*]]) {5973; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X]] to i325974; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 15975; CHECK-NEXT: ret i1 [[CMP]]5976;5977 %shl = shl i64 %x, 325978 %cmp = icmp sgt i64 %shl, 85899345915979 ret i1 %cmp5980}5981 5982define i1 @pr94897(i32 range(i32 -2147483648, 0) %x) {5983; CHECK-LABEL: define i1 @pr94897(5984; CHECK-SAME: i32 range(i32 -2147483648, 0) [[X:%.*]]) {5985; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[X]], -35986; CHECK-NEXT: ret i1 [[CMP]]5987;5988 %shl = shl nsw i32 %x, 245989 %cmp = icmp ugt i32 %shl, -503316485990 ret i1 %cmp5991}5992 5993define i1 @icmp_and_inv_pow2_ne_0(i32 %A, i32 %B) {5994; CHECK-LABEL: define i1 @icmp_and_inv_pow2_ne_0(5995; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {5996; CHECK-NEXT: [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A]])5997; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[POPCNT]], 15998; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])5999; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A]], [[B]]6000; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 06001; CHECK-NEXT: ret i1 [[CMP]]6002;6003 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)6004 %cond = icmp eq i32 %popcnt, 16005 call void @llvm.assume(i1 %cond)6006 6007 %inv = xor i32 %B, -16008 %and = and i32 %A, %inv6009 %cmp = icmp ne i32 %and, 06010 ret i1 %cmp6011}6012 6013define i1 @icmp_and_inv_pow2_or_zero_ne_0(i32 %A, i32 %B) {6014; CHECK-LABEL: define i1 @icmp_and_inv_pow2_or_zero_ne_0(6015; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {6016; CHECK-NEXT: [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A]])6017; CHECK-NEXT: [[COND:%.*]] = icmp samesign ult i32 [[POPCNT]], 26018; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6019; CHECK-NEXT: [[INV:%.*]] = xor i32 [[B]], -16020; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[INV]]6021; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 06022; CHECK-NEXT: ret i1 [[CMP]]6023;6024 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)6025 %cond = icmp ult i32 %popcnt, 26026 call void @llvm.assume(i1 %cond)6027 6028 %inv = xor i32 %B, -16029 %and = and i32 %A, %inv6030 %cmp = icmp ne i32 %and, 06031 ret i1 %cmp6032}6033 6034define i1 @icmp_samesign_logical_and(i32 %In) {6035; CHECK-LABEL: define i1 @icmp_samesign_logical_and(6036; CHECK-SAME: i32 [[IN:%.*]]) {6037; CHECK-NEXT: [[V:%.*]] = icmp eq i32 [[IN]], 16038; CHECK-NEXT: ret i1 [[V]]6039;6040 %c1 = icmp samesign sgt i32 %In, -16041 %c2 = icmp samesign eq i32 %In, 16042 %V = select i1 %c1, i1 %c2, i1 false6043 ret i1 %V6044}6045 6046define i1 @icmp_samesign_logical_or(i32 %In) {6047; CHECK-LABEL: define i1 @icmp_samesign_logical_or(6048; CHECK-SAME: i32 [[IN:%.*]]) {6049; CHECK-NEXT: [[V:%.*]] = icmp ne i32 [[IN]], 16050; CHECK-NEXT: ret i1 [[V]]6051;6052 %c1 = icmp samesign slt i32 %In, 06053 %c2 = icmp samesign ne i32 %In, 16054 %V = select i1 %c1, i1 true, i1 %c26055 ret i1 %V6056}6057 6058define i1 @non_zero_ptrdiff_implies_icmp_eq(ptr %p0, ptr %p1) {6059; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq(6060; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {6061; CHECK-NEXT: [[ENTRY:.*:]]6062; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i646063; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i646064; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]6065; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 126066; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6067; CHECK-NEXT: ret i1 false6068;6069entry:6070 %i0 = ptrtoint ptr %p0 to i646071 %i1 = ptrtoint ptr %p1 to i646072 %diff = sub i64 %i0, %i16073 %cond = icmp eq i64 %diff, 126074 call void @llvm.assume(i1 %cond)6075 %cmp = icmp eq ptr %p0, %p16076 ret i1 %cmp6077}6078 6079define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(ptr %p0, ptr %p1) {6080; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(6081; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {6082; CHECK-NEXT: [[ENTRY:.*:]]6083; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i646084; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i646085; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]6086; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 126087; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6088; CHECK-NEXT: ret i1 false6089;6090entry:6091 %i0 = ptrtoint ptr %p0 to i646092 %i1 = ptrtoint ptr %p1 to i646093 %diff = sub i64 %i0, %i16094 %cond = icmp eq i64 %diff, 126095 call void @llvm.assume(i1 %cond)6096 %cmp = icmp eq ptr %p1, %p06097 ret i1 %cmp6098}6099 6100define i1 @non_zero_ptrdiff_implies_icmp_ne(ptr %p0, ptr %p1) {6101; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_ne(6102; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {6103; CHECK-NEXT: [[ENTRY:.*:]]6104; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i646105; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i646106; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]6107; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 126108; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6109; CHECK-NEXT: ret i1 true6110;6111entry:6112 %i0 = ptrtoint ptr %p0 to i646113 %i1 = ptrtoint ptr %p1 to i646114 %diff = sub i64 %i0, %i16115 %cond = icmp eq i64 %diff, 126116 call void @llvm.assume(i1 %cond)6117 %cmp = icmp ne ptr %p0, %p16118 ret i1 %cmp6119}6120 6121; TODO: Handle this case if it is shown in real code.6122define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(ptr %p0, ptr %p1) {6123; CHECK-LABEL: define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(6124; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {6125; CHECK-NEXT: [[ENTRY:.*:]]6126; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P0]] to i646127; CHECK-NEXT: [[I0:%.*]] = trunc i64 [[TMP0]] to i86128; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P1]] to i646129; CHECK-NEXT: [[I1:%.*]] = trunc i64 [[TMP1]] to i86130; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[I0]], [[I1]]6131; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 126132; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6133; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P0]], [[P1]]6134; CHECK-NEXT: ret i1 [[CMP]]6135;6136entry:6137 %i0 = ptrtoint ptr %p0 to i86138 %i1 = ptrtoint ptr %p1 to i86139 %diff = sub i8 %i0, %i16140 %cond = icmp eq i8 %diff, 126141 call void @llvm.assume(i1 %cond)6142 %cmp = icmp ne ptr %p0, %p16143 ret i1 %cmp6144}6145 6146define i1 @non_zero_diff_implies_icmp_eq(i8 %p0, i8 %p1) {6147; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq(6148; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {6149; CHECK-NEXT: [[ENTRY:.*:]]6150; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]6151; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 126152; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6153; CHECK-NEXT: ret i1 false6154;6155entry:6156 %diff = sub i8 %p0, %p16157 %cond = icmp eq i8 %diff, 126158 call void @llvm.assume(i1 %cond)6159 %cmp = icmp eq i8 %p0, %p16160 ret i1 %cmp6161}6162 6163define i1 @non_zero_diff_implies_icmp_eq_commuted(i8 %p0, i8 %p1) {6164; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq_commuted(6165; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {6166; CHECK-NEXT: [[ENTRY:.*:]]6167; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]6168; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 126169; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6170; CHECK-NEXT: ret i1 false6171;6172entry:6173 %diff = sub i8 %p0, %p16174 %cond = icmp eq i8 %diff, 126175 call void @llvm.assume(i1 %cond)6176 %cmp = icmp eq i8 %p1, %p06177 ret i1 %cmp6178}6179 6180; Negative tests6181 6182define i1 @unknown_ptrdiff_implies_icmp_eq1(ptr %p0, ptr %p1) {6183; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq1(6184; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {6185; CHECK-NEXT: [[ENTRY:.*:]]6186; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i646187; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i646188; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]6189; CHECK-NEXT: [[COND:%.*]] = icmp ne i64 [[DIFF]], 126190; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6191; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]6192; CHECK-NEXT: ret i1 [[CMP]]6193;6194entry:6195 %i0 = ptrtoint ptr %p0 to i646196 %i1 = ptrtoint ptr %p1 to i646197 %diff = sub i64 %i0, %i16198 %cond = icmp ne i64 %diff, 126199 call void @llvm.assume(i1 %cond)6200 %cmp = icmp eq ptr %p0, %p16201 ret i1 %cmp6202}6203 6204define i1 @unknown_ptrdiff_implies_icmp_eq2(ptr %p0, ptr %p1, i64 %x) {6205; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq2(6206; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]], i64 [[X:%.*]]) {6207; CHECK-NEXT: [[ENTRY:.*:]]6208; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i646209; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i646210; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]6211; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], [[X]]6212; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6213; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]6214; CHECK-NEXT: ret i1 [[CMP]]6215;6216entry:6217 %i0 = ptrtoint ptr %p0 to i646218 %i1 = ptrtoint ptr %p1 to i646219 %diff = sub i64 %i0, %i16220 %cond = icmp eq i64 %diff, %x6221 call void @llvm.assume(i1 %cond)6222 %cmp = icmp eq ptr %p0, %p16223 ret i1 %cmp6224}6225 6226define i1 @non_zero_diff_implies_icmp_ult(i8 %p0, i8 %p1) {6227; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_ult(6228; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {6229; CHECK-NEXT: [[ENTRY:.*:]]6230; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]6231; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 126232; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])6233; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[P0]], [[P1]]6234; CHECK-NEXT: ret i1 [[CMP]]6235;6236entry:6237 %diff = sub i8 %p0, %p16238 %cond = icmp eq i8 %diff, 126239 call void @llvm.assume(i1 %cond)6240 %cmp = icmp ult i8 %p0, %p16241 ret i1 %cmp6242}6243