541 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64 | FileCheck %s3 4;5; trunc(nabs(sub(sext(a),sext(b)))) -> nabds(a,b)6;7 8define i8 @abd_ext_i8(i8 %a, i8 %b) nounwind {9; CHECK-LABEL: abd_ext_i8:10; CHECK: // %bb.0:11; CHECK-NEXT: sxtb w8, w012; CHECK-NEXT: subs w8, w8, w1, sxtb13; CHECK-NEXT: cneg w0, w8, pl14; CHECK-NEXT: ret15 %aext = sext i8 %a to i6416 %bext = sext i8 %b to i6417 %sub = sub i64 %aext, %bext18 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)19 %nabs = sub i64 0, %abs20 %trunc = trunc i64 %nabs to i821 ret i8 %trunc22}23 24define i8 @abd_ext_i8_i16(i8 %a, i16 %b) nounwind {25; CHECK-LABEL: abd_ext_i8_i16:26; CHECK: // %bb.0:27; CHECK-NEXT: sxtb w8, w028; CHECK-NEXT: subs w8, w8, w1, sxth29; CHECK-NEXT: cneg w0, w8, pl30; CHECK-NEXT: ret31 %aext = sext i8 %a to i6432 %bext = sext i16 %b to i6433 %sub = sub i64 %aext, %bext34 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)35 %nabs = sub i64 0, %abs36 %trunc = trunc i64 %nabs to i837 ret i8 %trunc38}39 40define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {41; CHECK-LABEL: abd_ext_i8_undef:42; CHECK: // %bb.0:43; CHECK-NEXT: sxtb w8, w044; CHECK-NEXT: subs w8, w8, w1, sxtb45; CHECK-NEXT: cneg w0, w8, pl46; CHECK-NEXT: ret47 %aext = sext i8 %a to i6448 %bext = sext i8 %b to i6449 %sub = sub i64 %aext, %bext50 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)51 %nabs = sub i64 0, %abs52 %trunc = trunc i64 %nabs to i853 ret i8 %trunc54}55 56define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {57; CHECK-LABEL: abd_ext_i16:58; CHECK: // %bb.0:59; CHECK-NEXT: sxth w8, w060; CHECK-NEXT: subs w8, w8, w1, sxth61; CHECK-NEXT: cneg w0, w8, pl62; CHECK-NEXT: ret63 %aext = sext i16 %a to i6464 %bext = sext i16 %b to i6465 %sub = sub i64 %aext, %bext66 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)67 %nabs = sub i64 0, %abs68 %trunc = trunc i64 %nabs to i1669 ret i16 %trunc70}71 72define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind {73; CHECK-LABEL: abd_ext_i16_i32:74; CHECK: // %bb.0:75; CHECK-NEXT: sxth w8, w076; CHECK-NEXT: subs w8, w8, w177; CHECK-NEXT: cneg w0, w8, gt78; CHECK-NEXT: ret79 %aext = sext i16 %a to i6480 %bext = sext i32 %b to i6481 %sub = sub i64 %aext, %bext82 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)83 %nabs = sub i64 0, %abs84 %trunc = trunc i64 %nabs to i1685 ret i16 %trunc86}87 88define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {89; CHECK-LABEL: abd_ext_i16_undef:90; CHECK: // %bb.0:91; CHECK-NEXT: sxth w8, w092; CHECK-NEXT: subs w8, w8, w1, sxth93; CHECK-NEXT: cneg w0, w8, pl94; CHECK-NEXT: ret95 %aext = sext i16 %a to i6496 %bext = sext i16 %b to i6497 %sub = sub i64 %aext, %bext98 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)99 %nabs = sub i64 0, %abs100 %trunc = trunc i64 %nabs to i16101 ret i16 %trunc102}103 104define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {105; CHECK-LABEL: abd_ext_i32:106; CHECK: // %bb.0:107; CHECK-NEXT: subs w8, w0, w1108; CHECK-NEXT: cneg w0, w8, gt109; CHECK-NEXT: ret110 %aext = sext i32 %a to i64111 %bext = sext i32 %b to i64112 %sub = sub i64 %aext, %bext113 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)114 %nabs = sub i64 0, %abs115 %trunc = trunc i64 %nabs to i32116 ret i32 %trunc117}118 119define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind {120; CHECK-LABEL: abd_ext_i32_i16:121; CHECK: // %bb.0:122; CHECK-NEXT: subs w8, w0, w1, sxth123; CHECK-NEXT: cneg w0, w8, gt124; CHECK-NEXT: ret125 %aext = sext i32 %a to i64126 %bext = sext i16 %b to i64127 %sub = sub i64 %aext, %bext128 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)129 %nabs = sub i64 0, %abs130 %trunc = trunc i64 %nabs to i32131 ret i32 %trunc132}133 134define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {135; CHECK-LABEL: abd_ext_i32_undef:136; CHECK: // %bb.0:137; CHECK-NEXT: subs w8, w0, w1138; CHECK-NEXT: cneg w0, w8, gt139; CHECK-NEXT: ret140 %aext = sext i32 %a to i64141 %bext = sext i32 %b to i64142 %sub = sub i64 %aext, %bext143 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)144 %nabs = sub i64 0, %abs145 %trunc = trunc i64 %nabs to i32146 ret i32 %trunc147}148 149define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {150; CHECK-LABEL: abd_ext_i64:151; CHECK: // %bb.0:152; CHECK-NEXT: subs x8, x0, x1153; CHECK-NEXT: cneg x0, x8, gt154; CHECK-NEXT: ret155 %aext = sext i64 %a to i128156 %bext = sext i64 %b to i128157 %sub = sub i128 %aext, %bext158 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)159 %nabs = sub i128 0, %abs160 %trunc = trunc i128 %nabs to i64161 ret i64 %trunc162}163 164define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {165; CHECK-LABEL: abd_ext_i64_undef:166; CHECK: // %bb.0:167; CHECK-NEXT: subs x8, x0, x1168; CHECK-NEXT: cneg x0, x8, gt169; CHECK-NEXT: ret170 %aext = sext i64 %a to i128171 %bext = sext i64 %b to i128172 %sub = sub i128 %aext, %bext173 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)174 %nabs = sub i128 0, %abs175 %trunc = trunc i128 %nabs to i64176 ret i64 %trunc177}178 179define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {180; CHECK-LABEL: abd_ext_i128:181; CHECK: // %bb.0:182; CHECK-NEXT: subs x8, x0, x2183; CHECK-NEXT: sbc x9, x1, x3184; CHECK-NEXT: subs x10, x2, x0185; CHECK-NEXT: sbcs x11, x3, x1186; CHECK-NEXT: csel x8, x8, x10, lt187; CHECK-NEXT: csel x9, x9, x11, lt188; CHECK-NEXT: negs x0, x8189; CHECK-NEXT: ngc x1, x9190; CHECK-NEXT: ret191 %aext = sext i128 %a to i256192 %bext = sext i128 %b to i256193 %sub = sub i256 %aext, %bext194 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)195 %nabs = sub i256 0, %abs196 %trunc = trunc i256 %nabs to i128197 ret i128 %trunc198}199 200define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {201; CHECK-LABEL: abd_ext_i128_undef:202; CHECK: // %bb.0:203; CHECK-NEXT: subs x8, x0, x2204; CHECK-NEXT: sbc x9, x1, x3205; CHECK-NEXT: subs x10, x2, x0206; CHECK-NEXT: sbcs x11, x3, x1207; CHECK-NEXT: csel x8, x8, x10, lt208; CHECK-NEXT: csel x9, x9, x11, lt209; CHECK-NEXT: negs x0, x8210; CHECK-NEXT: ngc x1, x9211; CHECK-NEXT: ret212 %aext = sext i128 %a to i256213 %bext = sext i128 %b to i256214 %sub = sub i256 %aext, %bext215 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)216 %nabs = sub i256 0, %abs217 %trunc = trunc i256 %nabs to i128218 ret i128 %trunc219}220 221;222; sub(smin(a,b),smax(a,b)) -> nabds(a,b)223;224 225define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {226; CHECK-LABEL: abd_minmax_i8:227; CHECK: // %bb.0:228; CHECK-NEXT: sxtb w8, w1229; CHECK-NEXT: sxtb w9, w0230; CHECK-NEXT: cmp w9, w8231; CHECK-NEXT: csel w10, w9, w8, lt232; CHECK-NEXT: csel w8, w9, w8, gt233; CHECK-NEXT: sub w0, w10, w8234; CHECK-NEXT: ret235 %min = call i8 @llvm.smin.i8(i8 %a, i8 %b)236 %max = call i8 @llvm.smax.i8(i8 %a, i8 %b)237 %sub = sub i8 %min, %max238 ret i8 %sub239}240 241define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {242; CHECK-LABEL: abd_minmax_i16:243; CHECK: // %bb.0:244; CHECK-NEXT: sxth w8, w1245; CHECK-NEXT: sxth w9, w0246; CHECK-NEXT: cmp w9, w8247; CHECK-NEXT: csel w10, w9, w8, lt248; CHECK-NEXT: csel w8, w9, w8, gt249; CHECK-NEXT: sub w0, w10, w8250; CHECK-NEXT: ret251 %min = call i16 @llvm.smin.i16(i16 %a, i16 %b)252 %max = call i16 @llvm.smax.i16(i16 %a, i16 %b)253 %sub = sub i16 %min, %max254 ret i16 %sub255}256 257define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {258; CHECK-LABEL: abd_minmax_i32:259; CHECK: // %bb.0:260; CHECK-NEXT: cmp w0, w1261; CHECK-NEXT: csel w8, w0, w1, lt262; CHECK-NEXT: csel w9, w0, w1, gt263; CHECK-NEXT: sub w0, w8, w9264; CHECK-NEXT: ret265 %min = call i32 @llvm.smin.i32(i32 %a, i32 %b)266 %max = call i32 @llvm.smax.i32(i32 %a, i32 %b)267 %sub = sub i32 %min, %max268 ret i32 %sub269}270 271define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {272; CHECK-LABEL: abd_minmax_i64:273; CHECK: // %bb.0:274; CHECK-NEXT: cmp x0, x1275; CHECK-NEXT: csel x8, x0, x1, lt276; CHECK-NEXT: csel x9, x0, x1, gt277; CHECK-NEXT: sub x0, x8, x9278; CHECK-NEXT: ret279 %min = call i64 @llvm.smin.i64(i64 %a, i64 %b)280 %max = call i64 @llvm.smax.i64(i64 %a, i64 %b)281 %sub = sub i64 %min, %max282 ret i64 %sub283}284 285define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {286; CHECK-LABEL: abd_minmax_i128:287; CHECK: // %bb.0:288; CHECK-NEXT: cmp x0, x2289; CHECK-NEXT: sbcs xzr, x1, x3290; CHECK-NEXT: csel x8, x1, x3, lt291; CHECK-NEXT: csel x9, x0, x2, lt292; CHECK-NEXT: cmp x2, x0293; CHECK-NEXT: sbcs xzr, x3, x1294; CHECK-NEXT: csel x10, x0, x2, lt295; CHECK-NEXT: csel x11, x1, x3, lt296; CHECK-NEXT: subs x0, x9, x10297; CHECK-NEXT: sbc x1, x8, x11298; CHECK-NEXT: ret299 %min = call i128 @llvm.smin.i128(i128 %a, i128 %b)300 %max = call i128 @llvm.smax.i128(i128 %a, i128 %b)301 %sub = sub i128 %min, %max302 ret i128 %sub303}304 305;306; select(icmp(a,b),sub(a,b),sub(b,a)) -> nabds(a,b)307;308 309define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {310; CHECK-LABEL: abd_cmp_i8:311; CHECK: // %bb.0:312; CHECK-NEXT: sxtb w8, w0313; CHECK-NEXT: sub w9, w0, w1314; CHECK-NEXT: sub w10, w1, w0315; CHECK-NEXT: cmp w8, w1, sxtb316; CHECK-NEXT: csel w0, w9, w10, le317; CHECK-NEXT: ret318 %cmp = icmp sle i8 %a, %b319 %ab = sub i8 %a, %b320 %ba = sub i8 %b, %a321 %sel = select i1 %cmp, i8 %ab, i8 %ba322 ret i8 %sel323}324 325define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {326; CHECK-LABEL: abd_cmp_i16:327; CHECK: // %bb.0:328; CHECK-NEXT: sxth w8, w0329; CHECK-NEXT: sub w9, w0, w1330; CHECK-NEXT: sub w10, w1, w0331; CHECK-NEXT: cmp w8, w1, sxth332; CHECK-NEXT: csel w0, w9, w10, lt333; CHECK-NEXT: ret334 %cmp = icmp slt i16 %a, %b335 %ab = sub i16 %a, %b336 %ba = sub i16 %b, %a337 %sel = select i1 %cmp, i16 %ab, i16 %ba338 ret i16 %sel339}340 341define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {342; CHECK-LABEL: abd_cmp_i32:343; CHECK: // %bb.0:344; CHECK-NEXT: subs w8, w0, w1345; CHECK-NEXT: cneg w0, w8, ge346; CHECK-NEXT: ret347 %cmp = icmp sge i32 %a, %b348 %ab = sub i32 %a, %b349 %ba = sub i32 %b, %a350 %sel = select i1 %cmp, i32 %ba, i32 %ab351 ret i32 %sel352}353 354define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {355; CHECK-LABEL: abd_cmp_i64:356; CHECK: // %bb.0:357; CHECK-NEXT: subs x8, x0, x1358; CHECK-NEXT: cneg x0, x8, ge359; CHECK-NEXT: ret360 %cmp = icmp slt i64 %a, %b361 %ab = sub i64 %a, %b362 %ba = sub i64 %b, %a363 %sel = select i1 %cmp, i64 %ab, i64 %ba364 ret i64 %sel365}366 367define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {368; CHECK-LABEL: abd_cmp_i128:369; CHECK: // %bb.0:370; CHECK-NEXT: subs x8, x2, x0371; CHECK-NEXT: sbc x9, x3, x1372; CHECK-NEXT: subs x10, x0, x2373; CHECK-NEXT: sbcs x11, x1, x3374; CHECK-NEXT: csel x0, x10, x8, lt375; CHECK-NEXT: csel x1, x11, x9, lt376; CHECK-NEXT: ret377 %cmp = icmp slt i128 %a, %b378 %ab = sub i128 %a, %b379 %ba = sub i128 %b, %a380 %sel = select i1 %cmp, i128 %ab, i128 %ba381 ret i128 %sel382}383 384;385; nabs(sub_nsw(x, y)) -> nabds(a,b)386;387 388define i8 @abd_subnsw_i8(i8 %a, i8 %b) nounwind {389; CHECK-LABEL: abd_subnsw_i8:390; CHECK: // %bb.0:391; CHECK-NEXT: sub w8, w0, w1392; CHECK-NEXT: sbfx w9, w8, #7, #1393; CHECK-NEXT: eor w8, w8, w9394; CHECK-NEXT: sub w0, w9, w8395; CHECK-NEXT: ret396 %sub = sub nsw i8 %a, %b397 %abs = call i8 @llvm.abs.i8(i8 %sub, i1 false)398 %nabs = sub i8 0, %abs399 ret i8 %nabs400}401 402define i8 @abd_subnsw_i8_undef(i8 %a, i8 %b) nounwind {403; CHECK-LABEL: abd_subnsw_i8_undef:404; CHECK: // %bb.0:405; CHECK-NEXT: sub w8, w0, w1406; CHECK-NEXT: sbfx w9, w8, #7, #1407; CHECK-NEXT: eor w8, w8, w9408; CHECK-NEXT: sub w0, w9, w8409; CHECK-NEXT: ret410 %sub = sub nsw i8 %a, %b411 %abs = call i8 @llvm.abs.i8(i8 %sub, i1 true)412 %nabs = sub i8 0, %abs413 ret i8 %nabs414}415 416define i16 @abd_subnsw_i16(i16 %a, i16 %b) nounwind {417; CHECK-LABEL: abd_subnsw_i16:418; CHECK: // %bb.0:419; CHECK-NEXT: sub w8, w0, w1420; CHECK-NEXT: sbfx w9, w8, #15, #1421; CHECK-NEXT: eor w8, w8, w9422; CHECK-NEXT: sub w0, w9, w8423; CHECK-NEXT: ret424 %sub = sub nsw i16 %a, %b425 %abs = call i16 @llvm.abs.i16(i16 %sub, i1 false)426 %nabs = sub i16 0, %abs427 ret i16 %nabs428}429 430define i16 @abd_subnsw_i16_undef(i16 %a, i16 %b) nounwind {431; CHECK-LABEL: abd_subnsw_i16_undef:432; CHECK: // %bb.0:433; CHECK-NEXT: sub w8, w0, w1434; CHECK-NEXT: sbfx w9, w8, #15, #1435; CHECK-NEXT: eor w8, w8, w9436; CHECK-NEXT: sub w0, w9, w8437; CHECK-NEXT: ret438 %sub = sub nsw i16 %a, %b439 %abs = call i16 @llvm.abs.i16(i16 %sub, i1 true)440 %nabs = sub i16 0, %abs441 ret i16 %nabs442}443 444define i32 @abd_subnsw_i32(i32 %a, i32 %b) nounwind {445; CHECK-LABEL: abd_subnsw_i32:446; CHECK: // %bb.0:447; CHECK-NEXT: subs w8, w0, w1448; CHECK-NEXT: cneg w0, w8, pl449; CHECK-NEXT: ret450 %sub = sub nsw i32 %a, %b451 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)452 %nabs = sub i32 0, %abs453 ret i32 %nabs454}455 456define i32 @abd_subnsw_i32_undef(i32 %a, i32 %b) nounwind {457; CHECK-LABEL: abd_subnsw_i32_undef:458; CHECK: // %bb.0:459; CHECK-NEXT: subs w8, w0, w1460; CHECK-NEXT: cneg w0, w8, pl461; CHECK-NEXT: ret462 %sub = sub nsw i32 %a, %b463 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 true)464 %nabs = sub i32 0, %abs465 ret i32 %nabs466}467 468define i64 @abd_subnsw_i64(i64 %a, i64 %b) nounwind {469; CHECK-LABEL: abd_subnsw_i64:470; CHECK: // %bb.0:471; CHECK-NEXT: subs x8, x0, x1472; CHECK-NEXT: cneg x0, x8, pl473; CHECK-NEXT: ret474 %sub = sub nsw i64 %a, %b475 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)476 %nabs = sub i64 0, %abs477 ret i64 %nabs478}479 480define i64 @abd_subnsw_i64_undef(i64 %a, i64 %b) nounwind {481; CHECK-LABEL: abd_subnsw_i64_undef:482; CHECK: // %bb.0:483; CHECK-NEXT: subs x8, x0, x1484; CHECK-NEXT: cneg x0, x8, pl485; CHECK-NEXT: ret486 %sub = sub nsw i64 %a, %b487 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)488 %nabs = sub i64 0, %abs489 ret i64 %nabs490}491 492define i128 @abd_subnsw_i128(i128 %a, i128 %b) nounwind {493; CHECK-LABEL: abd_subnsw_i128:494; CHECK: // %bb.0:495; CHECK-NEXT: subs x8, x0, x2496; CHECK-NEXT: sbc x9, x1, x3497; CHECK-NEXT: asr x10, x9, #63498; CHECK-NEXT: eor x8, x8, x10499; CHECK-NEXT: eor x9, x9, x10500; CHECK-NEXT: subs x0, x10, x8501; CHECK-NEXT: sbc x1, x10, x9502; CHECK-NEXT: ret503 %sub = sub nsw i128 %a, %b504 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)505 %nabs = sub i128 0, %abs506 ret i128 %nabs507}508 509define i128 @abd_subnsw_i128_undef(i128 %a, i128 %b) nounwind {510; CHECK-LABEL: abd_subnsw_i128_undef:511; CHECK: // %bb.0:512; CHECK-NEXT: subs x8, x0, x2513; CHECK-NEXT: sbc x9, x1, x3514; CHECK-NEXT: asr x10, x9, #63515; CHECK-NEXT: eor x8, x8, x10516; CHECK-NEXT: eor x9, x9, x10517; CHECK-NEXT: subs x0, x10, x8518; CHECK-NEXT: sbc x1, x10, x9519; CHECK-NEXT: ret520 %sub = sub nsw i128 %a, %b521 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)522 %nabs = sub i128 0, %abs523 ret i128 %nabs524}525 526declare i8 @llvm.abs.i8(i8, i1)527declare i16 @llvm.abs.i16(i16, i1)528declare i32 @llvm.abs.i32(i32, i1)529declare i64 @llvm.abs.i64(i64, i1)530declare i128 @llvm.abs.i128(i128, i1)531 532declare i8 @llvm.smax.i8(i8, i8)533declare i16 @llvm.smax.i16(i16, i16)534declare i32 @llvm.smax.i32(i32, i32)535declare i64 @llvm.smax.i64(i64, i64)536 537declare i8 @llvm.smin.i8(i8, i8)538declare i16 @llvm.smin.i16(i16, i16)539declare i32 @llvm.smin.i32(i32, i32)540declare i64 @llvm.smin.i64(i64, i64)541