467 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=arm64-apple-iphoneos -aarch64-enable-sink-fold=true -o - %s | FileCheck %s3 4define i3 @sign_i3(i3 %a) {5; CHECK-LABEL: sign_i3:6; CHECK: // %bb.0:7; CHECK-NEXT: sbfx w8, w0, #2, #18; CHECK-NEXT: orr w0, w8, #0x19; CHECK-NEXT: ret10 %c = icmp sgt i3 %a, -111 %res = select i1 %c, i3 1, i3 -112 ret i3 %res13}14 15define i4 @sign_i4(i4 %a) {16; CHECK-LABEL: sign_i4:17; CHECK: // %bb.0:18; CHECK-NEXT: sbfx w8, w0, #3, #119; CHECK-NEXT: orr w0, w8, #0x120; CHECK-NEXT: ret21 %c = icmp sgt i4 %a, -122 %res = select i1 %c, i4 1, i4 -123 ret i4 %res24}25 26define i8 @sign_i8(i8 %a) {27; CHECK-LABEL: sign_i8:28; CHECK: // %bb.0:29; CHECK-NEXT: sbfx w8, w0, #7, #130; CHECK-NEXT: orr w0, w8, #0x131; CHECK-NEXT: ret32 %c = icmp sgt i8 %a, -133 %res = select i1 %c, i8 1, i8 -134 ret i8 %res35}36 37define i16 @sign_i16(i16 %a) {38; CHECK-LABEL: sign_i16:39; CHECK: // %bb.0:40; CHECK-NEXT: sbfx w8, w0, #15, #141; CHECK-NEXT: orr w0, w8, #0x142; CHECK-NEXT: ret43 %c = icmp sgt i16 %a, -144 %res = select i1 %c, i16 1, i16 -145 ret i16 %res46}47 48define i32 @sign_i32(i32 %a) {49; CHECK-LABEL: sign_i32:50; CHECK: // %bb.0:51; CHECK-NEXT: asr w8, w0, #3152; CHECK-NEXT: orr w0, w8, #0x153; CHECK-NEXT: ret54 %c = icmp sgt i32 %a, -155 %res = select i1 %c, i32 1, i32 -156 ret i32 %res57}58 59define i64 @sign_i64(i64 %a) {60; CHECK-LABEL: sign_i64:61; CHECK: // %bb.0:62; CHECK-NEXT: asr x8, x0, #6363; CHECK-NEXT: orr x0, x8, #0x164; CHECK-NEXT: ret65 %c = icmp sgt i64 %a, -166 %res = select i1 %c, i64 1, i64 -167 ret i64 %res68}69 70 71define i64 @not_sign_i64(i64 %a) {72; CHECK-LABEL: not_sign_i64:73; CHECK: // %bb.0:74; CHECK-NEXT: mov w8, #1 // =0x175; CHECK-NEXT: cmp x0, #076; CHECK-NEXT: cneg x0, x8, le77; CHECK-NEXT: ret78 %c = icmp sgt i64 %a, 079 %res = select i1 %c, i64 1, i64 -180 ret i64 %res81}82 83define i64 @not_sign_i64_2(i64 %a) {84; CHECK-LABEL: not_sign_i64_2:85; CHECK: // %bb.0:86; CHECK-NEXT: asr x0, x0, #6387; CHECK-NEXT: ret88 %c = icmp sgt i64 %a, -189 %res = select i1 %c, i64 0, i64 -190 ret i64 %res91}92 93define i64 @not_sign_i64_3(i64 %a) {94; CHECK-LABEL: not_sign_i64_3:95; CHECK: // %bb.0:96; CHECK-NEXT: mvn x8, x097; CHECK-NEXT: lsr x0, x8, #6398; CHECK-NEXT: ret99 %c = icmp sgt i64 %a, -1100 %res = select i1 %c, i64 1, i64 0101 ret i64 %res102}103 104define i64 @not_sign_i64_4(i64 %a) {105; CHECK-LABEL: not_sign_i64_4:106; CHECK: // %bb.0:107; CHECK-NEXT: mov x0, #-1 // =0xffffffffffffffff108; CHECK-NEXT: ret109 %c = icmp ugt i64 %a, -1110 %res = select i1 %c, i64 1, i64 -1111 ret i64 %res112}113 114define <7 x i8> @sign_7xi8(<7 x i8> %a) {115; CHECK-LABEL: sign_7xi8:116; CHECK: // %bb.0:117; CHECK-NEXT: movi v1.8b, #1118; CHECK-NEXT: cmlt v0.8b, v0.8b, #0119; CHECK-NEXT: orr v0.8b, v0.8b, v1.8b120; CHECK-NEXT: ret121 %c = icmp sgt <7 x i8> %a, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>122 %res = select <7 x i1> %c, <7 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <7 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>123 ret <7 x i8> %res124}125 126define <8 x i8> @sign_8xi8(<8 x i8> %a) {127; CHECK-LABEL: sign_8xi8:128; CHECK: // %bb.0:129; CHECK-NEXT: movi v1.8b, #1130; CHECK-NEXT: cmlt v0.8b, v0.8b, #0131; CHECK-NEXT: orr v0.8b, v0.8b, v1.8b132; CHECK-NEXT: ret133 %c = icmp sgt <8 x i8> %a, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>134 %res = select <8 x i1> %c, <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <8 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>135 ret <8 x i8> %res136}137 138define <16 x i8> @sign_16xi8(<16 x i8> %a) {139; CHECK-LABEL: sign_16xi8:140; CHECK: // %bb.0:141; CHECK-NEXT: movi v1.16b, #1142; CHECK-NEXT: cmlt v0.16b, v0.16b, #0143; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b144; CHECK-NEXT: ret145 %c = icmp sgt <16 x i8> %a, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>146 %res = select <16 x i1> %c, <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <16 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>147 ret <16 x i8> %res148}149 150define <3 x i32> @sign_3xi32(<3 x i32> %a) {151; CHECK-LABEL: sign_3xi32:152; CHECK: // %bb.0:153; CHECK-NEXT: cmlt v0.4s, v0.4s, #0154; CHECK-NEXT: orr v0.4s, #1155; CHECK-NEXT: ret156 %c = icmp sgt <3 x i32> %a, <i32 -1, i32 -1, i32 -1>157 %res = select <3 x i1> %c, <3 x i32> <i32 1, i32 1, i32 1>, <3 x i32> <i32 -1, i32 -1, i32 -1>158 ret <3 x i32> %res159}160 161define <4 x i32> @sign_4xi32(<4 x i32> %a) {162; CHECK-LABEL: sign_4xi32:163; CHECK: // %bb.0:164; CHECK-NEXT: cmlt v0.4s, v0.4s, #0165; CHECK-NEXT: orr v0.4s, #1166; CHECK-NEXT: ret167 %c = icmp sgt <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>168 %res = select <4 x i1> %c, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>169 ret <4 x i32> %res170}171 172define <4 x i32> @sign_4xi32_multi_use(<4 x i32> %a) {173; CHECK-LABEL: sign_4xi32_multi_use:174; CHECK: // %bb.0:175; CHECK-NEXT: sub sp, sp, #32176; CHECK-NEXT: str x30, [sp, #16] // 8-byte Spill177; CHECK-NEXT: .cfi_def_cfa_offset 32178; CHECK-NEXT: .cfi_offset w30, -16179; CHECK-NEXT: cmlt v1.4s, v0.4s, #0180; CHECK-NEXT: cmge v0.4s, v0.4s, #0181; CHECK-NEXT: xtn v0.4h, v0.4s182; CHECK-NEXT: orr v1.4s, #1183; CHECK-NEXT: str q1, [sp] // 16-byte Spill184; CHECK-NEXT: bl use_4xi1185; CHECK-NEXT: ldr q0, [sp] // 16-byte Reload186; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Reload187; CHECK-NEXT: add sp, sp, #32188; CHECK-NEXT: ret189 %c = icmp sgt <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>190 %res = select <4 x i1> %c, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>191 call void @use_4xi1(<4 x i1> %c)192 ret <4 x i32> %res193}194 195; Second icmp operand breaks sign pattern.196define <4 x i32> @not_sign_4xi32(<4 x i32> %a) {197; CHECK-LABEL: not_sign_4xi32:198; CHECK: // %bb.0:199; CHECK-NEXT: adrp x8, .LCPI16_0200; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI16_0]201; CHECK-NEXT: cmge v0.4s, v1.4s, v0.4s202; CHECK-NEXT: orr v0.4s, #1203; CHECK-NEXT: ret204 %c = icmp sgt <4 x i32> %a, <i32 1, i32 -1, i32 -1, i32 -1>205 %res = select <4 x i1> %c, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>206 ret <4 x i32> %res207}208 209; First select operand breaks sign pattern.210define <4 x i32> @not_sign_4xi32_2(<4 x i32> %a) {211; CHECK-LABEL: not_sign_4xi32_2:212; CHECK: // %bb.0:213; CHECK-NEXT: adrp x8, .LCPI17_0214; CHECK-NEXT: cmlt v0.4s, v0.4s, #0215; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI17_0]216; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b217; CHECK-NEXT: ret218 %c = icmp sgt <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>219 %res = select <4 x i1> %c, <4 x i32> <i32 1, i32 1, i32 -1, i32 1>, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>220 ret <4 x i32> %res221}222 223; Second select operand breaks sign pattern.224define <4 x i32> @not_sign_4xi32_3(<4 x i32> %a) {225; CHECK-LABEL: not_sign_4xi32_3:226; CHECK: // %bb.0:227; CHECK-NEXT: adrp x8, .LCPI18_0228; CHECK-NEXT: cmge v0.4s, v0.4s, #0229; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI18_0]230; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b231; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s232; CHECK-NEXT: ret233 %c = icmp sgt <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>234 %res = select <4 x i1> %c, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 1>235 ret <4 x i32> %res236}237 238; i65 is not legal.239define <4 x i65> @sign_4xi65(<4 x i65> %a) {240; CHECK-LABEL: sign_4xi65:241; CHECK: // %bb.0:242; CHECK-NEXT: sbfx x8, x5, #0, #1243; CHECK-NEXT: sbfx x9, x3, #0, #1244; CHECK-NEXT: sbfx x10, x1, #0, #1245; CHECK-NEXT: sbfx x11, x7, #0, #1246; CHECK-NEXT: lsr x1, x10, #63247; CHECK-NEXT: lsr x3, x9, #63248; CHECK-NEXT: lsr x5, x8, #63249; CHECK-NEXT: lsr x7, x11, #63250; CHECK-NEXT: orr x0, x10, #0x1251; CHECK-NEXT: orr x2, x9, #0x1252; CHECK-NEXT: orr x4, x8, #0x1253; CHECK-NEXT: orr x6, x11, #0x1254; CHECK-NEXT: ret255 %c = icmp sgt <4 x i65> %a, <i65 -1, i65 -1, i65 -1, i65 -1>256 %res = select <4 x i1> %c, <4 x i65> <i65 1, i65 1, i65 1, i65 1>, <4 x i65 > <i65 -1, i65 -1, i65 -1, i65 -1>257 ret <4 x i65> %res258}259 260define i32 @or_neg(i32 %x, i32 %y) {261; CHECK-LABEL: or_neg:262; CHECK: // %bb.0:263; CHECK-NEXT: orr w8, w0, #0x1264; CHECK-NEXT: cmn w1, w8265; CHECK-NEXT: cset w0, lt266; CHECK-NEXT: ret267 %3 = or i32 %x, 1268 %4 = sub i32 0, %3269 %5 = icmp sgt i32 %4, %y270 %6 = zext i1 %5 to i32271 ret i32 %6272}273 274define i32 @or_neg_ugt(i32 %x, i32 %y) {275; CHECK-LABEL: or_neg_ugt:276; CHECK: // %bb.0:277; CHECK-NEXT: orr w8, w0, #0x1278; CHECK-NEXT: cmn w1, w8279; CHECK-NEXT: cset w0, lo280; CHECK-NEXT: ret281 %3 = or i32 %x, 1282 %4 = sub i32 0, %3283 %5 = icmp ugt i32 %4, %y284 %6 = zext i1 %5 to i32285 ret i32 %6286}287 288; Negative test289 290define i32 @or_neg_no_smin(i32 %x, i32 %y) {291; CHECK-LABEL: or_neg_no_smin:292; CHECK: // %bb.0:293; CHECK-NEXT: neg w8, w0294; CHECK-NEXT: cmp w8, w1295; CHECK-NEXT: cset w0, gt296; CHECK-NEXT: ret297 %4 = sub i32 0, %x298 %5 = icmp sgt i32 %4, %y299 %6 = zext i1 %5 to i32300 ret i32 %6301}302 303; Negative test304 305define i32 @or_neg_ult_no_zero(i32 %x, i32 %y) {306; CHECK-LABEL: or_neg_ult_no_zero:307; CHECK: // %bb.0:308; CHECK-NEXT: neg w8, w0309; CHECK-NEXT: cmp w8, w1310; CHECK-NEXT: cset w0, lo311; CHECK-NEXT: ret312 %4 = sub i32 0, %x313 %5 = icmp ult i32 %4, %y314 %6 = zext i1 %5 to i32315 ret i32 %6316}317 318define i32 @or_neg_no_smin_but_zero(i32 %x, i32 %y) {319; CHECK-LABEL: or_neg_no_smin_but_zero:320; CHECK: // %bb.0:321; CHECK-NEXT: bic w8, w0, w0, asr #31322; CHECK-NEXT: cmn w1, w8323; CHECK-NEXT: cset w0, lt324; CHECK-NEXT: ret325 %3 = call i32 @llvm.smax.i32(i32 %x, i32 0)326 %4 = sub i32 0, %3327 %5 = icmp sgt i32 %4, %y328 %6 = zext i1 %5 to i32329 ret i32 %6330}331 332define i32 @or_neg_slt_zero_but_no_smin(i32 %x, i32 %y) {333; CHECK-LABEL: or_neg_slt_zero_but_no_smin:334; CHECK: // %bb.0:335; CHECK-NEXT: mov w8, #9 // =0x9336; CHECK-NEXT: cmp w0, #9337; CHECK-NEXT: csel w8, w0, w8, lo338; CHECK-NEXT: neg w8, w8339; CHECK-NEXT: cmp w8, w1340; CHECK-NEXT: cset w0, hi341; CHECK-NEXT: ret342 %3 = call i32 @llvm.umin.i32(i32 %x, i32 9)343 %4 = sub i32 0, %3344 %5 = icmp ugt i32 %4, %y345 %6 = zext i1 %5 to i32346 ret i32 %6347}348 349define i32 @or_neg2(i32 %x, i32 %y) {350; CHECK-LABEL: or_neg2:351; CHECK: // %bb.0:352; CHECK-NEXT: orr w8, w0, #0x1353; CHECK-NEXT: cmn w1, w8354; CHECK-NEXT: cset w0, le355; CHECK-NEXT: ret356 %3 = or i32 %x, 1357 %4 = sub i32 0, %3358 %5 = icmp sge i32 %4, %y359 %6 = zext i1 %5 to i32360 ret i32 %6361}362 363define i32 @or_neg3(i32 %x, i32 %y) {364; CHECK-LABEL: or_neg3:365; CHECK: // %bb.0:366; CHECK-NEXT: orr w8, w0, #0x1367; CHECK-NEXT: cmn w1, w8368; CHECK-NEXT: cset w0, gt369; CHECK-NEXT: ret370 %3 = or i32 %x, 1371 %4 = sub i32 0, %3372 %5 = icmp slt i32 %4, %y373 %6 = zext i1 %5 to i32374 ret i32 %6375}376 377define i32 @or_neg4(i32 %x, i32 %y) {378; CHECK-LABEL: or_neg4:379; CHECK: // %bb.0:380; CHECK-NEXT: orr w8, w0, #0x1381; CHECK-NEXT: cmn w1, w8382; CHECK-NEXT: cset w0, ge383; CHECK-NEXT: ret384 %3 = or i32 %x, 1385 %4 = sub i32 0, %3386 %5 = icmp sle i32 %4, %y387 %6 = zext i1 %5 to i32388 ret i32 %6389}390 391define i32 @or_neg_ult(i32 %x, i32 %y) {392; CHECK-LABEL: or_neg_ult:393; CHECK: // %bb.0:394; CHECK-NEXT: orr w8, w0, #0x1395; CHECK-NEXT: cmn w1, w8396; CHECK-NEXT: cset w0, lo397; CHECK-NEXT: ret398 %3 = or i32 %x, 1399 %4 = sub i32 0, %3400 %5 = icmp ugt i32 %4, %y401 %6 = zext i1 %5 to i32402 ret i32 %6403}404 405define i32 @or_neg_no_smin2(i32 %x, i32 %y) {406; CHECK-LABEL: or_neg_no_smin2:407; CHECK: // %bb.0:408; CHECK-NEXT: neg w8, w0409; CHECK-NEXT: cmp w8, w1410; CHECK-NEXT: cset w0, ge411; CHECK-NEXT: ret412 %4 = sub i32 0, %x413 %5 = icmp sge i32 %4, %y414 %6 = zext i1 %5 to i32415 ret i32 %6416}417 418; Negative test419 420define i32 @or_neg_ult_no_zero2(i32 %x, i32 %y) {421; CHECK-LABEL: or_neg_ult_no_zero2:422; CHECK: // %bb.0:423; CHECK-NEXT: neg w8, w0424; CHECK-NEXT: cmp w8, w1425; CHECK-NEXT: cset w0, lo426; CHECK-NEXT: ret427 %4 = sub i32 0, %x428 %5 = icmp ult i32 %4, %y429 %6 = zext i1 %5 to i32430 ret i32 %6431}432 433define i32 @or_neg_no_smin_but_zero2(i32 %x, i32 %y) {434; CHECK-LABEL: or_neg_no_smin_but_zero2:435; CHECK: // %bb.0:436; CHECK-NEXT: bic w8, w0, w0, asr #31437; CHECK-NEXT: cmn w1, w8438; CHECK-NEXT: cset w0, ge439; CHECK-NEXT: ret440 %3 = call i32 @llvm.smax.i32(i32 %x, i32 0)441 %4 = sub i32 0, %3442 %5 = icmp sle i32 %4, %y443 %6 = zext i1 %5 to i32444 ret i32 %6445}446 447define i32 @or_neg_slt_zero_but_no_smin2(i32 %x, i32 %y) {448; CHECK-LABEL: or_neg_slt_zero_but_no_smin2:449; CHECK: // %bb.0:450; CHECK-NEXT: mov w8, #9 // =0x9451; CHECK-NEXT: cmp w0, #9452; CHECK-NEXT: csel w8, w0, w8, lo453; CHECK-NEXT: neg w8, w8454; CHECK-NEXT: cmp w8, w1455; CHECK-NEXT: cset w0, hs456; CHECK-NEXT: ret457 %3 = call i32 @llvm.umin.i32(i32 %x, i32 9)458 %4 = sub i32 0, %3459 %5 = icmp uge i32 %4, %y460 %6 = zext i1 %5 to i32461 ret i32 %6462}463 464declare i32 @llvm.smax.i32(i32, i32)465declare i32 @llvm.umax.i32(i32, i32)466declare void @use_4xi1(<4 x i1>)467