460 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(abs(sub(zext(a),zext(b)))) -> abdu(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, mi14; 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 %trunc = trunc i64 %abs to i820 ret i8 %trunc21}22 23define i8 @abd_ext_i8_i16(i8 %a, i16 %b) nounwind {24; CHECK-LABEL: abd_ext_i8_i16:25; CHECK: // %bb.0:26; CHECK-NEXT: and w8, w0, #0xff27; CHECK-NEXT: subs w8, w8, w1, uxth28; CHECK-NEXT: cneg w0, w8, mi29; CHECK-NEXT: ret30 %aext = zext i8 %a to i6431 %bext = zext i16 %b to i6432 %sub = sub i64 %aext, %bext33 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)34 %trunc = trunc i64 %abs to i835 ret i8 %trunc36}37 38define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {39; CHECK-LABEL: abd_ext_i8_undef:40; CHECK: // %bb.0:41; CHECK-NEXT: and w8, w0, #0xff42; CHECK-NEXT: subs w8, w8, w1, uxtb43; CHECK-NEXT: cneg w0, w8, mi44; CHECK-NEXT: ret45 %aext = zext i8 %a to i6446 %bext = zext i8 %b to i6447 %sub = sub i64 %aext, %bext48 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)49 %trunc = trunc i64 %abs to i850 ret i8 %trunc51}52 53define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {54; CHECK-LABEL: abd_ext_i16:55; CHECK: // %bb.0:56; CHECK-NEXT: and w8, w0, #0xffff57; CHECK-NEXT: subs w8, w8, w1, uxth58; CHECK-NEXT: cneg w0, w8, mi59; CHECK-NEXT: ret60 %aext = zext i16 %a to i6461 %bext = zext i16 %b to i6462 %sub = sub i64 %aext, %bext63 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)64 %trunc = trunc i64 %abs to i1665 ret i16 %trunc66}67 68define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind {69; CHECK-LABEL: abd_ext_i16_i32:70; CHECK: // %bb.0:71; CHECK-NEXT: and w8, w0, #0xffff72; CHECK-NEXT: subs w8, w8, w173; CHECK-NEXT: cneg w0, w8, ls74; CHECK-NEXT: ret75 %aext = zext i16 %a to i6476 %bext = zext i32 %b to i6477 %sub = sub i64 %aext, %bext78 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)79 %trunc = trunc i64 %abs to i1680 ret i16 %trunc81}82 83define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {84; CHECK-LABEL: abd_ext_i16_undef:85; CHECK: // %bb.0:86; CHECK-NEXT: and w8, w0, #0xffff87; CHECK-NEXT: subs w8, w8, w1, uxth88; CHECK-NEXT: cneg w0, w8, mi89; CHECK-NEXT: ret90 %aext = zext i16 %a to i6491 %bext = zext i16 %b to i6492 %sub = sub i64 %aext, %bext93 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)94 %trunc = trunc i64 %abs to i1695 ret i16 %trunc96}97 98define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {99; CHECK-LABEL: abd_ext_i32:100; CHECK: // %bb.0:101; CHECK-NEXT: subs w8, w0, w1102; CHECK-NEXT: cneg w0, w8, ls103; CHECK-NEXT: ret104 %aext = zext i32 %a to i64105 %bext = zext i32 %b to i64106 %sub = sub i64 %aext, %bext107 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)108 %trunc = trunc i64 %abs to i32109 ret i32 %trunc110}111 112define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind {113; CHECK-LABEL: abd_ext_i32_i16:114; CHECK: // %bb.0:115; CHECK-NEXT: subs w8, w0, w1, uxth116; CHECK-NEXT: cneg w0, w8, ls117; CHECK-NEXT: ret118 %aext = zext i32 %a to i64119 %bext = zext i16 %b to i64120 %sub = sub i64 %aext, %bext121 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)122 %trunc = trunc i64 %abs to i32123 ret i32 %trunc124}125 126define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {127; CHECK-LABEL: abd_ext_i32_undef:128; CHECK: // %bb.0:129; CHECK-NEXT: subs w8, w0, w1130; CHECK-NEXT: cneg w0, w8, ls131; CHECK-NEXT: ret132 %aext = zext i32 %a to i64133 %bext = zext i32 %b to i64134 %sub = sub i64 %aext, %bext135 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)136 %trunc = trunc i64 %abs to i32137 ret i32 %trunc138}139 140define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {141; CHECK-LABEL: abd_ext_i64:142; CHECK: // %bb.0:143; CHECK-NEXT: subs x8, x0, x1144; CHECK-NEXT: cneg x0, x8, ls145; CHECK-NEXT: ret146 %aext = zext i64 %a to i128147 %bext = zext i64 %b to i128148 %sub = sub i128 %aext, %bext149 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)150 %trunc = trunc i128 %abs to i64151 ret i64 %trunc152}153 154define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {155; CHECK-LABEL: abd_ext_i64_undef:156; CHECK: // %bb.0:157; CHECK-NEXT: subs x8, x0, x1158; CHECK-NEXT: cneg x0, x8, ls159; CHECK-NEXT: ret160 %aext = zext i64 %a to i128161 %bext = zext i64 %b to i128162 %sub = sub i128 %aext, %bext163 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)164 %trunc = trunc i128 %abs to i64165 ret i64 %trunc166}167 168define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {169; CHECK-LABEL: abd_ext_i128:170; CHECK: // %bb.0:171; CHECK-NEXT: subs x8, x0, x2172; CHECK-NEXT: sbc x9, x1, x3173; CHECK-NEXT: subs x10, x2, x0174; CHECK-NEXT: sbcs x11, x3, x1175; CHECK-NEXT: csel x0, x8, x10, lo176; CHECK-NEXT: csel x1, x9, x11, lo177; CHECK-NEXT: ret178 %aext = zext i128 %a to i256179 %bext = zext i128 %b to i256180 %sub = sub i256 %aext, %bext181 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)182 %trunc = trunc i256 %abs to i128183 ret i128 %trunc184}185 186define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {187; CHECK-LABEL: abd_ext_i128_undef:188; CHECK: // %bb.0:189; CHECK-NEXT: subs x8, x0, x2190; CHECK-NEXT: sbc x9, x1, x3191; CHECK-NEXT: subs x10, x2, x0192; CHECK-NEXT: sbcs x11, x3, x1193; CHECK-NEXT: csel x0, x8, x10, lo194; CHECK-NEXT: csel x1, x9, x11, lo195; CHECK-NEXT: ret196 %aext = zext i128 %a to i256197 %bext = zext i128 %b to i256198 %sub = sub i256 %aext, %bext199 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)200 %trunc = trunc i256 %abs to i128201 ret i128 %trunc202}203 204;205; sub(umax(a,b),umin(a,b)) -> abdu(a,b)206;207 208define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {209; CHECK-LABEL: abd_minmax_i8:210; CHECK: // %bb.0:211; CHECK-NEXT: and w8, w0, #0xff212; CHECK-NEXT: subs w8, w8, w1, uxtb213; CHECK-NEXT: cneg w0, w8, mi214; CHECK-NEXT: ret215 %min = call i8 @llvm.umin.i8(i8 %a, i8 %b)216 %max = call i8 @llvm.umax.i8(i8 %a, i8 %b)217 %sub = sub i8 %max, %min218 ret i8 %sub219}220 221define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {222; CHECK-LABEL: abd_minmax_i16:223; CHECK: // %bb.0:224; CHECK-NEXT: and w8, w0, #0xffff225; CHECK-NEXT: subs w8, w8, w1, uxth226; CHECK-NEXT: cneg w0, w8, mi227; CHECK-NEXT: ret228 %min = call i16 @llvm.umin.i16(i16 %a, i16 %b)229 %max = call i16 @llvm.umax.i16(i16 %a, i16 %b)230 %sub = sub i16 %max, %min231 ret i16 %sub232}233 234define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {235; CHECK-LABEL: abd_minmax_i32:236; CHECK: // %bb.0:237; CHECK-NEXT: subs w8, w0, w1238; CHECK-NEXT: cneg w0, w8, ls239; CHECK-NEXT: ret240 %min = call i32 @llvm.umin.i32(i32 %a, i32 %b)241 %max = call i32 @llvm.umax.i32(i32 %a, i32 %b)242 %sub = sub i32 %max, %min243 ret i32 %sub244}245 246define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {247; CHECK-LABEL: abd_minmax_i64:248; CHECK: // %bb.0:249; CHECK-NEXT: subs x8, x0, x1250; CHECK-NEXT: cneg x0, x8, ls251; CHECK-NEXT: ret252 %min = call i64 @llvm.umin.i64(i64 %a, i64 %b)253 %max = call i64 @llvm.umax.i64(i64 %a, i64 %b)254 %sub = sub i64 %max, %min255 ret i64 %sub256}257 258define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {259; CHECK-LABEL: abd_minmax_i128:260; CHECK: // %bb.0:261; CHECK-NEXT: subs x8, x0, x2262; CHECK-NEXT: sbc x9, x1, x3263; CHECK-NEXT: subs x10, x2, x0264; CHECK-NEXT: sbcs x11, x3, x1265; CHECK-NEXT: csel x0, x8, x10, lo266; CHECK-NEXT: csel x1, x9, x11, lo267; CHECK-NEXT: ret268 %min = call i128 @llvm.umin.i128(i128 %a, i128 %b)269 %max = call i128 @llvm.umax.i128(i128 %a, i128 %b)270 %sub = sub i128 %max, %min271 ret i128 %sub272}273 274;275; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b)276;277 278define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {279; CHECK-LABEL: abd_cmp_i8:280; CHECK: // %bb.0:281; CHECK-NEXT: and w8, w0, #0xff282; CHECK-NEXT: subs w8, w8, w1, uxtb283; CHECK-NEXT: cneg w0, w8, mi284; CHECK-NEXT: ret285 %cmp = icmp ugt i8 %a, %b286 %ab = sub i8 %a, %b287 %ba = sub i8 %b, %a288 %sel = select i1 %cmp, i8 %ab, i8 %ba289 ret i8 %sel290}291 292define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {293; CHECK-LABEL: abd_cmp_i16:294; CHECK: // %bb.0:295; CHECK-NEXT: and w8, w0, #0xffff296; CHECK-NEXT: subs w8, w8, w1, uxth297; CHECK-NEXT: cneg w0, w8, mi298; CHECK-NEXT: ret299 %cmp = icmp uge i16 %a, %b300 %ab = sub i16 %a, %b301 %ba = sub i16 %b, %a302 %sel = select i1 %cmp, i16 %ab, i16 %ba303 ret i16 %sel304}305 306define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {307; CHECK-LABEL: abd_cmp_i32:308; CHECK: // %bb.0:309; CHECK-NEXT: subs w8, w0, w1310; CHECK-NEXT: cneg w0, w8, ls311; CHECK-NEXT: ret312 %cmp = icmp ult i32 %a, %b313 %ab = sub i32 %a, %b314 %ba = sub i32 %b, %a315 %sel = select i1 %cmp, i32 %ba, i32 %ab316 ret i32 %sel317}318 319define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {320; CHECK-LABEL: abd_cmp_i64:321; CHECK: // %bb.0:322; CHECK-NEXT: subs x8, x0, x1323; CHECK-NEXT: cneg x0, x8, ls324; CHECK-NEXT: ret325 %cmp = icmp uge i64 %a, %b326 %ab = sub i64 %a, %b327 %ba = sub i64 %b, %a328 %sel = select i1 %cmp, i64 %ab, i64 %ba329 ret i64 %sel330}331 332define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {333; CHECK-LABEL: abd_cmp_i128:334; CHECK: // %bb.0:335; CHECK-NEXT: subs x8, x0, x2336; CHECK-NEXT: sbc x9, x1, x3337; CHECK-NEXT: subs x10, x2, x0338; CHECK-NEXT: sbcs x11, x3, x1339; CHECK-NEXT: csel x0, x8, x10, lo340; CHECK-NEXT: csel x1, x9, x11, lo341; CHECK-NEXT: ret342 %cmp = icmp uge i128 %a, %b343 %ab = sub i128 %a, %b344 %ba = sub i128 %b, %a345 %sel = select i1 %cmp, i128 %ab, i128 %ba346 ret i128 %sel347}348 349;350; negative tests351;352 353define i64 @vector_legalized(i16 %a, i16 %b) {354; CHECK-LABEL: vector_legalized:355; CHECK: // %bb.0:356; CHECK-NEXT: and w8, w0, #0xffff357; CHECK-NEXT: subs w8, w8, w1, uxth358; CHECK-NEXT: cneg w0, w8, mi359; CHECK-NEXT: ret360 %ea = zext i16 %a to i32361 %eb = zext i16 %b to i32362 %s = sub i32 %ea, %eb363 %ab = call i32 @llvm.abs.i32(i32 %s, i1 false)364 %e = zext i32 %ab to i64365 %red = call i64 @llvm.vector.reduce.add.v32i64(<32 x i64> zeroinitializer)366 %z = add i64 %red, %e367 ret i64 %z368}369 370;371; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abdu(a,b)372;373 374define i8 @abd_select_i8(i8 %a, i8 %b) nounwind {375; CHECK-LABEL: abd_select_i8:376; CHECK: // %bb.0:377; CHECK-NEXT: and w8, w0, #0xff378; CHECK-NEXT: subs w8, w8, w1, uxtb379; CHECK-NEXT: cneg w0, w8, mi380; CHECK-NEXT: ret381 %cmp = icmp ult i8 %a, %b382 %ab = select i1 %cmp, i8 %a, i8 %b383 %ba = select i1 %cmp, i8 %b, i8 %a384 %sub = sub i8 %ba, %ab385 ret i8 %sub386}387 388define i16 @abd_select_i16(i16 %a, i16 %b) nounwind {389; CHECK-LABEL: abd_select_i16:390; CHECK: // %bb.0:391; CHECK-NEXT: and w8, w0, #0xffff392; CHECK-NEXT: subs w8, w8, w1, uxth393; CHECK-NEXT: cneg w0, w8, mi394; CHECK-NEXT: ret395 %cmp = icmp ule i16 %a, %b396 %ab = select i1 %cmp, i16 %a, i16 %b397 %ba = select i1 %cmp, i16 %b, i16 %a398 %sub = sub i16 %ba, %ab399 ret i16 %sub400}401 402define i32 @abd_select_i32(i32 %a, i32 %b) nounwind {403; CHECK-LABEL: abd_select_i32:404; CHECK: // %bb.0:405; CHECK-NEXT: subs w8, w0, w1406; CHECK-NEXT: cneg w0, w8, ls407; CHECK-NEXT: ret408 %cmp = icmp ugt i32 %a, %b409 %ab = select i1 %cmp, i32 %a, i32 %b410 %ba = select i1 %cmp, i32 %b, i32 %a411 %sub = sub i32 %ab, %ba412 ret i32 %sub413}414 415define i64 @abd_select_i64(i64 %a, i64 %b) nounwind {416; CHECK-LABEL: abd_select_i64:417; CHECK: // %bb.0:418; CHECK-NEXT: subs x8, x0, x1419; CHECK-NEXT: cneg x0, x8, ls420; CHECK-NEXT: ret421 %cmp = icmp uge i64 %a, %b422 %ab = select i1 %cmp, i64 %a, i64 %b423 %ba = select i1 %cmp, i64 %b, i64 %a424 %sub = sub i64 %ab, %ba425 ret i64 %sub426}427 428define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {429; CHECK-LABEL: abd_select_i128:430; CHECK: // %bb.0:431; CHECK-NEXT: subs x8, x0, x2432; CHECK-NEXT: sbc x9, x1, x3433; CHECK-NEXT: subs x10, x2, x0434; CHECK-NEXT: sbcs x11, x3, x1435; CHECK-NEXT: csel x0, x8, x10, lo436; CHECK-NEXT: csel x1, x9, x11, lo437; CHECK-NEXT: ret438 %cmp = icmp ult i128 %a, %b439 %ab = select i1 %cmp, i128 %a, i128 %b440 %ba = select i1 %cmp, i128 %b, i128 %a441 %sub = sub i128 %ba, %ab442 ret i128 %sub443}444 445declare i8 @llvm.abs.i8(i8, i1)446declare i16 @llvm.abs.i16(i16, i1)447declare i32 @llvm.abs.i32(i32, i1)448declare i64 @llvm.abs.i64(i64, i1)449declare i128 @llvm.abs.i128(i128, i1)450 451declare i8 @llvm.umax.i8(i8, i8)452declare i16 @llvm.umax.i16(i16, i16)453declare i32 @llvm.umax.i32(i32, i32)454declare i64 @llvm.umax.i64(i64, i64)455 456declare i8 @llvm.umin.i8(i8, i8)457declare i16 @llvm.umin.i16(i16, i16)458declare i32 @llvm.umin.i32(i32, i32)459declare i64 @llvm.umin.i64(i64, i64)460