890 lines · plain
1; Test that compares are omitted if CC already has the right value2; (z10 version).3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -no-integrated-as \5; RUN: -verify-machineinstrs| FileCheck %s6 7declare void @foo()8 9; Addition provides enough for comparisons with zero if we know no10; signed overflow happens, which is when the "nsw" flag is set.11; First test the EQ case.12define i32 @f1(i32 %a, i32 %b, ptr %dest) {13; CHECK-LABEL: f1:14; CHECK: afi %r2, 100000015; CHECK-NEXT: ber %r1416; CHECK: br %r1417entry:18 %res = add nsw i32 %a, 100000019 %cmp = icmp eq i32 %res, 020 br i1 %cmp, label %exit, label %store21 22store:23 store i32 %b, ptr %dest24 br label %exit25 26exit:27 ret i32 %res28}29 30; ...and again with NE.31define i32 @f2(i32 %a, i32 %b, ptr %dest) {32; CHECK-LABEL: f2:33; CHECK: afi %r2, 100000034; CHECK-NEXT: blhr %r1435; CHECK: br %r1436entry:37 %res = add nsw i32 %a, 100000038 %cmp = icmp ne i32 %res, 039 br i1 %cmp, label %exit, label %store40 41store:42 store i32 %b, ptr %dest43 br label %exit44 45exit:46 ret i32 %res47}48 49; ...and again with SLT.50define i32 @f3(i32 %a, i32 %b, ptr %dest) {51; CHECK-LABEL: f3:52; CHECK: afi %r2, 100000053; CHECK-NEXT: blr %r1454entry:55 %res = add nsw i32 %a, 100000056 %cmp = icmp slt i32 %res, 057 br i1 %cmp, label %exit, label %store58 59store:60 store i32 %b, ptr %dest61 br label %exit62 63exit:64 ret i32 %res65}66 67; ...and again with SLE.68define i32 @f4(i32 %a, i32 %b, ptr %dest) {69; CHECK-LABEL: f4:70; CHECK: afi %r2, 100000071; CHECK-NEXT: bler %r1472entry:73 %res = add nsw i32 %a, 100000074 %cmp = icmp sle i32 %res, 075 br i1 %cmp, label %exit, label %store76 77store:78 store i32 %b, ptr %dest79 br label %exit80 81exit:82 ret i32 %res83}84 85; ...and again with SGT.86define i32 @f5(i32 %a, i32 %b, ptr %dest) {87; CHECK-LABEL: f5:88; CHECK: afi %r2, 100000089; CHECK-NEXT: bhr %r1490entry:91 %res = add nsw i32 %a, 100000092 %cmp = icmp sgt i32 %res, 093 br i1 %cmp, label %exit, label %store94 95store:96 store i32 %b, ptr %dest97 br label %exit98 99exit:100 ret i32 %res101}102 103; ...and again with SGE.104define i32 @f6(i32 %a, i32 %b, ptr %dest) {105; CHECK-LABEL: f6:106; CHECK: afi %r2, 1000000107; CHECK-NEXT: bher %r14108entry:109 %res = add nsw i32 %a, 1000000110 %cmp = icmp sge i32 %res, 0111 br i1 %cmp, label %exit, label %store112 113store:114 store i32 %b, ptr %dest115 br label %exit116 117exit:118 ret i32 %res119}120 121; Subtraction provides in addition also enough for equality comparisons with122; zero even without "nsw".123define i32 @f7(i32 %a, i32 %b, ptr %dest) {124; CHECK-LABEL: f7:125; CHECK: s %r2, 0(%r4)126; CHECK-NEXT: bner %r14127; CHECK: br %r14128entry:129 %cur = load i32, ptr %dest130 %res = sub i32 %a, %cur131 %cmp = icmp ne i32 %res, 0132 br i1 %cmp, label %exit, label %store133 134store:135 store i32 %b, ptr %dest136 br label %exit137 138exit:139 ret i32 %res140}141 142; ...and again with SLT.143define i32 @f8(i32 %a, i32 %b, ptr %dest) {144; CHECK-LABEL: f8:145; CHECK: s %r2, 0(%r4)146; CHECK-NEXT: blr %r14147entry:148 %cur = load i32, ptr %dest149 %res = sub nsw i32 %a, %cur150 %cmp = icmp slt i32 %res, 0151 br i1 %cmp, label %exit, label %store152 153store:154 store i32 %b, ptr %dest155 br label %exit156 157exit:158 ret i32 %res159}160 161; Logic register-register instructions also provide enough for equality162; comparisons with zero.163define i32 @f9(i32 %a, i32 %b, ptr %dest) {164; CHECK-LABEL: f9:165; CHECK: nr %r2, %r3166; CHECK-NEXT: blr %r14167; CHECK: br %r14168entry:169 %res = and i32 %a, %b170 %cmp = icmp ne i32 %res, 0171 br i1 %cmp, label %exit, label %store172 173store:174 store i32 %b, ptr %dest175 br label %exit176 177exit:178 ret i32 %res179}180 181; ...but not for ordered comparisons.182define i32 @f10(i32 %a, i32 %b, ptr %dest) {183; CHECK-LABEL: f10:184; CHECK: nr %r2, %r3185; CHECK-NEXT: cibl %r2, 0, 0(%r14)186; CHECK: br %r14187entry:188 %res = and i32 %a, %b189 %cmp = icmp slt i32 %res, 0190 br i1 %cmp, label %exit, label %store191 192store:193 store i32 %b, ptr %dest194 br label %exit195 196exit:197 ret i32 %res198}199 200; Logic register-immediate instructions also provide enough for equality201; comparisons with zero if the immediate covers the whole register.202define i32 @f11(i32 %a, i32 %b, ptr %dest) {203; CHECK-LABEL: f11:204; CHECK: nilf %r2, 100000001205; CHECK-NEXT: blr %r14206; CHECK: br %r14207entry:208 %res = and i32 %a, 100000001209 %cmp = icmp ne i32 %res, 0210 br i1 %cmp, label %exit, label %store211 212store:213 store i32 %b, ptr %dest214 br label %exit215 216exit:217 ret i32 %res218}219 220; Partial logic register-immediate instructions do not provide simple221; zero results.222define i32 @f12(i32 %a, i32 %b, ptr %dest) {223; CHECK-LABEL: f12:224; CHECK: nill %r2, 65436225; CHECK-NEXT: ciblh %r2, 0, 0(%r14)226; CHECK: br %r14227entry:228 %res = and i32 %a, -100229 %cmp = icmp ne i32 %res, 0230 br i1 %cmp, label %exit, label %store231 232store:233 store i32 %b, ptr %dest234 br label %exit235 236exit:237 ret i32 %res238}239 240; SRA provides the same CC result as a comparison with zero.241define i32 @f13(i32 %a, i32 %b, ptr %dest) {242; CHECK-LABEL: f13:243; CHECK: sra %r2, 0(%r3)244; CHECK-NEXT: ber %r14245; CHECK: br %r14246entry:247 %res = ashr i32 %a, %b248 %cmp = icmp eq i32 %res, 0249 br i1 %cmp, label %exit, label %store250 251store:252 store i32 %b, ptr %dest253 br label %exit254 255exit:256 ret i32 %res257}258 259; ...and again with NE.260define i32 @f14(i32 %a, i32 %b, ptr %dest) {261; CHECK-LABEL: f14:262; CHECK: sra %r2, 0(%r3)263; CHECK-NEXT: blhr %r14264; CHECK: br %r14265entry:266 %res = ashr i32 %a, %b267 %cmp = icmp ne i32 %res, 0268 br i1 %cmp, label %exit, label %store269 270store:271 store i32 %b, ptr %dest272 br label %exit273 274exit:275 ret i32 %res276}277 278; ...and SLT.279define i32 @f15(i32 %a, i32 %b, ptr %dest) {280; CHECK-LABEL: f15:281; CHECK: sra %r2, 0(%r3)282; CHECK-NEXT: blr %r14283; CHECK: br %r14284entry:285 %res = ashr i32 %a, %b286 %cmp = icmp slt i32 %res, 0287 br i1 %cmp, label %exit, label %store288 289store:290 store i32 %b, ptr %dest291 br label %exit292 293exit:294 ret i32 %res295}296 297; ...and SLE.298define i32 @f16(i32 %a, i32 %b, ptr %dest) {299; CHECK-LABEL: f16:300; CHECK: sra %r2, 0(%r3)301; CHECK-NEXT: bler %r14302; CHECK: br %r14303entry:304 %res = ashr i32 %a, %b305 %cmp = icmp sle i32 %res, 0306 br i1 %cmp, label %exit, label %store307 308store:309 store i32 %b, ptr %dest310 br label %exit311 312exit:313 ret i32 %res314}315 316; ...and SGT.317define i32 @f17(i32 %a, i32 %b, ptr %dest) {318; CHECK-LABEL: f17:319; CHECK: sra %r2, 0(%r3)320; CHECK-NEXT: bhr %r14321; CHECK: br %r14322entry:323 %res = ashr i32 %a, %b324 %cmp = icmp sgt i32 %res, 0325 br i1 %cmp, label %exit, label %store326 327store:328 store i32 %b, ptr %dest329 br label %exit330 331exit:332 ret i32 %res333}334 335; ...and SGE.336define i32 @f18(i32 %a, i32 %b, ptr %dest) {337; CHECK-LABEL: f18:338; CHECK: sra %r2, 0(%r3)339; CHECK-NEXT: bher %r14340; CHECK: br %r14341entry:342 %res = ashr i32 %a, %b343 %cmp = icmp sge i32 %res, 0344 br i1 %cmp, label %exit, label %store345 346store:347 store i32 %b, ptr %dest348 br label %exit349 350exit:351 ret i32 %res352}353 354; RISBG provides the same result as a comparison against zero.355; Test the EQ case.356define i64 @f19(i64 %a, i64 %b, ptr %dest) {357; CHECK-LABEL: f19:358; CHECK: risbg %r2, %r3, 0, 190, 0359; CHECK-NEXT: ber %r14360; CHECK: br %r14361entry:362 %res = and i64 %b, -2363 %cmp = icmp eq i64 %res, 0364 br i1 %cmp, label %exit, label %store365 366store:367 store i64 %b, ptr %dest368 br label %exit369 370exit:371 ret i64 %res372}373 374; ...and the SLT case.375define i64 @f20(i64 %a, i64 %b, ptr %dest) {376; CHECK-LABEL: f20:377; CHECK: risbg %r2, %r3, 0, 190, 0378; CHECK-NEXT: blr %r14379; CHECK: br %r14380entry:381 %res = and i64 %b, -2382 %cmp = icmp slt i64 %res, 0383 br i1 %cmp, label %exit, label %store384 385store:386 store i64 %b, ptr %dest387 br label %exit388 389exit:390 ret i64 %res391}392 393; Test a case where the register we're testing is set by a non-CC-clobbering394; instruction.395define i32 @f21(i32 %a, i32 %b, ptr %dest) {396; CHECK-LABEL: f21:397; CHECK: afi %r2, 1000000398; CHECK-NEXT: #APP399; CHECK-NEXT: blah %r2400; CHECK-NEXT: #NO_APP401; CHECK-NEXT: cibe %r2, 0, 0(%r14)402; CHECK: br %r14403entry:404 %add = add i32 %a, 1000000405 %res = call i32 asm "blah $0", "=r,0" (i32 %add)406 %cmp = icmp eq i32 %res, 0407 br i1 %cmp, label %exit, label %store408 409store:410 store i32 %b, ptr %dest411 br label %exit412 413exit:414 ret i32 %res415}416 417; ...and again with a CC-clobbering instruction.418define i32 @f22(i32 %a, i32 %b, ptr %dest) {419; CHECK-LABEL: f22:420; CHECK: afi %r2, 1000000421; CHECK-NEXT: #APP422; CHECK-NEXT: blah %r2423; CHECK-NEXT: #NO_APP424; CHECK-NEXT: cibe %r2, 0, 0(%r14)425; CHECK: br %r14426entry:427 %add = add i32 %a, 1000000428 %res = call i32 asm "blah $0", "=r,0,~{cc}" (i32 %add)429 %cmp = icmp eq i32 %res, 0430 br i1 %cmp, label %exit, label %store431 432store:433 store i32 %b, ptr %dest434 br label %exit435 436exit:437 ret i32 %res438}439 440; Check that stores do not interfere.441define i32 @f23(i32 %a, i32 %b, ptr %dest1, ptr %dest2) {442; CHECK-LABEL: f23:443; CHECK: afi %r2, 1000000444; CHECK-NEXT: st %r2, 0(%r4)445; CHECK-NEXT: blhr %r14446; CHECK: br %r14447entry:448 %res = add nsw i32 %a, 1000000449 store i32 %res, ptr %dest1450 %cmp = icmp ne i32 %res, 0451 br i1 %cmp, label %exit, label %store452 453store:454 store i32 %b, ptr %dest2455 br label %exit456 457exit:458 ret i32 %res459}460 461; Check that calls do interfere.462define void @f24(ptr %ptr) {463; CHECK-LABEL: f24:464; CHECK: afi [[REG:%r[0-9]+]], 1000000465; CHECK-NEXT: brasl %r14, foo@PLT466; CHECK-NEXT: cijlh [[REG]], 0, .L{{.*}}467; CHECK: br %r14468entry:469 %val = load i32, ptr %ptr470 %xor = xor i32 %val, 1471 %add = add i32 %xor, 1000000472 call void @foo()473 %cmp = icmp eq i32 %add, 0474 br i1 %cmp, label %store, label %exit, !prof !1475 476store:477 store i32 %add, ptr %ptr478 br label %exit479 480exit:481 ret void482}483 484; Check that inline asms don't interfere if they don't clobber CC.485define void @f25(i32 %a, ptr %ptr) {486; CHECK-LABEL: f25:487; CHECK: afi %r2, 1000000488; CHECK-NEXT: #APP489; CHECK-NEXT: blah490; CHECK-NEXT: #NO_APP491; CHECK-NEXT: blhr %r14492; CHECK: br %r14493entry:494 %add = add nsw i32 %a, 1000000495 call void asm sideeffect "blah", "r"(i32 %add)496 %cmp = icmp ne i32 %add, 0497 br i1 %cmp, label %exit, label %store498 499store:500 store i32 %add, ptr %ptr501 br label %exit502 503exit:504 ret void505}506 507; ...but do interfere if they do clobber CC.508define void @f26(i32 %a, ptr %ptr) {509; CHECK-LABEL: f26:510; CHECK: afi %r2, 1000000511; CHECK-NEXT: #APP512; CHECK-NEXT: blah513; CHECK-NEXT: #NO_APP514; CHECK-NEXT: ciblh %r2, 0, 0(%r14)515; CHECK: br %r14516entry:517 %add = add i32 %a, 1000000518 call void asm sideeffect "blah", "r,~{cc}"(i32 %add)519 %cmp = icmp ne i32 %add, 0520 br i1 %cmp, label %exit, label %store521 522store:523 store i32 %add, ptr %ptr524 br label %exit525 526exit:527 ret void528}529 530; Test a case where CC is set based on a different register from the531; compare input.532define i32 @f27(i32 %a, i32 %b, ptr %dest1, ptr %dest2) {533; CHECK-LABEL: f27:534; CHECK: afi %r2, 1000000535; CHECK-NEXT: sr %r3, %r2536; CHECK-NEXT: st %r3, 0(%r4)537; CHECK-NEXT: cibe %r2, 0, 0(%r14)538; CHECK: br %r14539entry:540 %add = add nsw i32 %a, 1000000541 %sub = sub i32 %b, %add542 store i32 %sub, ptr %dest1543 %cmp = icmp eq i32 %add, 0544 br i1 %cmp, label %exit, label %store545 546store:547 store i32 %sub, ptr %dest2548 br label %exit549 550exit:551 ret i32 %add552}553 554; Make sure that we don't confuse a base register for a destination.555define void @f28(i64 %a, ptr %dest) {556; CHECK-LABEL: f28:557; CHECK: xi 0(%r2), 15558; CHECK: cgibe %r2, 0, 0(%r14)559; CHECK: br %r14560entry:561 %ptr = inttoptr i64 %a to ptr562 %val = load i8, ptr %ptr563 %xor = xor i8 %val, 15564 store i8 %xor, ptr %ptr565 %cmp = icmp eq i64 %a, 0566 br i1 %cmp, label %exit, label %store567 568store:569 store i64 %a, ptr %dest570 br label %exit571 572exit:573 ret void574}575 576; Test that L gets converted to LT where useful.577define i32 @f29(i64 %base, i64 %index, ptr %dest) {578; CHECK-LABEL: f29:579; CHECK: lt %r2, 0({{%r2,%r3|%r3,%r2}})580; CHECK-NEXT: bler %r14581; CHECK: br %r14582entry:583 %add = add i64 %base, %index584 %ptr = inttoptr i64 %add to ptr585 %res = load i32, ptr %ptr586 %cmp = icmp sle i32 %res, 0587 br i1 %cmp, label %exit, label %store588 589store:590 store i32 %res, ptr %dest591 br label %exit592 593exit:594 ret i32 %res595}596 597; Test that LY gets converted to LT where useful.598define i32 @f30(i64 %base, i64 %index, ptr %dest) {599; CHECK-LABEL: f30:600; CHECK: lt %r2, 100000({{%r2,%r3|%r3,%r2}})601; CHECK-NEXT: bler %r14602; CHECK: br %r14603entry:604 %add1 = add i64 %base, %index605 %add2 = add i64 %add1, 100000606 %ptr = inttoptr i64 %add2 to ptr607 %res = load i32, ptr %ptr608 %cmp = icmp sle i32 %res, 0609 br i1 %cmp, label %exit, label %store610 611store:612 store i32 %res, ptr %dest613 br label %exit614 615exit:616 ret i32 %res617}618 619; Test that LG gets converted to LTG where useful.620define i64 @f31(i64 %base, i64 %index, ptr %dest) {621; CHECK-LABEL: f31:622; CHECK: ltg %r2, 0({{%r2,%r3|%r3,%r2}})623; CHECK-NEXT: bher %r14624; CHECK: br %r14625entry:626 %add = add i64 %base, %index627 %ptr = inttoptr i64 %add to ptr628 %res = load i64, ptr %ptr629 %cmp = icmp sge i64 %res, 0630 br i1 %cmp, label %exit, label %store631 632store:633 store i64 %res, ptr %dest634 br label %exit635 636exit:637 ret i64 %res638}639 640; Test that LGF gets converted to LTGF where useful.641define i64 @f32(i64 %base, i64 %index, ptr %dest) {642; CHECK-LABEL: f32:643; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})644; CHECK-NEXT: bhr %r14645; CHECK: br %r14646entry:647 %add = add i64 %base, %index648 %ptr = inttoptr i64 %add to ptr649 %val = load i32, ptr %ptr650 %res = sext i32 %val to i64651 %cmp = icmp sgt i64 %res, 0652 br i1 %cmp, label %exit, label %store653 654store:655 store i64 %res, ptr %dest656 br label %exit657 658exit:659 ret i64 %res660}661 662; Test that LR gets converted to LTR where useful.663define i32 @f33(i32 %dummy, i32 %val, ptr %dest) {664; CHECK-LABEL: f33:665; CHECK: ltr %r2, %r3666; CHECK-NEXT: #APP667; CHECK-NEXT: blah %r2668; CHECK-NEXT: #NO_APP669; CHECK-NEXT: blr %r14670; CHECK: br %r14671entry:672 call void asm sideeffect "blah $0", "{r2}"(i32 %val)673 %cmp = icmp slt i32 %val, 0674 br i1 %cmp, label %exit, label %store675 676store:677 store i32 %val, ptr %dest678 br label %exit679 680exit:681 ret i32 %val682}683 684; Test that LGR gets converted to LTGR where useful.685define i64 @f34(i64 %dummy, i64 %val, ptr %dest) {686; CHECK-LABEL: f34:687; CHECK: ltgr %r2, %r3688; CHECK-NEXT: #APP689; CHECK-NEXT: blah %r2690; CHECK-NEXT: #NO_APP691; CHECK-NEXT: bhr %r14692; CHECK: br %r14693entry:694 call void asm sideeffect "blah $0", "{r2}"(i64 %val)695 %cmp = icmp sgt i64 %val, 0696 br i1 %cmp, label %exit, label %store697 698store:699 store i64 %val, ptr %dest700 br label %exit701 702exit:703 ret i64 %val704}705 706; Test that LGFR gets converted to LTGFR where useful.707define i64 @f35(i64 %dummy, i32 %val, ptr %dest) {708; CHECK-LABEL: f35:709; CHECK: ltgfr %r2, %r3710; CHECK-NEXT: #APP711; CHECK-NEXT: blah %r2712; CHECK-NEXT: #NO_APP713; CHECK-NEXT: bhr %r14714; CHECK: br %r14715entry:716 %ext = sext i32 %val to i64717 call void asm sideeffect "blah $0", "{r2}"(i64 %ext)718 %cmp = icmp sgt i64 %ext, 0719 br i1 %cmp, label %exit, label %store720 721store:722 store i64 %ext, ptr %dest723 br label %exit724 725exit:726 ret i64 %ext727}728 729; Test a case where it is the source rather than destination of LR that730; we need.731define i32 @f36(i32 %val, i32 %dummy, ptr %dest) {732; CHECK-LABEL: f36:733; CHECK: ltr %r3, %r2734; CHECK-NEXT: #APP735; CHECK-NEXT: blah %r3736; CHECK-NEXT: #NO_APP737; CHECK-NEXT: blr %r14738; CHECK: br %r14739entry:740 call void asm sideeffect "blah $0", "{r3}"(i32 %val)741 %cmp = icmp slt i32 %val, 0742 br i1 %cmp, label %exit, label %store743 744store:745 store i32 %val, ptr %dest746 br label %exit747 748exit:749 ret i32 %val750}751 752; Test a case where it is the source rather than destination of LGR that753; we need.754define i64 @f37(i64 %val, i64 %dummy, ptr %dest) {755; CHECK-LABEL: f37:756; CHECK: ltgr %r3, %r2757; CHECK-NEXT: #APP758; CHECK-NEXT: blah %r3759; CHECK-NEXT: #NO_APP760; CHECK-NEXT: blr %r14761; CHECK: br %r14762entry:763 call void asm sideeffect "blah $0", "{r3}"(i64 %val)764 %cmp = icmp slt i64 %val, 0765 br i1 %cmp, label %exit, label %store766 767store:768 store i64 %val, ptr %dest769 br label %exit770 771exit:772 ret i64 %val773}774 775; Test a case where it is the source rather than destination of LGFR that776; we need.777define i32 @f38(i32 %val, i64 %dummy, ptr %dest) {778; CHECK-LABEL: f38:779; CHECK: ltgfr %r3, %r2780; CHECK-NEXT: #APP781; CHECK-NEXT: blah %r3782; CHECK-NEXT: #NO_APP783; CHECK-NEXT: blr %r14784; CHECK: br %r14785entry:786 %ext = sext i32 %val to i64787 call void asm sideeffect "blah $0", "{r3}"(i64 %ext)788 %cmp = icmp slt i32 %val, 0789 br i1 %cmp, label %exit, label %store790 791store:792 store i32 %val, ptr %dest793 br label %exit794 795exit:796 ret i32 %val797}798 799; Test f35 for in-register extensions.800define i64 @f39(i64 %dummy, i64 %a, ptr %dest) {801; CHECK-LABEL: f39:802; CHECK: ltgfr %r2, %r3803; CHECK-NEXT: #APP804; CHECK-NEXT: blah %r2805; CHECK-NEXT: #NO_APP806; CHECK-NEXT: bhr %r14807; CHECK: br %r14808entry:809 %val = trunc i64 %a to i32810 %ext = sext i32 %val to i64811 call void asm sideeffect "blah $0", "{r2}"(i64 %ext)812 %cmp = icmp sgt i64 %ext, 0813 br i1 %cmp, label %exit, label %store814 815store:816 store i64 %ext, ptr %dest817 br label %exit818 819exit:820 ret i64 %ext821}822 823; ...and again with what InstCombine would produce for f40.824define i64 @f40(i64 %dummy, i64 %a, ptr %dest) {825; CHECK-LABEL: f40:826; CHECK: ltgfr %r2, %r3827; CHECK-NEXT: #APP828; CHECK-NEXT: blah %r2829; CHECK-NEXT: #NO_APP830; CHECK-NEXT: bhr %r14831; CHECK: br %r14832entry:833 %shl = shl i64 %a, 32834 %ext = ashr i64 %shl, 32835 call void asm sideeffect "blah $0", "{r2}"(i64 %ext)836 %cmp = icmp sgt i64 %shl, 0837 br i1 %cmp, label %exit, label %store838 839store:840 store i64 %ext, ptr %dest841 br label %exit842 843exit:844 ret i64 %ext845}846 847; Try a form of f7 in which the subtraction operands are compared directly.848define i32 @f41(i32 %a, i32 %b, ptr %dest) {849; CHECK-LABEL: f41:850; CHECK: s %r2, 0(%r4)851; CHECK-NEXT: bner %r14852; CHECK: br %r14853entry:854 %cur = load i32, ptr %dest855 %res = sub i32 %a, %cur856 %cmp = icmp ne i32 %a, %cur857 br i1 %cmp, label %exit, label %store858 859store:860 store i32 %b, ptr %dest861 br label %exit862 863exit:864 ret i32 %res865}866 867; A version of f32 that tests the unextended value.868define i64 @f42(i64 %base, i64 %index, ptr %dest) {869; CHECK-LABEL: f42:870; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})871; CHECK-NEXT: bhr %r14872; CHECK: br %r14873entry:874 %add = add i64 %base, %index875 %ptr = inttoptr i64 %add to ptr876 %val = load i32, ptr %ptr877 %res = sext i32 %val to i64878 %cmp = icmp sgt i32 %val, 0879 br i1 %cmp, label %exit, label %store880 881store:882 store i64 %res, ptr %dest883 br label %exit884 885exit:886 ret i64 %res887}888 889!1 = !{!"branch_weights", i32 2, i32 1}890