399 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(zext(a),zext(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: and w8, w0, #0xff12; CHECK-NEXT: subs w8, w8, w1, uxtb13; CHECK-NEXT: cneg w0, w8, pl14; CHECK-NEXT: ret15 %aext = zext i8 %a to i6416 %bext = zext 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: and w8, w0, #0xff28; CHECK-NEXT: subs w8, w8, w1, uxth29; CHECK-NEXT: cneg w0, w8, pl30; CHECK-NEXT: ret31 %aext = zext i8 %a to i6432 %bext = zext 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: and w8, w0, #0xff44; CHECK-NEXT: subs w8, w8, w1, uxtb45; CHECK-NEXT: cneg w0, w8, pl46; CHECK-NEXT: ret47 %aext = zext i8 %a to i6448 %bext = zext 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: and w8, w0, #0xffff60; CHECK-NEXT: subs w8, w8, w1, uxth61; CHECK-NEXT: cneg w0, w8, pl62; CHECK-NEXT: ret63 %aext = zext i16 %a to i6464 %bext = zext 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: and w8, w0, #0xffff76; CHECK-NEXT: subs w8, w8, w177; CHECK-NEXT: cneg w0, w8, hi78; CHECK-NEXT: ret79 %aext = zext i16 %a to i6480 %bext = zext 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: and w8, w0, #0xffff92; CHECK-NEXT: subs w8, w8, w1, uxth93; CHECK-NEXT: cneg w0, w8, pl94; CHECK-NEXT: ret95 %aext = zext i16 %a to i6496 %bext = zext 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, hi109; CHECK-NEXT: ret110 %aext = zext i32 %a to i64111 %bext = zext 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, uxth123; CHECK-NEXT: cneg w0, w8, hi124; CHECK-NEXT: ret125 %aext = zext i32 %a to i64126 %bext = zext 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, hi139; CHECK-NEXT: ret140 %aext = zext i32 %a to i64141 %bext = zext 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, hi154; CHECK-NEXT: ret155 %aext = zext i64 %a to i128156 %bext = zext 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, hi169; CHECK-NEXT: ret170 %aext = zext i64 %a to i128171 %bext = zext 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, lo187; CHECK-NEXT: csel x9, x9, x11, lo188; CHECK-NEXT: negs x0, x8189; CHECK-NEXT: ngc x1, x9190; CHECK-NEXT: ret191 %aext = zext i128 %a to i256192 %bext = zext 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, lo208; CHECK-NEXT: csel x9, x9, x11, lo209; CHECK-NEXT: negs x0, x8210; CHECK-NEXT: ngc x1, x9211; CHECK-NEXT: ret212 %aext = zext i128 %a to i256213 %bext = zext 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(umin(a,b),umax(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: and w8, w1, #0xff229; CHECK-NEXT: and w9, w0, #0xff230; CHECK-NEXT: cmp w9, w8231; CHECK-NEXT: csel w10, w9, w8, lo232; CHECK-NEXT: csel w8, w9, w8, hi233; CHECK-NEXT: sub w0, w10, w8234; CHECK-NEXT: ret235 %min = call i8 @llvm.umin.i8(i8 %a, i8 %b)236 %max = call i8 @llvm.umax.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: and w8, w1, #0xffff245; CHECK-NEXT: and w9, w0, #0xffff246; CHECK-NEXT: cmp w9, w8247; CHECK-NEXT: csel w10, w9, w8, lo248; CHECK-NEXT: csel w8, w9, w8, hi249; CHECK-NEXT: sub w0, w10, w8250; CHECK-NEXT: ret251 %min = call i16 @llvm.umin.i16(i16 %a, i16 %b)252 %max = call i16 @llvm.umax.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, lo262; CHECK-NEXT: csel w9, w0, w1, hi263; CHECK-NEXT: sub w0, w8, w9264; CHECK-NEXT: ret265 %min = call i32 @llvm.umin.i32(i32 %a, i32 %b)266 %max = call i32 @llvm.umax.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, lo276; CHECK-NEXT: csel x9, x0, x1, hi277; CHECK-NEXT: sub x0, x8, x9278; CHECK-NEXT: ret279 %min = call i64 @llvm.umin.i64(i64 %a, i64 %b)280 %max = call i64 @llvm.umax.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, lo291; CHECK-NEXT: csel x9, x0, x2, lo292; CHECK-NEXT: cmp x2, x0293; CHECK-NEXT: sbcs xzr, x3, x1294; CHECK-NEXT: csel x10, x0, x2, lo295; CHECK-NEXT: csel x11, x1, x3, lo296; CHECK-NEXT: subs x0, x9, x10297; CHECK-NEXT: sbc x1, x8, x11298; CHECK-NEXT: ret299 %min = call i128 @llvm.umin.i128(i128 %a, i128 %b)300 %max = call i128 @llvm.umax.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: and w8, w0, #0xff313; CHECK-NEXT: sub w9, w0, w1314; CHECK-NEXT: sub w10, w1, w0315; CHECK-NEXT: cmp w8, w1, uxtb316; CHECK-NEXT: csel w0, w9, w10, ls317; CHECK-NEXT: ret318 %cmp = icmp ule 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: and w8, w0, #0xffff329; CHECK-NEXT: sub w9, w0, w1330; CHECK-NEXT: sub w10, w1, w0331; CHECK-NEXT: cmp w8, w1, uxth332; CHECK-NEXT: csel w0, w9, w10, lo333; CHECK-NEXT: ret334 %cmp = icmp ult 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, hs346; CHECK-NEXT: ret347 %cmp = icmp uge 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, hs359; CHECK-NEXT: ret360 %cmp = icmp ult 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, lo375; CHECK-NEXT: csel x1, x11, x9, lo376; CHECK-NEXT: ret377 %cmp = icmp ult 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 384declare i8 @llvm.abs.i8(i8, i1)385declare i16 @llvm.abs.i16(i16, i1)386declare i32 @llvm.abs.i32(i32, i1)387declare i64 @llvm.abs.i64(i64, i1)388declare i128 @llvm.abs.i128(i128, i1)389 390declare i8 @llvm.umax.i8(i8, i8)391declare i16 @llvm.umax.i16(i16, i16)392declare i32 @llvm.umax.i32(i32, i32)393declare i64 @llvm.umax.i64(i64, i64)394 395declare i8 @llvm.umin.i8(i8, i8)396declare i16 @llvm.umin.i16(i16, i16)397declare i32 @llvm.umin.i32(i32, i32)398declare i64 @llvm.umin.i64(i64, i64)399