812 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @llvm.assume(i1)5declare void @barrier()6declare void @use.i8(i8)7 8; Test case of X comp X^Neg_C, which have Transform to SLT.9; X s< X^Neg_C --> X s< 010define i1 @src_slt(i8 %x) {11; CHECK-LABEL: @src_slt(12; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 013; CHECK-NEXT: ret i1 [[CMP]]14;15 %not = xor i8 %x, -116 %cmp = icmp slt i8 %x, %not17 ret i1 %cmp18}19 20define <2 x i1> @src_slt_vec(<2 x i8> %x) {21; CHECK-LABEL: @src_slt_vec(22; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer23; CHECK-NEXT: ret <2 x i1> [[CMP]]24;25 %not = xor <2 x i8> %x, <i8 -1, i8 -1>26 %cmp = icmp slt <2 x i8> %x, %not27 ret <2 x i1> %cmp28}29 30; X s<= X^Neg_C --> X s< 031define i1 @src_sle(i8 %x) {32; CHECK-LABEL: @src_sle(33; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 034; CHECK-NEXT: ret i1 [[CMP]]35;36 %not = xor i8 %x, -137 %cmp = icmp sle i8 %x, %not38 ret i1 %cmp39}40 41define <2 x i1> @src_sle_vec(<2 x i8> %x) {42; CHECK-LABEL: @src_sle_vec(43; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer44; CHECK-NEXT: ret <2 x i1> [[CMP]]45;46 %not = xor <2 x i8> %x, <i8 -1, i8 -1>47 %cmp = icmp sle <2 x i8> %x, %not48 ret <2 x i1> %cmp49}50 51; X u> X^Neg_C --> X s< 052define i1 @src_ugt(i8 %x) {53; CHECK-LABEL: @src_ugt(54; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 055; CHECK-NEXT: ret i1 [[CMP]]56;57 %not = xor i8 %x, -158 %cmp = icmp ugt i8 %x, %not59 ret i1 %cmp60}61 62define <2 x i1> @src_ugt_vec(<2 x i8> %x) {63; CHECK-LABEL: @src_ugt_vec(64; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer65; CHECK-NEXT: ret <2 x i1> [[CMP]]66;67 %not = xor <2 x i8> %x, <i8 -1, i8 -1>68 %cmp = icmp ugt <2 x i8> %x, %not69 ret <2 x i1> %cmp70}71 72; X u>= X^Neg_C --> X s< 073define i1 @src_uge(i8 %x) {74; CHECK-LABEL: @src_uge(75; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 076; CHECK-NEXT: ret i1 [[CMP]]77;78 %not = xor i8 %x, -179 %cmp = icmp uge i8 %x, %not80 ret i1 %cmp81}82 83define <2 x i1> @src_uge_vec(<2 x i8> %x) {84; CHECK-LABEL: @src_uge_vec(85; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer86; CHECK-NEXT: ret <2 x i1> [[CMP]]87;88 %not = xor <2 x i8> %x, <i8 -1, i8 -1>89 %cmp = icmp uge <2 x i8> %x, %not90 ret <2 x i1> %cmp91}92 93define <2 x i1> @src_uge_vec_min(<2 x i8> %x) {94; CHECK-LABEL: @src_uge_vec_min(95; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer96; CHECK-NEXT: ret <2 x i1> [[CMP]]97;98 %not = xor <2 x i8> %x, <i8 -128, i8 -128>99 %cmp = icmp uge <2 x i8> %x, %not100 ret <2 x i1> %cmp101}102 103define <2 x i1> @src_uge_vec_128(<2 x i128> %x) {104; CHECK-LABEL: @src_uge_vec_128(105; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i128> [[X:%.*]], zeroinitializer106; CHECK-NEXT: ret <2 x i1> [[CMP]]107;108 %not = xor <2 x i128> %x, <i128 -170141183460469231731687303715884105728, i128 -170141183460469231731687303715884105728>109 %cmp = icmp uge <2 x i128> %x, %not110 ret <2 x i1> %cmp111}112 113; Test case of X comp X^Neg_C, which have Transform to SGT.114; X s> X^Neg_C --> X s> -1115define i1 @src_sgt(i8 %x) {116; CHECK-LABEL: @src_sgt(117; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1118; CHECK-NEXT: ret i1 [[CMP]]119;120 %not = xor i8 %x, -1121 %cmp = icmp sgt i8 %x, %not122 ret i1 %cmp123}124 125define <2 x i1> @src_sgt_vec(<2 x i8> %x) {126; CHECK-LABEL: @src_sgt_vec(127; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)128; CHECK-NEXT: ret <2 x i1> [[CMP]]129;130 %not = xor <2 x i8> %x, <i8 -1, i8 -1>131 %cmp = icmp sgt <2 x i8> %x, %not132 ret <2 x i1> %cmp133}134 135; X s>= X^Neg_C --> X s> -1136define i1 @src_sge(i8 %x) {137; CHECK-LABEL: @src_sge(138; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1139; CHECK-NEXT: ret i1 [[CMP]]140;141 %not = xor i8 %x, -1142 %cmp = icmp sge i8 %x, %not143 ret i1 %cmp144}145 146define <2 x i1> @src_sge_vec(<2 x i8> %x) {147; CHECK-LABEL: @src_sge_vec(148; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)149; CHECK-NEXT: ret <2 x i1> [[CMP]]150;151 %not = xor <2 x i8> %x, <i8 -1, i8 -1>152 %cmp = icmp sge <2 x i8> %x, %not153 ret <2 x i1> %cmp154}155 156; X u< X^Neg_C --> X s> -1157define i1 @src_ult(i8 %x) {158; CHECK-LABEL: @src_ult(159; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1160; CHECK-NEXT: ret i1 [[CMP]]161;162 %not = xor i8 %x, -1163 %cmp = icmp ult i8 %x, %not164 ret i1 %cmp165}166 167define <2 x i1> @src_ult_vec(<2 x i8> %x) {168; CHECK-LABEL: @src_ult_vec(169; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)170; CHECK-NEXT: ret <2 x i1> [[CMP]]171;172 %not = xor <2 x i8> %x, <i8 -1, i8 -1>173 %cmp = icmp ult <2 x i8> %x, %not174 ret <2 x i1> %cmp175}176 177; X u<= X^Neg_C --> X s> -1178define i1 @src_ule(i8 %x) {179; CHECK-LABEL: @src_ule(180; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1181; CHECK-NEXT: ret i1 [[CMP]]182;183 %not = xor i8 %x, -1184 %cmp = icmp ule i8 %x, %not185 ret i1 %cmp186}187 188define <2 x i1> @src_ule_vec(<2 x i8> %x) {189; CHECK-LABEL: @src_ule_vec(190; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)191; CHECK-NEXT: ret <2 x i1> [[CMP]]192;193 %not = xor <2 x i8> %x, <i8 -1, i8 -1>194 %cmp = icmp ule <2 x i8> %x, %not195 ret <2 x i1> %cmp196}197 198define <2 x i1> @src_ule_vec_min(<2 x i8> %x) {199; CHECK-LABEL: @src_ule_vec_min(200; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)201; CHECK-NEXT: ret <2 x i1> [[CMP]]202;203 %not = xor <2 x i8> %x, <i8 -128, i8 -128>204 %cmp = icmp ule <2 x i8> %x, %not205 ret <2 x i1> %cmp206}207 208define <2 x i1> @src_ule_vec_128(<2 x i128> %x) {209; CHECK-LABEL: @src_ule_vec_128(210; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i128> [[X:%.*]], splat (i128 -1)211; CHECK-NEXT: ret <2 x i1> [[CMP]]212;213 %not = xor <2 x i128> %x, <i128 -170141183460469231731687303715884105728, i128 -170141183460469231731687303715884105728>214 %cmp = icmp ule <2 x i128> %x, %not215 ret <2 x i1> %cmp216}217 218; X comp X^Neg_C tests. negative219; X comp Y220define i1 @src_sle_xny(i8 %x, i8 %y) {221; CHECK-LABEL: @src_sle_xny(222; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1223; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y_NOT]]224; CHECK-NEXT: ret i1 [[CMP]]225;226 %y.not = xor i8 %y, -1227 %cmp = icmp sle i8 %x, %y.not228 ret i1 %cmp229}230define i1 @src_sle_nyx(i8 %x, i8 %y) {231; CHECK-LABEL: @src_sle_nyx(232; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1233; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y_NOT]]234; CHECK-NEXT: ret i1 [[CMP]]235;236 %y.not = xor i8 %y, -1237 %cmp = icmp sle i8 %y.not, %x238 ret i1 %cmp239}240define i1 @src_sge_xny(i8 %x, i8 %y) {241; CHECK-LABEL: @src_sge_xny(242; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1243; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y_NOT]]244; CHECK-NEXT: ret i1 [[CMP]]245;246 %y.not = xor i8 %y, -1247 %cmp = icmp sge i8 %x, %y.not248 ret i1 %cmp249}250define i1 @src_sge_nyx(i8 %x, i8 %y) {251; CHECK-LABEL: @src_sge_nyx(252; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1253; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y_NOT]]254; CHECK-NEXT: ret i1 [[CMP]]255;256 %y.not = xor i8 %y, -1257 %cmp = icmp sge i8 %y.not, %x258 ret i1 %cmp259}260define i1 @src_ule_xny(i8 %x, i8 %y) {261; CHECK-LABEL: @src_ule_xny(262; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1263; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y_NOT]]264; CHECK-NEXT: ret i1 [[CMP]]265;266 %y.not = xor i8 %y, -1267 %cmp = icmp ule i8 %x, %y.not268 ret i1 %cmp269}270define i1 @src_ule_nyx(i8 %x, i8 %y) {271; CHECK-LABEL: @src_ule_nyx(272; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1273; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y_NOT]]274; CHECK-NEXT: ret i1 [[CMP]]275;276 %y.not = xor i8 %y, -1277 %cmp = icmp ule i8 %y.not, %x278 ret i1 %cmp279}280define i1 @src_uge_xny(i8 %x, i8 %y) {281; CHECK-LABEL: @src_uge_xny(282; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1283; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y_NOT]]284; CHECK-NEXT: ret i1 [[CMP]]285;286 %y.not = xor i8 %y, -1287 %cmp = icmp uge i8 %x, %y.not288 ret i1 %cmp289}290define i1 @src_uge_nyx(i8 %x, i8 %y) {291; CHECK-LABEL: @src_uge_nyx(292; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1293; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y_NOT]]294; CHECK-NEXT: ret i1 [[CMP]]295;296 %y.not = xor i8 %y, -1297 %cmp = icmp uge i8 %y.not, %x298 ret i1 %cmp299}300 301; X comp X^Neg_C tests. negative302; (X+1) comp X^Neg_C303define i1 @src_sle_incx_nx(i8 %x) {304; CHECK-LABEL: @src_sle_incx_nx(305; CHECK-NEXT: [[TMP1:%.*]] = sub i8 -2, [[X:%.*]]306; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[TMP1]], [[X]]307; CHECK-NEXT: ret i1 [[CMP]]308;309 %nx = xor i8 %x, -1310 %inc.x = add i8 %x, 1311 %cmp = icmp sle i8 %inc.x, %nx312 ret i1 %cmp313}314; (X-1) comp X^Neg_C315define i1 @src_sle_decx_nx(i8 %x) {316; CHECK-LABEL: @src_sle_decx_nx(317; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[X:%.*]]318; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X]], [[TMP1]]319; CHECK-NEXT: ret i1 [[CMP]]320;321 %nx = xor i8 %x, -1322 %dec.x = add i8 %x, -1323 %cmp = icmp sle i8 %dec.x, %nx324 ret i1 %cmp325}326; X comp (X+1)^Neg_C327define i1 @src_sle_x_nincx(i8 %x) {328; CHECK-LABEL: @src_sle_x_nincx(329; CHECK-NEXT: [[NOT_INC_X:%.*]] = sub i8 -2, [[X:%.*]]330; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X]], [[NOT_INC_X]]331; CHECK-NEXT: ret i1 [[CMP]]332;333 %inc.x = add i8 %x, 1334 %not.inc.x = xor i8 %inc.x, -1335 %cmp = icmp sle i8 %x, %not.inc.x336 ret i1 %cmp337}338; X comp (X-1)^Neg_C339define i1 @src_sle_x_ndecx(i8 %x) {340; CHECK-LABEL: @src_sle_x_ndecx(341; CHECK-NEXT: [[NOT_DEC_X:%.*]] = sub i8 0, [[X:%.*]]342; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X]], [[NOT_DEC_X]]343; CHECK-NEXT: ret i1 [[CMP]]344;345 %dec.x = add i8 %x, -1346 %not.dec.x = xor i8 %dec.x, -1347 %cmp = icmp sle i8 %x, %not.dec.x348 ret i1 %cmp349}350 351; test for (~x ^ y) < ~z352define i1 @test_xor1(i8 %x, i8 %y, i8 %z) {353; CHECK-LABEL: @test_xor1(354; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1355; CHECK-NEXT: call void @use.i8(i8 [[XOR]])356; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]357; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[TMP1]], [[Z:%.*]]358; CHECK-NEXT: ret i1 [[R]]359;360 %xor = xor i8 %x, -1361 call void @use.i8(i8 %xor)362 %xor2 = xor i8 %xor, %y363 %nz = xor i8 %z, -1364 %r = icmp slt i8 %xor2, %nz365 ret i1 %r366}367 368; test for ~z <= (x ^ ~y)369define i1 @test_xor2(i8 %x, i8 %y, i8 %z) {370; CHECK-LABEL: @test_xor2(371; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], -1372; CHECK-NEXT: call void @use.i8(i8 [[XOR]])373; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X:%.*]], [[Y]]374; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[TMP1]], [[Z:%.*]]375; CHECK-NEXT: ret i1 [[R]]376;377 %nz = xor i8 %z, -1378 %xor = xor i8 %y, -1379 call void @use.i8(i8 %xor)380 %xor2 = xor i8 %xor, %x381 %r = icmp sle i8 %nz, %xor2382 ret i1 %r383}384 385; test for ~z > (~x ^ y)386define i1 @test_xor3(i8 %x, i8 %y, i8 %z) {387; CHECK-LABEL: @test_xor3(388; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1389; CHECK-NEXT: call void @use.i8(i8 [[XOR]])390; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]391; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[TMP1]], [[Z:%.*]]392; CHECK-NEXT: ret i1 [[R]]393;394 %nz = xor i8 %z, -1395 %xor = xor i8 %x, -1396 call void @use.i8(i8 %xor)397 %xor2 = xor i8 %xor, %y398 %r = icmp sgt i8 %nz, %xor2399 ret i1 %r400}401 402; tests for equality403define i1 @test_xor_ne(i8 %x, i8 %y, i8 %z) {404; CHECK-LABEL: @test_xor_ne(405; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]406; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[Z:%.*]], [[TMP1]]407; CHECK-NEXT: ret i1 [[R]]408;409 %nz = xor i8 %z, -1410 %xor = xor i8 %y, -1411 %xor2 = xor i8 %xor, %x412 %r = icmp ne i8 %nz, %xor2413 ret i1 %r414}415 416define i1 @test_xor_eq(i8 %x, i8 %y, i8 %z) {417; CHECK-LABEL: @test_xor_eq(418; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]419; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Z:%.*]], [[TMP1]]420; CHECK-NEXT: ret i1 [[R]]421;422 %nz = xor i8 %z, -1423 %xor = xor i8 %y, -1424 %xor2 = xor i8 %xor, %x425 %r = icmp eq i8 %nz, %xor2426 ret i1 %r427}428 429; other tests430define i1 @test_xor4(i8 %x, i8 %y, i8 %z) {431; CHECK-LABEL: @test_xor4(432; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1433; CHECK-NEXT: call void @use.i8(i8 [[XOR]])434; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]435; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[TMP1]], [[Z:%.*]]436; CHECK-NEXT: ret i1 [[R]]437;438 %nz = xor i8 %z, -1439 %xor = xor i8 %x, -1440 call void @use.i8(i8 %xor)441 %xor2 = xor i8 %xor, %y442 %r = icmp sge i8 %xor2, %nz443 ret i1 %r444}445 446define i1 @test_xor5(i8 %x, i8 %y, i8 %z) {447; CHECK-LABEL: @test_xor5(448; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1449; CHECK-NEXT: call void @use.i8(i8 [[XOR]])450; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]451; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[TMP1]], [[Z:%.*]]452; CHECK-NEXT: ret i1 [[R]]453;454 %nz = xor i8 %z, -1455 %xor = xor i8 %x, -1456 call void @use.i8(i8 %xor)457 %xor2 = xor i8 %xor, %y458 %r = icmp ult i8 %xor2, %nz459 ret i1 %r460}461 462define i1 @test_xor6(i8 %x, i8 %y, i8 %z) {463; CHECK-LABEL: @test_xor6(464; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1465; CHECK-NEXT: call void @use.i8(i8 [[XOR]])466; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]467; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[TMP1]], [[Z:%.*]]468; CHECK-NEXT: ret i1 [[R]]469;470 %nz = xor i8 %z, -1471 %xor = xor i8 %x, -1472 call void @use.i8(i8 %xor)473 %xor2 = xor i8 %xor, %y474 %r = icmp ule i8 %xor2, %nz475 ret i1 %r476}477 478define i1 @test_xor7(i8 %x, i8 %y, i8 %z) {479; CHECK-LABEL: @test_xor7(480; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1481; CHECK-NEXT: call void @use.i8(i8 [[XOR]])482; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]483; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[TMP1]], [[Z:%.*]]484; CHECK-NEXT: ret i1 [[R]]485;486 %nz = xor i8 %z, -1487 %xor = xor i8 %x, -1488 call void @use.i8(i8 %xor)489 %xor2 = xor i8 %xor, %y490 %r = icmp ugt i8 %xor2, %nz491 ret i1 %r492}493 494define i1 @test_xor8(i8 %x, i8 %y, i8 %z) {495; CHECK-LABEL: @test_xor8(496; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1497; CHECK-NEXT: call void @use.i8(i8 [[XOR]])498; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X]]499; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[TMP1]], [[Z:%.*]]500; CHECK-NEXT: ret i1 [[R]]501;502 %nz = xor i8 %z, -1503 %xor = xor i8 %x, -1504 call void @use.i8(i8 %xor)505 %xor2 = xor i8 %xor, %y506 %r = icmp uge i8 %xor2, %nz507 ret i1 %r508}509 510; test (~a ^ b) < ~a511define i1 @test_slt_xor(i32 %x, i32 %y) {512; CHECK-LABEL: @test_slt_xor(513; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]514; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], [[X]]515; CHECK-NEXT: ret i1 [[R]]516;517 %xor1 = xor i32 %x, -1518 %xor2 = xor i32 %xor1, %y519 %r = icmp slt i32 %xor2, %xor1520 ret i1 %r521}522 523; test (a ^ ~b) <= ~b524define i1 @test_sle_xor(i32 %x, i32 %y) {525; CHECK-LABEL: @test_sle_xor(526; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]527; CHECK-NEXT: [[R:%.*]] = icmp sge i32 [[TMP1]], [[Y]]528; CHECK-NEXT: ret i1 [[R]]529;530 %xor1 = xor i32 %y, -1531 %xor2 = xor i32 %xor1, %x532 %r = icmp sle i32 %xor2, %xor1533 ret i1 %r534}535 536; test ~a > (~a ^ b)537define i1 @test_sgt_xor(i32 %x, i32 %y) {538; CHECK-LABEL: @test_sgt_xor(539; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]540; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[X]]541; CHECK-NEXT: ret i1 [[CMP]]542;543 %xor1 = xor i32 %x, -1544 %xor2 = xor i32 %xor1, %y545 %cmp = icmp sgt i32 %xor2, %xor1546 ret i1 %cmp547}548 549define i1 @test_sge_xor(i32 %x, i32 %y) {550; CHECK-LABEL: @test_sge_xor(551; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]552; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X]]553; CHECK-NEXT: ret i1 [[CMP]]554;555 %xor1 = xor i32 %x, -1556 %xor2 = xor i32 %xor1, %y557 %cmp = icmp sge i32 %xor2, %xor1558 ret i1 %cmp559}560 561define i1 @test_ult_xor(i32 %x, i32 %y) {562; CHECK-LABEL: @test_ult_xor(563; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]564; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP1]], [[X]]565; CHECK-NEXT: ret i1 [[CMP]]566;567 %xor1 = xor i32 %x, -1568 %xor2 = xor i32 %xor1, %y569 %cmp = icmp ult i32 %xor2, %xor1570 ret i1 %cmp571}572 573define i1 @test_ule_xor(i32 %x, i32 %y) {574; CHECK-LABEL: @test_ule_xor(575; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]576; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[TMP1]], [[X]]577; CHECK-NEXT: ret i1 [[CMP]]578;579 %xor1 = xor i32 %x, -1580 %xor2 = xor i32 %xor1, %y581 %cmp = icmp ule i32 %xor2, %xor1582 ret i1 %cmp583}584 585define i1 @test_ugt_xor(i32 %x, i32 %y) {586; CHECK-LABEL: @test_ugt_xor(587; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]588; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[X]]589; CHECK-NEXT: ret i1 [[CMP]]590;591 %xor1 = xor i32 %x, -1592 %xor2 = xor i32 %xor1, %y593 %cmp = icmp ugt i32 %xor2, %xor1594 ret i1 %cmp595}596 597define i1 @test_uge_xor(i32 %x, i32 %y) {598; CHECK-LABEL: @test_uge_xor(599; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]600; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[TMP1]], [[X]]601; CHECK-NEXT: ret i1 [[CMP]]602;603 %xor1 = xor i32 %x, -1604 %xor2 = xor i32 %xor1, %y605 %cmp = icmp uge i32 %xor2, %xor1606 ret i1 %cmp607}608 609; Negative tests610define i1 @test_xor1_nofold_multi_use(i8 %x, i8 %y, i8 %z) {611; CHECK-LABEL: @test_xor1_nofold_multi_use(612; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]613; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], -1614; CHECK-NEXT: call void @use.i8(i8 [[XOR2]])615; CHECK-NEXT: [[NZ:%.*]] = xor i8 [[Z:%.*]], -1616; CHECK-NEXT: call void @use.i8(i8 [[NZ]])617; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[TMP1]], [[Z]]618; CHECK-NEXT: ret i1 [[R]]619;620 %xor = xor i8 %x, -1621 %xor2 = xor i8 %xor, %y622 call void @use.i8(i8 %xor2)623 %nz = xor i8 %z, -1624 call void @use.i8(i8 %nz)625 %r = icmp slt i8 %xor2, %nz626 ret i1 %r627}628 629define i1 @xor_uge(i8 %x, i8 %y) {630; CHECK-LABEL: @xor_uge(631; CHECK-NEXT: [[YNZ:%.*]] = icmp ne i8 [[Y:%.*]], 0632; CHECK-NEXT: call void @llvm.assume(i1 [[YNZ]])633; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y]]634; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[XOR]], [[X]]635; CHECK-NEXT: ret i1 [[R]]636;637 %ynz = icmp ne i8 %y, 0638 call void @llvm.assume(i1 %ynz)639 %xor = xor i8 %x, %y640 %r = icmp uge i8 %xor, %x641 ret i1 %r642}643 644define i1 @xor_uge_fail_maybe_zero(i8 %x, i8 %y) {645; CHECK-LABEL: @xor_uge_fail_maybe_zero(646; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]647; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[XOR]], [[X]]648; CHECK-NEXT: ret i1 [[R]]649;650 %xor = xor i8 %x, %y651 %r = icmp uge i8 %xor, %x652 ret i1 %r653}654 655define <2 x i1> @xor_ule_2(<2 x i8> %x, <2 x i8> %yy) {656; CHECK-LABEL: @xor_ule_2(657; CHECK-NEXT: [[Y:%.*]] = or <2 x i8> [[YY:%.*]], <i8 9, i8 8>658; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[Y]], [[X:%.*]]659; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[XOR]], [[X]]660; CHECK-NEXT: ret <2 x i1> [[R]]661;662 %y = or <2 x i8> %yy, <i8 9, i8 8>663 %xor = xor <2 x i8> %y, %x664 %r = icmp ule <2 x i8> %xor, %x665 ret <2 x i1> %r666}667 668define i1 @xor_sle_2(i8 %xx, i8 %y, i8 %z) {669; CHECK-LABEL: @xor_sle_2(670; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], [[Z:%.*]]671; CHECK-NEXT: [[YNZ:%.*]] = icmp ne i8 [[Y:%.*]], 0672; CHECK-NEXT: call void @llvm.assume(i1 [[YNZ]])673; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], [[Y]]674; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[XOR]], [[X]]675; CHECK-NEXT: ret i1 [[R]]676;677 %x = add i8 %xx, %z678 %ynz = icmp ne i8 %y, 0679 call void @llvm.assume(i1 %ynz)680 %xor = xor i8 %x, %y681 %r = icmp sle i8 %x, %xor682 ret i1 %r683}684 685define i1 @xor_sge(i8 %xx, i8 %yy) {686; CHECK-LABEL: @xor_sge(687; CHECK-NEXT: [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]]688; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY:%.*]], -128689; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y]], [[X]]690; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[XOR]], [[X]]691; CHECK-NEXT: ret i1 [[R]]692;693 %x = mul i8 %xx, %xx694 %y = or i8 %yy, 128695 %xor = xor i8 %y, %x696 %r = icmp sge i8 %x, %xor697 ret i1 %r698}699 700define i1 @xor_ugt_2(i8 %xx, i8 %y, i8 %z) {701; CHECK-LABEL: @xor_ugt_2(702; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], [[Z:%.*]]703; CHECK-NEXT: [[YZ:%.*]] = and i8 [[Y:%.*]], 63704; CHECK-NEXT: [[Y1:%.*]] = or disjoint i8 [[YZ]], 64705; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], [[Y1]]706; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[XOR]]707; CHECK-NEXT: ret i1 [[R]]708;709 %x = add i8 %xx, %z710 %yz = and i8 %y, 63711 %y1 = or i8 %yz, 64712 %xor = xor i8 %x, %y1713 %r = icmp ugt i8 %x, %xor714 ret i1 %r715}716 717define i1 @xor_ult(i8 %x) {718; CHECK-LABEL: @xor_ult(719; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 123720; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[XOR]], [[X]]721; CHECK-NEXT: ret i1 [[R]]722;723 %xor = xor i8 %x, 123724 %r = icmp ult i8 %xor, %x725 ret i1 %r726}727 728define <2 x i1> @xor_sgt(<2 x i8> %x, <2 x i8> %y) {729; CHECK-LABEL: @xor_sgt(730; CHECK-NEXT: [[YZ:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 31)731; CHECK-NEXT: [[Y1:%.*]] = or disjoint <2 x i8> [[YZ]], splat (i8 64)732; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], [[Y1]]733; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i8> [[XOR]], [[X]]734; CHECK-NEXT: ret <2 x i1> [[R]]735;736 %yz = and <2 x i8> %y, <i8 31, i8 31>737 %y1 = or <2 x i8> %yz, <i8 64, i8 64>738 %xor = xor <2 x i8> %x, %y1739 %r = icmp sgt <2 x i8> %xor, %x740 ret <2 x i1> %r741}742 743define <2 x i1> @xor_sgt_fail_no_known_msb(<2 x i8> %x, <2 x i8> %y) {744; CHECK-LABEL: @xor_sgt_fail_no_known_msb(745; CHECK-NEXT: [[YZ:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 55)746; CHECK-NEXT: [[Y1:%.*]] = or disjoint <2 x i8> [[YZ]], splat (i8 8)747; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], [[Y1]]748; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i8> [[XOR]], [[X]]749; CHECK-NEXT: ret <2 x i1> [[R]]750;751 %yz = and <2 x i8> %y, <i8 63, i8 63>752 %y1 = or <2 x i8> %yz, <i8 8, i8 8>753 %xor = xor <2 x i8> %x, %y1754 %r = icmp sgt <2 x i8> %xor, %x755 ret <2 x i1> %r756}757 758define i1 @xor_slt_2(i8 %x, i8 %y, i8 %z) {759; CHECK-LABEL: @xor_slt_2(760; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 88761; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[X]], [[XOR]]762; CHECK-NEXT: ret i1 [[R]]763;764 %xor = xor i8 %x, 88765 %r = icmp slt i8 %x, %xor766 ret i1 %r767}768 769define <2 x i1> @xor_sgt_intmin_2(<2 x i8> %xx, <2 x i8> %yy, <2 x i8> %z) {770; CHECK-LABEL: @xor_sgt_intmin_2(771; CHECK-NEXT: [[X:%.*]] = add <2 x i8> [[XX:%.*]], [[Z:%.*]]772; CHECK-NEXT: [[Y:%.*]] = or <2 x i8> [[YY:%.*]], splat (i8 -128)773; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X]], [[Y]]774; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i8> [[X]], [[XOR]]775; CHECK-NEXT: ret <2 x i1> [[R]]776;777 %x = add <2 x i8> %xx, %z778 %y = or <2 x i8> %yy, <i8 128, i8 128>779 %xor = xor <2 x i8> %x, %y780 %r = icmp sgt <2 x i8> %x, %xor781 ret <2 x i1> %r782}783 784define i1 @or_slt_intmin_indirect(i8 %x, i8 %C) {785; CHECK-LABEL: @or_slt_intmin_indirect(786; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[C:%.*]], 0787; CHECK-NEXT: br i1 [[CMP]], label [[NEG:%.*]], label [[POS:%.*]]788; CHECK: common.ret:789; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ [[R:%.*]], [[NEG]] ], [ false, [[POS]] ]790; CHECK-NEXT: ret i1 [[COMMON_RET_OP]]791; CHECK: neg:792; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[C]], [[X:%.*]]793; CHECK-NEXT: [[R]] = icmp slt i8 [[XOR]], [[X]]794; CHECK-NEXT: br label [[COMMON_RET:%.*]]795; CHECK: pos:796; CHECK-NEXT: tail call void @barrier()797; CHECK-NEXT: br label [[COMMON_RET]]798;799 %cmp = icmp slt i8 %C, 0800 br i1 %cmp, label %neg, label %pos801common.ret:802 %common.ret.op = phi i1 [ %r, %neg ], [ false, %pos ]803 ret i1 %common.ret.op804neg:805 %xor = xor i8 %C, %x806 %r = icmp slt i8 %xor, %x807 br label %common.ret808pos:809 tail call void @barrier()810 br label %common.ret811}812