511 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -debugify-and-strip-all-safe -O3 < %s | FileCheck %s3target datalayout = "e-p: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-n32:64"4target triple = "arm64-unknown-unknown"5 6define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp {7; CHECK-LABEL: foo1:8; CHECK: // %bb.0: // %entry9; CHECK-NEXT: cmp w1, #010; CHECK-NEXT: add w8, w1, w011; CHECK-NEXT: cinc w0, w8, ne12; CHECK-NEXT: ret13entry:14 %not.tobool = icmp ne i32 %c, 015 %add = zext i1 %not.tobool to i3216 %b.add = add i32 %c, %b17 %add1 = add i32 %b.add, %add18 ret i32 %add119}20 21define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp {22; CHECK-LABEL: foo2:23; CHECK: // %bb.0: // %entry24; CHECK-NEXT: cmp w1, #025; CHECK-NEXT: cneg w8, w0, ne26; CHECK-NEXT: add w0, w8, w127; CHECK-NEXT: ret28entry:29 %mul = sub i32 0, %b30 %tobool = icmp eq i32 %c, 031 %b.mul = select i1 %tobool, i32 %b, i32 %mul32 %add = add nsw i32 %b.mul, %c33 ret i32 %add34}35 36define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp {37; CHECK-LABEL: foo3:38; CHECK: // %bb.0: // %entry39; CHECK-NEXT: cmp w1, #040; CHECK-NEXT: cinv w8, w0, ne41; CHECK-NEXT: add w0, w8, w142; CHECK-NEXT: ret43entry:44 %not.tobool = icmp ne i32 %c, 045 %xor = sext i1 %not.tobool to i3246 %b.xor = xor i32 %xor, %b47 %add = add nsw i32 %b.xor, %c48 ret i32 %add49}50 51; rdar://1163232552define i32@foo4(i32 %a) nounwind ssp {53; CHECK-LABEL: foo4:54; CHECK: // %bb.0:55; CHECK-NEXT: cmp w0, #056; CHECK-NEXT: cneg w0, w0, mi57; CHECK-NEXT: ret58 %cmp = icmp sgt i32 %a, -159 %neg = sub nsw i32 0, %a60 %cond = select i1 %cmp, i32 %a, i32 %neg61 ret i32 %cond62}63 64define i32@foo5(i32 %a, i32 %b) nounwind ssp {65; CHECK-LABEL: foo5:66; CHECK: // %bb.0: // %entry67; CHECK-NEXT: subs w8, w0, w168; CHECK-NEXT: cneg w0, w8, mi69; CHECK-NEXT: ret70entry:71 %sub = sub nsw i32 %a, %b72 %cmp = icmp sgt i32 %sub, -173 %sub3 = sub nsw i32 0, %sub74 %cond = select i1 %cmp, i32 %sub, i32 %sub375 ret i32 %cond76}77 78; make sure we can handle branch instruction in optimizeCompare.79define i32@foo6(i32 %a, i32 %b) nounwind ssp {80; CHECK-LABEL: foo6:81; CHECK: // %bb.0: // %common.ret82; CHECK-NEXT: subs w8, w0, w183; CHECK-NEXT: csinc w0, w8, wzr, le84; CHECK-NEXT: ret85 %sub = sub nsw i32 %a, %b86 %cmp = icmp sgt i32 %sub, 087 br i1 %cmp, label %l.if, label %l.else88 89l.if:90 ret i32 191 92l.else:93 ret i32 %sub94}95 96; If CPSR is used multiple times and V flag is used, we don't remove cmp.97define i32 @foo7(i32 %a, i32 %b) nounwind {98; CHECK-LABEL: foo7:99; CHECK: // %bb.0: // %entry100; CHECK-NEXT: subs w8, w0, w1101; CHECK-NEXT: cneg w9, w8, mi102; CHECK-NEXT: cmn w8, #1103; CHECK-NEXT: csel w8, w9, w0, lt104; CHECK-NEXT: csel w0, w8, w9, gt105; CHECK-NEXT: ret106entry:107 %sub = sub nsw i32 %a, %b108 %cmp = icmp sgt i32 %sub, -1109 %sub3 = sub nsw i32 0, %sub110 %cond = select i1 %cmp, i32 %sub, i32 %sub3111 br i1 %cmp, label %if.then, label %if.else112 113if.then:114 %cmp2 = icmp slt i32 %sub, -1115 %sel = select i1 %cmp2, i32 %cond, i32 %a116 ret i32 %sel117 118if.else:119 ret i32 %cond120}121 122define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp {123; CHECK-LABEL: foo8:124; CHECK: // %bb.0: // %entry125; CHECK-NEXT: cmp w0, #0126; CHECK-NEXT: csinv w0, w1, w2, ne127; CHECK-NEXT: ret128entry:129 %tobool = icmp eq i32 %v, 0130 %neg = xor i32 -1, %b131 %cond = select i1 %tobool, i32 %neg, i32 %a132 ret i32 %cond133}134 135define i32 @foo9(i32 %v) nounwind readnone optsize ssp {136; CHECK-LABEL: foo9:137; CHECK: // %bb.0: // %entry138; CHECK-NEXT: mov w8, #4 // =0x4139; CHECK-NEXT: cmp w0, #0140; CHECK-NEXT: cinv w0, w8, eq141; CHECK-NEXT: ret142entry:143 %tobool = icmp ne i32 %v, 0144 %cond = select i1 %tobool, i32 4, i32 -5145 ret i32 %cond146}147 148define i64 @foo10(i64 %v) nounwind readnone optsize ssp {149; CHECK-LABEL: foo10:150; CHECK: // %bb.0: // %entry151; CHECK-NEXT: mov w8, #4 // =0x4152; CHECK-NEXT: cmp x0, #0153; CHECK-NEXT: cinv x0, x8, eq154; CHECK-NEXT: ret155entry:156 %tobool = icmp ne i64 %v, 0157 %cond = select i1 %tobool, i64 4, i64 -5158 ret i64 %cond159}160 161define i32 @foo11(i32 %v) nounwind readnone optsize ssp {162; CHECK-LABEL: foo11:163; CHECK: // %bb.0: // %entry164; CHECK-NEXT: mov w8, #4 // =0x4165; CHECK-NEXT: cmp w0, #0166; CHECK-NEXT: cneg w0, w8, eq167; CHECK-NEXT: ret168entry:169 %tobool = icmp ne i32 %v, 0170 %cond = select i1 %tobool, i32 4, i32 -4171 ret i32 %cond172}173 174define i64 @foo12(i64 %v) nounwind readnone optsize ssp {175; CHECK-LABEL: foo12:176; CHECK: // %bb.0: // %entry177; CHECK-NEXT: mov w8, #4 // =0x4178; CHECK-NEXT: cmp x0, #0179; CHECK-NEXT: cneg x0, x8, eq180; CHECK-NEXT: ret181entry:182 %tobool = icmp ne i64 %v, 0183 %cond = select i1 %tobool, i64 4, i64 -4184 ret i64 %cond185}186 187define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp {188; CHECK-LABEL: foo13:189; CHECK: // %bb.0: // %entry190; CHECK-NEXT: cmp w0, #0191; CHECK-NEXT: csneg w0, w1, w2, ne192; CHECK-NEXT: ret193entry:194 %tobool = icmp eq i32 %v, 0195 %sub = sub i32 0, %b196 %cond = select i1 %tobool, i32 %sub, i32 %a197 ret i32 %cond198}199 200define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp {201; CHECK-LABEL: foo14:202; CHECK: // %bb.0: // %entry203; CHECK-NEXT: cmp x0, #0204; CHECK-NEXT: csneg x0, x1, x2, ne205; CHECK-NEXT: ret206entry:207 %tobool = icmp eq i64 %v, 0208 %sub = sub i64 0, %b209 %cond = select i1 %tobool, i64 %sub, i64 %a210 ret i64 %cond211}212 213define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp {214; CHECK-LABEL: foo15:215; CHECK: // %bb.0: // %entry216; CHECK-NEXT: mov w8, #1 // =0x1217; CHECK-NEXT: cmp w0, w1218; CHECK-NEXT: cinc w0, w8, gt219; CHECK-NEXT: ret220entry:221 %cmp = icmp sgt i32 %a, %b222 %. = select i1 %cmp, i32 2, i32 1223 ret i32 %.224}225 226define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp {227; CHECK-LABEL: foo16:228; CHECK: // %bb.0: // %entry229; CHECK-NEXT: mov w8, #1 // =0x1230; CHECK-NEXT: cmp w0, w1231; CHECK-NEXT: cinc w0, w8, le232; CHECK-NEXT: ret233entry:234 %cmp = icmp sgt i32 %a, %b235 %. = select i1 %cmp, i32 1, i32 2236 ret i32 %.237}238 239define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp {240; CHECK-LABEL: foo17:241; CHECK: // %bb.0: // %entry242; CHECK-NEXT: mov w8, #1 // =0x1243; CHECK-NEXT: cmp x0, x1244; CHECK-NEXT: cinc x0, x8, gt245; CHECK-NEXT: ret246entry:247 %cmp = icmp sgt i64 %a, %b248 %. = select i1 %cmp, i64 2, i64 1249 ret i64 %.250}251 252define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp {253; CHECK-LABEL: foo18:254; CHECK: // %bb.0: // %entry255; CHECK-NEXT: mov w8, #1 // =0x1256; CHECK-NEXT: cmp x0, x1257; CHECK-NEXT: cinc x0, x8, le258; CHECK-NEXT: ret259entry:260 %cmp = icmp sgt i64 %a, %b261 %. = select i1 %cmp, i64 1, i64 2262 ret i64 %.263}264 265; Regression test for TrueVal + 1 overflow266define i64 @foo18_overflow1(i64 %a, i64 %b) nounwind readnone optsize ssp {267; CHECK-LABEL: foo18_overflow1:268; CHECK: // %bb.0: // %entry269; CHECK-NEXT: mov x8, #9223372036854775807 // =0x7fffffffffffffff270; CHECK-NEXT: cmp x0, x1271; CHECK-NEXT: csel x0, x8, xzr, gt272; CHECK-NEXT: ret273entry:274 %cmp = icmp sgt i64 %a, %b275 %. = select i1 %cmp, i64 9223372036854775807, i64 0276 ret i64 %.277}278 279; Regression test for FalseVal + 1 overflow280define i64 @foo18_overflow2(i64 %a, i64 %b) nounwind readnone optsize ssp {281; CHECK-LABEL: foo18_overflow2:282; CHECK: // %bb.0: // %entry283; CHECK-NEXT: mov x8, #9223372036854775807 // =0x7fffffffffffffff284; CHECK-NEXT: cmp x0, x1285; CHECK-NEXT: csel x0, xzr, x8, gt286; CHECK-NEXT: ret287entry:288 %cmp = icmp sgt i64 %a, %b289 %. = select i1 %cmp, i64 0, i64 9223372036854775807290 ret i64 %.291}292 293; Regression test for FalseVal - TrueVal overflow294define i64 @foo18_overflow3(i1 %cmp) nounwind readnone optsize ssp {295; CHECK-LABEL: foo18_overflow3:296; CHECK: // %bb.0: // %entry297; CHECK-NEXT: mov x8, #-9223372036854775808 // =0x8000000000000000298; CHECK-NEXT: tst w0, #0x1299; CHECK-NEXT: csel x0, x8, xzr, ne300; CHECK-NEXT: ret301entry:302 %. = select i1 %cmp, i64 -9223372036854775808, i64 0303 ret i64 %.304}305 306; Regression test for TrueVal - FalseVal overflow307define i64 @foo18_overflow4(i1 %cmp) nounwind readnone optsize ssp {308; CHECK-LABEL: foo18_overflow4:309; CHECK: // %bb.0: // %entry310; CHECK-NEXT: mov x8, #-9223372036854775808 // =0x8000000000000000311; CHECK-NEXT: tst w0, #0x1312; CHECK-NEXT: csel x0, xzr, x8, ne313; CHECK-NEXT: ret314entry:315 %. = select i1 %cmp, i64 0, i64 -9223372036854775808316 ret i64 %.317}318 319define i64 @foo19(i64 %a, i64 %b, i64 %c) {320; CHECK-LABEL: foo19:321; CHECK: // %bb.0: // %entry322; CHECK-NEXT: cmp x0, x1323; CHECK-NEXT: cinc x0, x2, lo324; CHECK-NEXT: ret325entry:326 %cmp = icmp ult i64 %a, %b327 %inc = zext i1 %cmp to i64328 %inc.c = add i64 %inc, %c329 ret i64 %inc.c330}331 332define i32 @foo20(i32 %x) {333; CHECK-LABEL: foo20:334; CHECK: // %bb.0:335; CHECK-NEXT: mov w8, #6 // =0x6336; CHECK-NEXT: cmp w0, #5337; CHECK-NEXT: csinc w0, w8, wzr, eq338; CHECK-NEXT: ret339 %cmp = icmp eq i32 %x, 5340 %res = select i1 %cmp, i32 6, i32 1341 ret i32 %res342}343 344define i64 @foo21(i64 %x) {345; CHECK-LABEL: foo21:346; CHECK: // %bb.0:347; CHECK-NEXT: mov w8, #6 // =0x6348; CHECK-NEXT: cmp x0, #5349; CHECK-NEXT: csinc x0, x8, xzr, eq350; CHECK-NEXT: ret351 %cmp = icmp eq i64 %x, 5352 %res = select i1 %cmp, i64 6, i64 1353 ret i64 %res354}355 356define i32 @foo22(i32 %x) {357; CHECK-LABEL: foo22:358; CHECK: // %bb.0:359; CHECK-NEXT: mov w8, #6 // =0x6360; CHECK-NEXT: cmp w0, #5361; CHECK-NEXT: csinc w0, w8, wzr, ne362; CHECK-NEXT: ret363 %cmp = icmp eq i32 %x, 5364 %res = select i1 %cmp, i32 1, i32 6365 ret i32 %res366}367 368define i64 @foo23(i64 %x) {369; CHECK-LABEL: foo23:370; CHECK: // %bb.0:371; CHECK-NEXT: mov w8, #6 // =0x6372; CHECK-NEXT: cmp x0, #5373; CHECK-NEXT: csinc x0, x8, xzr, ne374; CHECK-NEXT: ret375 %cmp = icmp eq i64 %x, 5376 %res = select i1 %cmp, i64 1, i64 6377 ret i64 %res378}379 380define i16 @foo24(ptr nocapture readonly %A, ptr nocapture readonly %B) {381; CHECK-LABEL: foo24:382; CHECK: // %bb.0: // %entry383; CHECK-NEXT: ldrb w8, [x0]384; CHECK-NEXT: ldrb w9, [x1]385; CHECK-NEXT: cmp w8, #3386; CHECK-NEXT: cset w8, hi387; CHECK-NEXT: cmp w9, #33388; CHECK-NEXT: cinc w0, w8, hi389; CHECK-NEXT: ret390entry:391 %0 = load i8, ptr %A, align 1392 %cmp = icmp ugt i8 %0, 3393 %conv1 = zext i1 %cmp to i16394 %1 = load i8, ptr %B, align 1395 %cmp4 = icmp ugt i8 %1, 33396 %conv5 = zext i1 %cmp4 to i16397 %add = add nuw nsw i16 %conv5, %conv1398 ret i16 %add399}400 401define i64 @foo25(ptr nocapture readonly %A, ptr nocapture readonly %B) {402; CHECK-LABEL: foo25:403; CHECK: // %bb.0: // %entry404; CHECK-NEXT: ldr x8, [x1]405; CHECK-NEXT: ldr x9, [x0]406; CHECK-NEXT: cmp x8, #33407; CHECK-NEXT: cset w8, hi408; CHECK-NEXT: cmp x9, #3409; CHECK-NEXT: cinc x0, x8, hi410; CHECK-NEXT: ret411entry:412 %0 = load i64, ptr %A, align 1413 %cmp = icmp ugt i64 %0, 3414 %conv1 = zext i1 %cmp to i64415 %1 = load i64, ptr %B, align 1416 %cmp4 = icmp ugt i64 %1, 33417 %conv5 = zext i1 %cmp4 to i64418 %add = add nuw nsw i64 %conv5, %conv1419 ret i64 %add420}421 422define i32 @or(i32 %num, i32 %x) {423; CHECK-LABEL: or:424; CHECK: // %bb.0: // %entry425; CHECK-NEXT: and w8, w0, #0xff00426; CHECK-NEXT: cmp w1, #0427; CHECK-NEXT: cinc w0, w8, ne428; CHECK-NEXT: ret429entry:430 %and = and i32 %num, 65280431 %tobool.not = icmp ne i32 %x, 0432 %cond = zext i1 %tobool.not to i32433 %or = or disjoint i32 %and, %cond434 ret i32 %or435}436 437define i64 @or64(i64 %num, i64 %x) {438; CHECK-LABEL: or64:439; CHECK: // %bb.0: // %entry440; CHECK-NEXT: and x8, x0, #0xff00441; CHECK-NEXT: cmp x1, #0442; CHECK-NEXT: cinc x0, x8, ne443; CHECK-NEXT: ret444entry:445 %and = and i64 %num, 65280446 %tobool.not = icmp ne i64 %x, 0447 %conv = zext i1 %tobool.not to i64448 %or = or disjoint i64 %and, %conv449 ret i64 %or450}451 452define i32 @selor32(i32 %num, i32 %x) {453; CHECK-LABEL: selor32:454; CHECK: // %bb.0: // %entry455; CHECK-NEXT: and w8, w0, #0xff00456; CHECK-NEXT: cmp w1, #0457; CHECK-NEXT: cinc w0, w8, ne458; CHECK-NEXT: ret459entry:460 %and = and i32 %num, 65280461 %tobool.not = icmp ne i32 %x, 0462 %or = or disjoint i32 %and, 1463 %sel = select i1 %tobool.not, i32 %or, i32 %and464 ret i32 %sel465}466 467define i32 @selor32_2(i32 %num, i32 %x) {468; CHECK-LABEL: selor32_2:469; CHECK: // %bb.0: // %entry470; CHECK-NEXT: and w8, w0, #0xff00471; CHECK-NEXT: cmp w1, #0472; CHECK-NEXT: orr w9, w8, #0x2473; CHECK-NEXT: csel w0, w9, w8, ne474; CHECK-NEXT: ret475entry:476 %and = and i32 %num, 65280477 %tobool.not = icmp ne i32 %x, 0478 %or = or disjoint i32 %and, 2479 %sel = select i1 %tobool.not, i32 %or, i32 %and480 ret i32 %sel481}482 483define i64 @selor64(i64 %num, i64 %x) {484; CHECK-LABEL: selor64:485; CHECK: // %bb.0: // %entry486; CHECK-NEXT: and x8, x0, #0xff00487; CHECK-NEXT: cmp x1, #0488; CHECK-NEXT: cinc x0, x8, ne489; CHECK-NEXT: ret490entry:491 %and = and i64 %num, 65280492 %tobool.not = icmp ne i64 %x, 0493 %or = or disjoint i64 %and, 1494 %sel = select i1 %tobool.not, i64 %or, i64 %and495 ret i64 %sel496}497 498; Same as above with disjoint but without knowing haveNoCommonBitsSet.499define i64 @selor64_disjoint(i64 %num, i64 %x) {500; CHECK-LABEL: selor64_disjoint:501; CHECK: // %bb.0: // %entry502; CHECK-NEXT: cmp x1, #0503; CHECK-NEXT: cinc x0, x0, ne504; CHECK-NEXT: ret505entry:506 %tobool.not = icmp ne i64 %x, 0507 %or = or disjoint i64 %num, 1508 %sel = select i1 %tobool.not, i64 %or, i64 %num509 ret i64 %sel510}511