763 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare i8 @llvm.smin.i8(i8, i8)5declare i8 @llvm.umin.i8(i8, i8)6declare i8 @llvm.smax.i8(i8, i8)7declare i8 @llvm.umax.i8(i8, i8)8 9declare void @llvm.assume(i1)10 11declare void @use.i8(i8)12declare void @use.i1(i1)13 14define i8 @xor_1(i8 %a, i1 %c, i8 %x, i8 %y) {15; CHECK-LABEL: @xor_1(16; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -12417; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]18; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[TMP2]], [[A:%.*]]19; CHECK-NEXT: ret i8 [[NOT_BA]]20;21 %nx = xor i8 %x, -122 %yy = xor i8 %y, 12323 %b = select i1 %c, i8 %nx, i8 %yy24 %ba = xor i8 %b, %a25 %not_ba = xor i8 %ba, -126 ret i8 %not_ba27}28 29define i8 @xor_2(i8 %a, i1 %c, i8 %x, i8 %y) {30; CHECK-LABEL: @xor_2(31; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -12432; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]33; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[A:%.*]], [[TMP2]]34; CHECK-NEXT: ret i8 [[NOT_AB]]35;36 %nx = xor i8 %x, -137 %yy = xor i8 %y, 12338 %b = select i1 %c, i8 %nx, i8 %yy39 %ab = xor i8 %a, %b40 %not_ab = xor i8 %ab, -141 ret i8 %not_ab42}43 44define i8 @xor_fail(i8 %a, i1 %c, i8 %x, i8 %y) {45; CHECK-LABEL: @xor_fail(46; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -147; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[Y:%.*]]48; CHECK-NEXT: [[AB:%.*]] = xor i8 [[A:%.*]], [[B]]49; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -150; CHECK-NEXT: ret i8 [[NOT_AB]]51;52 %nx = xor i8 %x, -153 %b = select i1 %c, i8 %nx, i8 %y54 %ab = xor i8 %a, %b55 %not_ab = xor i8 %ab, -156 ret i8 %not_ab57}58 59define i8 @add_1(i8 %a, i1 %c, i8 %x, i8 %y) {60; CHECK-LABEL: @add_1(61; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -12462; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]63; CHECK-NEXT: [[NOT_BA:%.*]] = sub i8 [[TMP2]], [[A:%.*]]64; CHECK-NEXT: ret i8 [[NOT_BA]]65;66 %nx = xor i8 %x, -167 %yy = xor i8 %y, 12368 %b = select i1 %c, i8 %nx, i8 %yy69 %ba = add i8 %b, %a70 %not_ba = xor i8 %ba, -171 ret i8 %not_ba72}73 74define i8 @add_2(i8 %a, i1 %c, i8 %x, i8 %y) {75; CHECK-LABEL: @add_2(76; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -12477; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]78; CHECK-NEXT: [[NOT_AB:%.*]] = sub i8 [[TMP2]], [[A:%.*]]79; CHECK-NEXT: ret i8 [[NOT_AB]]80;81 %nx = xor i8 %x, -182 %yy = xor i8 %y, 12383 %b = select i1 %c, i8 %nx, i8 %yy84 %ab = add i8 %a, %b85 %not_ab = xor i8 %ab, -186 ret i8 %not_ab87}88 89define i8 @add_fail(i8 %a, i1 %c, i8 %x, i8 %y) {90; CHECK-LABEL: @add_fail(91; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], [[A:%.*]]92; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 12393; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]94; CHECK-NEXT: [[AB:%.*]] = add i8 [[A]], [[B]]95; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -196; CHECK-NEXT: ret i8 [[NOT_AB]]97;98 %nx = xor i8 %x, %a99 %yy = xor i8 %y, 123100 %b = select i1 %c, i8 %nx, i8 %yy101 %ab = add i8 %a, %b102 %not_ab = xor i8 %ab, -1103 ret i8 %not_ab104}105 106define i8 @sub_1(i8 %a, i1 %c, i8 %x, i8 %y) {107; CHECK-LABEL: @sub_1(108; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124109; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]110; CHECK-NEXT: [[NOT_BA:%.*]] = add i8 [[TMP2]], [[A:%.*]]111; CHECK-NEXT: ret i8 [[NOT_BA]]112;113 %nx = xor i8 %x, -1114 %yy = xor i8 %y, 123115 %b = select i1 %c, i8 %nx, i8 %yy116 %ba = sub i8 %b, %a117 %not_ba = xor i8 %ba, -1118 ret i8 %not_ba119}120 121define i8 @sub_2(i8 %a, i1 %c, i8 %x, i8 %y) {122; CHECK-LABEL: @sub_2(123; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124124; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]125; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], [[A:%.*]]126; CHECK-NEXT: [[NOT_AB:%.*]] = sub i8 -2, [[TMP3]]127; CHECK-NEXT: ret i8 [[NOT_AB]]128;129 %nx = xor i8 %x, -1130 %yy = xor i8 %y, 123131 %b = select i1 %c, i8 %nx, i8 %yy132 %ab = sub i8 %a, %b133 %not_ab = xor i8 %ab, -1134 ret i8 %not_ab135}136 137; Same as above but with a type larger than i64 to make sure we create -2138; correctly.139define i128 @sub_3(i128 %a, i1 %c, i128 %x, i128 %y) {140; CHECK-LABEL: @sub_3(141; CHECK-NEXT: [[TMP1:%.*]] = xor i128 [[Y:%.*]], -124142; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i128 [[X:%.*]], i128 [[TMP1]]143; CHECK-NEXT: [[TMP3:%.*]] = add i128 [[TMP2]], [[A:%.*]]144; CHECK-NEXT: [[NOT_AB:%.*]] = sub i128 -2, [[TMP3]]145; CHECK-NEXT: ret i128 [[NOT_AB]]146;147 %nx = xor i128 %x, -1148 %yy = xor i128 %y, 123149 %b = select i1 %c, i128 %nx, i128 %yy150 %ab = sub i128 %a, %b151 %not_ab = xor i128 %ab, -1152 ret i128 %not_ab153}154 155define i8 @sub_fail(i8 %a, i1 %c, i8 %x, i8 %y) {156; CHECK-LABEL: @sub_fail(157; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1158; CHECK-NEXT: call void @use.i8(i8 [[NX]])159; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124160; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[TMP1]]161; CHECK-NEXT: [[NOT_BA:%.*]] = add i8 [[TMP2]], [[A:%.*]]162; CHECK-NEXT: ret i8 [[NOT_BA]]163;164 %nx = xor i8 %x, -1165 %yy = xor i8 %y, 123166 call void @use.i8(i8 %nx)167 %b = select i1 %c, i8 %nx, i8 %yy168 %ba = sub i8 %b, %a169 %not_ba = xor i8 %ba, -1170 ret i8 %not_ba171}172 173define i8 @ashr_1(i8 %a, i1 %c, i8 %x, i8 %y) {174; CHECK-LABEL: @ashr_1(175; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124176; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]177; CHECK-NEXT: [[NOT_BA:%.*]] = ashr i8 [[TMP2]], [[A:%.*]]178; CHECK-NEXT: ret i8 [[NOT_BA]]179;180 %nx = xor i8 %x, -1181 %yy = xor i8 %y, 123182 %b = select i1 %c, i8 %nx, i8 %yy183 %ba = ashr i8 %b, %a184 %not_ba = xor i8 %ba, -1185 ret i8 %not_ba186}187 188define i8 @ashr_2_fail(i8 %a, i1 %c, i8 %x, i8 %y) {189; CHECK-LABEL: @ashr_2_fail(190; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1191; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123192; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]193; CHECK-NEXT: [[AB:%.*]] = ashr i8 [[A:%.*]], [[B]]194; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1195; CHECK-NEXT: ret i8 [[NOT_AB]]196;197 %nx = xor i8 %x, -1198 %yy = xor i8 %y, 123199 %b = select i1 %c, i8 %nx, i8 %yy200 %ab = ashr i8 %a, %b201 %not_ab = xor i8 %ab, -1202 ret i8 %not_ab203}204 205define i8 @select_1(i1 %cc, i8 %na, i8 %aa, i1 %c, i8 %x, i8 %y) {206; CHECK-LABEL: @select_1(207; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[NA:%.*]], [[AA:%.*]]208; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[TMP1]], -46209; CHECK-NEXT: [[TMP3:%.*]] = xor i8 [[Y:%.*]], -124210; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP3]]211; CHECK-NEXT: [[NOT_AB:%.*]] = select i1 [[CC:%.*]], i8 [[TMP2]], i8 [[TMP4]]212; CHECK-NEXT: ret i8 [[NOT_AB]]213;214 %nx = xor i8 %x, -1215 %yy = xor i8 %y, 123216 %b = select i1 %c, i8 %nx, i8 %yy217 %nna = xor i8 %na, 45218 %a = xor i8 %aa, %nna219 %ab = select i1 %cc, i8 %a, i8 %b220 %not_ab = xor i8 %ab, -1221 ret i8 %not_ab222}223 224define i8 @select_2(i1 %cc, i8 %na, i1 %c, i8 %x, i8 %y) {225; CHECK-LABEL: @select_2(226; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124227; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]228; CHECK-NEXT: [[TMP3:%.*]] = xor i8 [[NA:%.*]], -46229; CHECK-NEXT: [[NOT_BA:%.*]] = select i1 [[CC:%.*]], i8 [[TMP2]], i8 [[TMP3]]230; CHECK-NEXT: ret i8 [[NOT_BA]]231;232 %nx = xor i8 %x, -1233 %yy = xor i8 %y, 123234 %b = select i1 %c, i8 %nx, i8 %yy235 %a = xor i8 %na, 45236 %ba = select i1 %cc, i8 %b, i8 %a237 %not_ba = xor i8 %ba, -1238 ret i8 %not_ba239}240 241define i1 @select_logic_or_fail(i1 %cc, i1 %c, i1 %x, i8 %y) {242; CHECK-LABEL: @select_logic_or_fail(243; CHECK-NEXT: [[NX:%.*]] = xor i1 [[X:%.*]], true244; CHECK-NEXT: [[YY:%.*]] = icmp eq i8 [[Y:%.*]], 123245; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i1 [[NX]], i1 [[YY]]246; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i1 [[B]], i1 false247; CHECK-NEXT: [[NOT_AB:%.*]] = xor i1 [[AB]], true248; CHECK-NEXT: ret i1 [[NOT_AB]]249;250 %nx = xor i1 %x, -1251 %yy = icmp eq i8 %y, 123252 %b = select i1 %c, i1 %nx, i1 %yy253 %ab = select i1 %cc, i1 %b, i1 false254 %not_ab = xor i1 %ab, -1255 ret i1 %not_ab256}257 258define i1 @select_logic_and_fail(i1 %cc, i1 %c, i1 %x, i8 %y) {259; CHECK-LABEL: @select_logic_and_fail(260; CHECK-NEXT: [[NX:%.*]] = xor i1 [[X:%.*]], true261; CHECK-NEXT: [[YY:%.*]] = icmp eq i8 [[Y:%.*]], 123262; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i1 [[NX]], i1 [[YY]]263; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i1 true, i1 [[B]]264; CHECK-NEXT: [[NOT_AB:%.*]] = xor i1 [[AB]], true265; CHECK-NEXT: ret i1 [[NOT_AB]]266;267 %nx = xor i1 %x, -1268 %yy = icmp eq i8 %y, 123269 %b = select i1 %c, i1 %nx, i1 %yy270 %ab = select i1 %cc, i1 true, i1 %b271 %not_ab = xor i1 %ab, -1272 ret i1 %not_ab273}274 275define i8 @smin_1(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) {276; CHECK-LABEL: @smin_1(277; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[NA:%.*]], [[AA:%.*]]278; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y:%.*]], -124279; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP2]]280; CHECK-NEXT: [[NOT_AB:%.*]] = call i8 @llvm.smax.i8(i8 [[TMP1]], i8 [[TMP3]])281; CHECK-NEXT: ret i8 [[NOT_AB]]282;283 %nx = xor i8 %x, -1284 %yy = xor i8 %y, 123285 %b = select i1 %c, i8 %nx, i8 %yy286 %nna = xor i8 %na, -1287 %a = add i8 %aa, %nna288 %ab = call i8 @llvm.smin.i8(i8 %a, i8 %b)289 %not_ab = xor i8 %ab, -1290 ret i8 %not_ab291}292 293define i8 @smin_1_fail(i8 %a, i1 %c, i8 %x, i8 %y) {294; CHECK-LABEL: @smin_1_fail(295; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1296; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123297; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]298; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smin.i8(i8 [[A:%.*]], i8 [[B]])299; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1300; CHECK-NEXT: ret i8 [[NOT_AB]]301;302 %nx = xor i8 %x, -1303 %yy = xor i8 %y, 123304 %b = select i1 %c, i8 %nx, i8 %yy305 %ab = call i8 @llvm.smin.i8(i8 %a, i8 %b)306 %not_ab = xor i8 %ab, -1307 ret i8 %not_ab308}309 310define i8 @umin_1_fail(i1 %c, i8 %x, i8 %y) {311; CHECK-LABEL: @umin_1_fail(312; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1313; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[Y:%.*]]314; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 85)315; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1316; CHECK-NEXT: ret i8 [[NOT_BA]]317;318 %nx = xor i8 %x, -1319 %b = select i1 %c, i8 %nx, i8 %y320 %ba = call i8 @llvm.umin.i8(i8 %b, i8 85)321 %not_ba = xor i8 %ba, -1322 ret i8 %not_ba323}324 325define i8 @smax_1(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) {326; CHECK-LABEL: @smax_1(327; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[NA:%.*]], [[AA:%.*]]328; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y:%.*]], -124329; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP2]]330; CHECK-NEXT: [[NOT_AB:%.*]] = call i8 @llvm.smin.i8(i8 [[TMP1]], i8 [[TMP3]])331; CHECK-NEXT: ret i8 [[NOT_AB]]332;333 %nx = xor i8 %x, -1334 %yy = xor i8 %y, 123335 %b = select i1 %c, i8 %nx, i8 %yy336 %nna = xor i8 %na, -1337 %a = sub i8 %nna, %aa338 %ab = call i8 @llvm.smax.i8(i8 %a, i8 %b)339 %not_ab = xor i8 %ab, -1340 ret i8 %not_ab341}342 343define i8 @smax_1_fail(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) {344; CHECK-LABEL: @smax_1_fail(345; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1346; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123347; CHECK-NEXT: call void @use.i8(i8 [[YY]])348; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]349; CHECK-NEXT: [[NNA:%.*]] = xor i8 [[NA:%.*]], -1350; CHECK-NEXT: [[A:%.*]] = sub i8 [[NNA]], [[AA:%.*]]351; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]])352; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1353; CHECK-NEXT: ret i8 [[NOT_AB]]354;355 %nx = xor i8 %x, -1356 %yy = xor i8 %y, 123357 call void @use.i8(i8 %yy)358 %b = select i1 %c, i8 %nx, i8 %yy359 %nna = xor i8 %na, -1360 %a = sub i8 %nna, %aa361 %ab = call i8 @llvm.smax.i8(i8 %a, i8 %b)362 %not_ab = xor i8 %ab, -1363 ret i8 %not_ab364}365 366define i8 @umax_1(i8 %na, i1 %c, i8 %x, i8 %y) {367; CHECK-LABEL: @umax_1(368; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124369; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]370; CHECK-NEXT: [[NOT_BA:%.*]] = call i8 @llvm.umin.i8(i8 [[TMP2]], i8 -86)371; CHECK-NEXT: ret i8 [[NOT_BA]]372;373 %nx = xor i8 %x, -1374 %yy = xor i8 %y, 123375 %b = select i1 %c, i8 %nx, i8 %yy376 %ba = call i8 @llvm.umax.i8(i8 %b, i8 85)377 %not_ba = xor i8 %ba, -1378 ret i8 %not_ba379}380 381define i8 @umax_1_fail(i8 %na, i1 %c, i8 %x, i8 %y) {382; CHECK-LABEL: @umax_1_fail(383; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1384; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123385; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]386; CHECK-NEXT: call void @use.i8(i8 [[B]])387; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 85)388; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1389; CHECK-NEXT: ret i8 [[NOT_BA]]390;391 %nx = xor i8 %x, -1392 %yy = xor i8 %y, 123393 %b = select i1 %c, i8 %nx, i8 %yy394 call void @use.i8(i8 %b)395 %ba = call i8 @llvm.umax.i8(i8 %b, i8 85)396 %not_ba = xor i8 %ba, -1397 ret i8 %not_ba398}399 400define i8 @sub_both_freely_invertable_always(i8 %x, i8 %y) {401; CHECK-LABEL: @sub_both_freely_invertable_always(402; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123403; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45404; CHECK-NEXT: [[R:%.*]] = sub i8 [[XX]], [[YY]]405; CHECK-NEXT: ret i8 [[R]]406;407 %xx = xor i8 %x, 123408 %yy = xor i8 %y, 45409 %r = sub i8 %xx, %yy410 ret i8 %r411}412 413define i8 @add_both_freely_invertable_always(i8 %x, i8 %y) {414; CHECK-LABEL: @add_both_freely_invertable_always(415; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123416; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45417; CHECK-NEXT: [[R:%.*]] = add i8 [[XX]], [[YY]]418; CHECK-NEXT: ret i8 [[R]]419;420 %xx = xor i8 %x, 123421 %yy = xor i8 %y, 45422 %r = add i8 %xx, %yy423 ret i8 %r424}425 426define i8 @xor_both_freely_invertable_always(i8 %x, i8 %y) {427; CHECK-LABEL: @xor_both_freely_invertable_always(428; CHECK-NEXT: [[XX:%.*]] = add i8 [[X:%.*]], 123429; CHECK-NEXT: [[YY:%.*]] = add i8 [[Y:%.*]], 45430; CHECK-NEXT: [[R:%.*]] = xor i8 [[XX]], [[YY]]431; CHECK-NEXT: ret i8 [[R]]432;433 %xx = add i8 %x, 123434 %yy = add i8 %y, 45435 %r = xor i8 %xx, %yy436 ret i8 %r437}438 439define i8 @ashr_both_freely_invertable_always(i8 %x, i8 %y) {440; CHECK-LABEL: @ashr_both_freely_invertable_always(441; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123442; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45443; CHECK-NEXT: [[R:%.*]] = ashr i8 [[XX]], [[YY]]444; CHECK-NEXT: ret i8 [[R]]445;446 %xx = xor i8 %x, 123447 %yy = xor i8 %y, 45448 %r = ashr i8 %xx, %yy449 ret i8 %r450}451 452define i8 @select_both_freely_invertable_always(i1 %cc, i8 %x, i8 %y) {453; CHECK-LABEL: @select_both_freely_invertable_always(454; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123455; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45456; CHECK-NEXT: [[R:%.*]] = select i1 [[CC:%.*]], i8 [[XX]], i8 [[YY]]457; CHECK-NEXT: ret i8 [[R]]458;459 %xx = xor i8 %x, 123460 %yy = xor i8 %y, 45461 %r = select i1 %cc, i8 %xx, i8 %yy462 ret i8 %r463}464 465define i8 @umin_both_freely_invertable_always(i8 %x, i8 %y) {466; CHECK-LABEL: @umin_both_freely_invertable_always(467; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123468; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45469; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[XX]], i8 [[YY]])470; CHECK-NEXT: ret i8 [[R]]471;472 %xx = xor i8 %x, 123473 %yy = xor i8 %y, 45474 %r = call i8 @llvm.umin.i8(i8 %xx, i8 %yy)475 ret i8 %r476}477 478define i8 @umax_both_freely_invertable_always(i8 %x, i8 %y) {479; CHECK-LABEL: @umax_both_freely_invertable_always(480; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123481; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45482; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[XX]], i8 [[YY]])483; CHECK-NEXT: ret i8 [[R]]484;485 %xx = xor i8 %x, 123486 %yy = xor i8 %y, 45487 %r = call i8 @llvm.umax.i8(i8 %xx, i8 %yy)488 ret i8 %r489}490 491define i8 @smin_both_freely_invertable_always(i8 %x, i8 %y) {492; CHECK-LABEL: @smin_both_freely_invertable_always(493; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123494; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45495; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[XX]], i8 [[YY]])496; CHECK-NEXT: ret i8 [[R]]497;498 %xx = xor i8 %x, 123499 %yy = xor i8 %y, 45500 %r = call i8 @llvm.smin.i8(i8 %xx, i8 %yy)501 ret i8 %r502}503 504define i8 @smax_both_freely_invertable_always(i8 %x, i8 %y) {505; CHECK-LABEL: @smax_both_freely_invertable_always(506; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123507; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45508; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[XX]], i8 [[YY]])509; CHECK-NEXT: ret i8 [[R]]510;511 %xx = xor i8 %x, 123512 %yy = xor i8 %y, 45513 %r = call i8 @llvm.smax.i8(i8 %xx, i8 %yy)514 ret i8 %r515}516 517define i8 @lshr_nneg(i8 %x, i8 %y) {518; CHECK-LABEL: @lshr_nneg(519; CHECK-NEXT: [[NEG:%.*]] = icmp slt i8 [[X:%.*]], 0520; CHECK-NEXT: call void @llvm.assume(i1 [[NEG]])521; CHECK-NEXT: [[SHR_NOT:%.*]] = ashr i8 [[X]], [[Y:%.*]]522; CHECK-NEXT: ret i8 [[SHR_NOT]]523;524 %neg = icmp slt i8 %x, 0525 call void @llvm.assume(i1 %neg)526 %x.not = xor i8 %x, -1527 %shr = lshr i8 %x.not, %y528 %shr.not = xor i8 %shr, -1529 ret i8 %shr.not530}531 532define i8 @lshr_not_nneg(i8 %x, i8 %y) {533; CHECK-LABEL: @lshr_not_nneg(534; CHECK-NEXT: [[X_NOT:%.*]] = xor i8 [[X:%.*]], -1535; CHECK-NEXT: [[SHR:%.*]] = lshr i8 [[X_NOT]], [[Y:%.*]]536; CHECK-NEXT: [[SHR_NOT:%.*]] = xor i8 [[SHR]], -1537; CHECK-NEXT: ret i8 [[SHR_NOT]]538;539 %x.not = xor i8 %x, -1540 %shr = lshr i8 %x.not, %y541 %shr.not = xor i8 %shr, -1542 ret i8 %shr.not543}544 545define i8 @lshr_not_nneg2(i8 %x) {546; CHECK-LABEL: @lshr_not_nneg2(547; CHECK-NEXT: [[SHR:%.*]] = lshr i8 [[X:%.*]], 1548; CHECK-NEXT: [[SHR_NOT:%.*]] = or disjoint i8 [[SHR]], -128549; CHECK-NEXT: ret i8 [[SHR_NOT]]550;551 %x.not = xor i8 %x, -1552 %shr = lshr i8 %x.not, 1553 %shr.not = xor i8 %shr, -1554 ret i8 %shr.not555}556 557define i1 @test_inv_free(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {558; CHECK-LABEL: @test_inv_free(559; CHECK-NEXT: entry:560; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]561; CHECK: b1:562; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]563; CHECK: b2:564; CHECK-NEXT: br label [[EXIT]]565; CHECK: b3:566; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[C3:%.*]], [[C4:%.*]]567; CHECK-NEXT: br label [[EXIT]]568; CHECK: exit:569; CHECK-NEXT: [[COND_NOT:%.*]] = phi i1 [ false, [[B1]] ], [ [[C4]], [[B2]] ], [ [[TMP0]], [[B3]] ]570; CHECK-NEXT: br i1 [[COND_NOT]], label [[B5:%.*]], label [[B4:%.*]]571; CHECK: b4:572; CHECK-NEXT: ret i1 true573; CHECK: b5:574; CHECK-NEXT: ret i1 false575;576entry:577 br i1 %c1, label %b1, label %b2578b1:579 br i1 %c2, label %exit, label %b3580b2:581 br label %exit582b3:583 %invc3 = xor i1 %c3, true584 br label %exit585exit:586 %val = phi i1 [ true, %b1 ], [ false, %b2 ], [ %invc3, %b3 ]587 %inv = xor i1 %c4, true588 %cond = or i1 %val, %inv589 br i1 %cond, label %b4, label %b5590b4:591 ret i1 true592b5:593 ret i1 false594}595 596define i32 @test_inv_free_i32(i1 %c1, i1 %c2, i32 %c3, i32 %c4) {597; CHECK-LABEL: @test_inv_free_i32(598; CHECK-NEXT: entry:599; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]600; CHECK: b1:601; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]602; CHECK: b2:603; CHECK-NEXT: br label [[EXIT]]604; CHECK: b3:605; CHECK-NEXT: br label [[EXIT]]606; CHECK: exit:607; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[B1]] ], [ -1, [[B2]] ], [ [[C3:%.*]], [[B3]] ]608; CHECK-NEXT: [[COND:%.*]] = xor i32 [[C4:%.*]], [[TMP0]]609; CHECK-NEXT: ret i32 [[COND]]610;611entry:612 br i1 %c1, label %b1, label %b2613b1:614 br i1 %c2, label %exit, label %b3615b2:616 br label %exit617b3:618 %invc3 = xor i32 %c3, -1619 br label %exit620exit:621 %val = phi i32 [ -1, %b1 ], [ 0, %b2 ], [ %invc3, %b3 ]622 %inv = xor i32 %c4, -1623 %cond = xor i32 %val, %inv624 ret i32 %cond625}626 627; Negative tests628 629define i1 @test_inv_free_multiuse(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {630; CHECK-LABEL: @test_inv_free_multiuse(631; CHECK-NEXT: entry:632; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]633; CHECK: b1:634; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]635; CHECK: b2:636; CHECK-NEXT: br label [[EXIT]]637; CHECK: b3:638; CHECK-NEXT: [[INVC3:%.*]] = xor i1 [[C3:%.*]], true639; CHECK-NEXT: br label [[EXIT]]640; CHECK: exit:641; CHECK-NEXT: [[VAL:%.*]] = phi i1 [ true, [[B1]] ], [ false, [[B2]] ], [ [[INVC3]], [[B3]] ]642; CHECK-NEXT: call void @use.i1(i1 [[VAL]])643; CHECK-NEXT: [[INV:%.*]] = xor i1 [[C4:%.*]], true644; CHECK-NEXT: [[COND:%.*]] = or i1 [[VAL]], [[INV]]645; CHECK-NEXT: br i1 [[COND]], label [[B4:%.*]], label [[B5:%.*]]646; CHECK: b4:647; CHECK-NEXT: ret i1 true648; CHECK: b5:649; CHECK-NEXT: ret i1 false650;651entry:652 br i1 %c1, label %b1, label %b2653b1:654 br i1 %c2, label %exit, label %b3655b2:656 br label %exit657b3:658 %invc3 = xor i1 %c3, true659 br label %exit660exit:661 %val = phi i1 [ true, %b1 ], [ false, %b2 ], [ %invc3, %b3 ]662 call void @use.i1(i1 %val)663 %inv = xor i1 %c4, true664 %cond = or i1 %val, %inv665 br i1 %cond, label %b4, label %b5666b4:667 ret i1 true668b5:669 ret i1 false670}671 672define i32 @test_inv_free_i32_newinst(i1 %c1, i1 %c2, i32 %c3, i32 %c4) {673; CHECK-LABEL: @test_inv_free_i32_newinst(674; CHECK-NEXT: entry:675; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]676; CHECK: b1:677; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]678; CHECK: b2:679; CHECK-NEXT: br label [[EXIT]]680; CHECK: b3:681; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 -8, [[C3:%.*]]682; CHECK-NEXT: br label [[EXIT]]683; CHECK: exit:684; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ -1, [[B1]] ], [ 0, [[B2]] ], [ [[ASHR]], [[B3]] ]685; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[C4:%.*]], [[VAL]]686; CHECK-NEXT: [[COND:%.*]] = xor i32 [[TMP0]], -1687; CHECK-NEXT: ret i32 [[COND]]688;689entry:690 br i1 %c1, label %b1, label %b2691b1:692 br i1 %c2, label %exit, label %b3693b2:694 br label %exit695b3:696 %ashr = ashr i32 -8, %c3697 br label %exit698exit:699 %val = phi i32 [ -1, %b1 ], [ 0, %b2 ], [ %ashr, %b3 ]700 %inv = xor i32 %c4, -1701 %cond = xor i32 %val, %inv702 ret i32 %cond703}704 705define i1 @test_inv_free_loop(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {706; CHECK-LABEL: @test_inv_free_loop(707; CHECK-NEXT: entry:708; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]709; CHECK: b1:710; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]711; CHECK: b2:712; CHECK-NEXT: br label [[EXIT]]713; CHECK: b3:714; CHECK-NEXT: [[INVC3:%.*]] = xor i1 [[C3:%.*]], true715; CHECK-NEXT: br label [[EXIT]]716; CHECK: exit:717; CHECK-NEXT: [[VAL:%.*]] = phi i1 [ true, [[B1]] ], [ false, [[B2]] ], [ [[INVC3]], [[B3]] ], [ [[NOT:%.*]], [[EXIT]] ]718; CHECK-NEXT: [[INV:%.*]] = xor i1 [[C4:%.*]], true719; CHECK-NEXT: [[COND:%.*]] = or i1 [[VAL]], [[INV]]720; CHECK-NEXT: [[NOT]] = xor i1 [[VAL]], true721; CHECK-NEXT: br i1 [[COND]], label [[EXIT]], label [[B4:%.*]]722; CHECK: b4:723; CHECK-NEXT: ret i1 true724;725entry:726 br i1 %c1, label %b1, label %b2727b1:728 br i1 %c2, label %exit, label %b3729b2:730 br label %exit731b3:732 %invc3 = xor i1 %c3, true733 br label %exit734exit:735 %val = phi i1 [ true, %b1 ], [ false, %b2 ], [ %invc3, %b3 ], [ %not, %exit ]736 %inv = xor i1 %c4, true737 %cond = or i1 %val, %inv738 %not = xor i1 %val, true739 br i1 %cond, label %exit, label %b4740b4:741 ret i1 true742}743 744define i64 @PR71390(i64 %v) {745; CHECK-LABEL: @PR71390(746; CHECK-NEXT: [[AND:%.*]] = and i64 [[V:%.*]], 9187201950435737471747; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i64 -72340172838076674, [[AND]]748; CHECK-NEXT: [[TMP2:%.*]] = add nuw i64 [[AND]], 6872316419617283935749; CHECK-NEXT: [[OR_NOT:%.*]] = and i64 [[TMP1]], [[TMP2]]750; CHECK-NEXT: [[NOT5:%.*]] = or i64 [[V]], [[OR_NOT]]751; CHECK-NEXT: ret i64 [[NOT5]]752;753 %and = and i64 %v, 9187201950435737471754 %add = add nuw i64 %and, 72340172838076673755 %add2 = add nuw i64 %and, 6872316419617283935756 %not = xor i64 %v, -1757 %not3 = xor i64 %add2, -1758 %or = or i64 %add, %not3759 %and4 = and i64 %not, %or760 %not5 = xor i64 %and4, -1761 ret i64 %not5762}763