375 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s3 4define i1 @combine_setcc_eq_vecreduce_or_v8i1(<8 x i8> %a) {5; CHECK-LABEL: combine_setcc_eq_vecreduce_or_v8i1:6; CHECK: // %bb.0:7; CHECK-NEXT: cmeq v0.8b, v0.8b, #08; CHECK-NEXT: mov w8, #1 // =0x19; CHECK-NEXT: umaxv b0, v0.8b10; CHECK-NEXT: fmov w9, s011; CHECK-NEXT: bic w0, w8, w912; CHECK-NEXT: ret13 %cmp1 = icmp eq <8 x i8> %a, zeroinitializer14 %cast = bitcast <8 x i1> %cmp1 to i815 %cmp2 = icmp eq i8 %cast, zeroinitializer16 ret i1 %cmp217}18 19define i1 @combine_setcc_eq_vecreduce_or_v16i1(<16 x i8> %a) {20; CHECK-LABEL: combine_setcc_eq_vecreduce_or_v16i1:21; CHECK: // %bb.0:22; CHECK-NEXT: cmeq v0.16b, v0.16b, #023; CHECK-NEXT: mov w8, #1 // =0x124; CHECK-NEXT: umaxv b0, v0.16b25; CHECK-NEXT: fmov w9, s026; CHECK-NEXT: bic w0, w8, w927; CHECK-NEXT: ret28 %cmp1 = icmp eq <16 x i8> %a, zeroinitializer29 %cast = bitcast <16 x i1> %cmp1 to i1630 %cmp2 = icmp eq i16 %cast, zeroinitializer31 ret i1 %cmp232}33 34define i1 @combine_setcc_eq_vecreduce_or_v32i1(<32 x i8> %a) {35; CHECK-LABEL: combine_setcc_eq_vecreduce_or_v32i1:36; CHECK: // %bb.0:37; CHECK-NEXT: cmeq v1.16b, v1.16b, #038; CHECK-NEXT: cmeq v0.16b, v0.16b, #039; CHECK-NEXT: mov w8, #1 // =0x140; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b41; CHECK-NEXT: umaxv b0, v0.16b42; CHECK-NEXT: fmov w9, s043; CHECK-NEXT: bic w0, w8, w944; CHECK-NEXT: ret45 %cmp1 = icmp eq <32 x i8> %a, zeroinitializer46 %cast = bitcast <32 x i1> %cmp1 to i3247 %cmp2 = icmp eq i32 %cast, zeroinitializer48 ret i1 %cmp249}50 51define i1 @combine_setcc_eq_vecreduce_or_v64i1(<64 x i8> %a) {52; CHECK-LABEL: combine_setcc_eq_vecreduce_or_v64i1:53; CHECK: // %bb.0:54; CHECK-NEXT: cmeq v2.16b, v2.16b, #055; CHECK-NEXT: cmeq v0.16b, v0.16b, #056; CHECK-NEXT: mov w9, #1 // =0x157; CHECK-NEXT: cmeq v3.16b, v3.16b, #058; CHECK-NEXT: cmeq v1.16b, v1.16b, #059; CHECK-NEXT: orr v0.16b, v0.16b, v2.16b60; CHECK-NEXT: orr v1.16b, v1.16b, v3.16b61; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b62; CHECK-NEXT: umaxv b0, v0.16b63; CHECK-NEXT: fmov w8, s064; CHECK-NEXT: bic w0, w9, w865; CHECK-NEXT: ret66 %cmp1 = icmp eq <64 x i8> %a, zeroinitializer67 %cast = bitcast <64 x i1> %cmp1 to i6468 %cmp2 = icmp eq i64 %cast, zeroinitializer69 ret i1 %cmp270}71 72define i1 @combine_setcc_ne_vecreduce_or_v8i1(<8 x i8> %a) {73; CHECK-LABEL: combine_setcc_ne_vecreduce_or_v8i1:74; CHECK: // %bb.0:75; CHECK-NEXT: cmtst v0.8b, v0.8b, v0.8b76; CHECK-NEXT: umaxv b0, v0.8b77; CHECK-NEXT: fmov w8, s078; CHECK-NEXT: and w0, w8, #0x179; CHECK-NEXT: ret80 %cmp1 = icmp ne <8 x i8> %a, zeroinitializer81 %cast = bitcast <8 x i1> %cmp1 to i882 %cmp2 = icmp ne i8 %cast, zeroinitializer83 ret i1 %cmp284}85 86define i1 @combine_setcc_ne_vecreduce_or_v16i1(<16 x i8> %a) {87; CHECK-LABEL: combine_setcc_ne_vecreduce_or_v16i1:88; CHECK: // %bb.0:89; CHECK-NEXT: cmtst v0.16b, v0.16b, v0.16b90; CHECK-NEXT: umaxv b0, v0.16b91; CHECK-NEXT: fmov w8, s092; CHECK-NEXT: and w0, w8, #0x193; CHECK-NEXT: ret94 %cmp1 = icmp ne <16 x i8> %a, zeroinitializer95 %cast = bitcast <16 x i1> %cmp1 to i1696 %cmp2 = icmp ne i16 %cast, zeroinitializer97 ret i1 %cmp298}99 100define i1 @combine_setcc_ne_vecreduce_or_v32i1(<32 x i8> %a) {101; CHECK-LABEL: combine_setcc_ne_vecreduce_or_v32i1:102; CHECK: // %bb.0:103; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b104; CHECK-NEXT: cmtst v0.16b, v0.16b, v0.16b105; CHECK-NEXT: umaxv b0, v0.16b106; CHECK-NEXT: fmov w8, s0107; CHECK-NEXT: and w0, w8, #0x1108; CHECK-NEXT: ret109 %cmp1 = icmp ne <32 x i8> %a, zeroinitializer110 %cast = bitcast <32 x i1> %cmp1 to i32111 %cmp2 = icmp ne i32 %cast, zeroinitializer112 ret i1 %cmp2113}114 115define i1 @combine_setcc_ne_vecreduce_or_v64i1(<64 x i8> %a) {116; CHECK-LABEL: combine_setcc_ne_vecreduce_or_v64i1:117; CHECK: // %bb.0:118; CHECK-NEXT: orr v1.16b, v1.16b, v3.16b119; CHECK-NEXT: orr v0.16b, v0.16b, v2.16b120; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b121; CHECK-NEXT: cmtst v0.16b, v0.16b, v0.16b122; CHECK-NEXT: umaxv b0, v0.16b123; CHECK-NEXT: fmov w8, s0124; CHECK-NEXT: and w0, w8, #0x1125; CHECK-NEXT: ret126 %cmp1 = icmp ne <64 x i8> %a, zeroinitializer127 %cast = bitcast <64 x i1> %cmp1 to i64128 %cmp2 = icmp ne i64 %cast, zeroinitializer129 ret i1 %cmp2130}131 132define i1 @combine_setcc_eq_vecreduce_and_v8i1(<8 x i8> %a) {133; CHECK-LABEL: combine_setcc_eq_vecreduce_and_v8i1:134; CHECK: // %bb.0:135; CHECK-NEXT: cmeq v0.8b, v0.8b, #0136; CHECK-NEXT: uminv b0, v0.8b137; CHECK-NEXT: fmov w8, s0138; CHECK-NEXT: and w0, w8, #0x1139; CHECK-NEXT: ret140 %cmp1 = icmp eq <8 x i8> %a, zeroinitializer141 %cast = bitcast <8 x i1> %cmp1 to i8142 %cmp2 = icmp eq i8 %cast, -1143 ret i1 %cmp2144}145 146define i1 @combine_setcc_eq_vecreduce_and_v16i1(<16 x i8> %a) {147; CHECK-LABEL: combine_setcc_eq_vecreduce_and_v16i1:148; CHECK: // %bb.0:149; CHECK-NEXT: cmeq v0.16b, v0.16b, #0150; CHECK-NEXT: uminv b0, v0.16b151; CHECK-NEXT: fmov w8, s0152; CHECK-NEXT: and w0, w8, #0x1153; CHECK-NEXT: ret154 %cmp1 = icmp eq <16 x i8> %a, zeroinitializer155 %cast = bitcast <16 x i1> %cmp1 to i16156 %cmp2 = icmp eq i16 %cast, -1157 ret i1 %cmp2158}159 160define i1 @combine_setcc_eq_vecreduce_and_v32i1(<32 x i8> %a) {161; CHECK-LABEL: combine_setcc_eq_vecreduce_and_v32i1:162; CHECK: // %bb.0:163; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b164; CHECK-NEXT: cmeq v0.16b, v0.16b, #0165; CHECK-NEXT: uminv b0, v0.16b166; CHECK-NEXT: fmov w8, s0167; CHECK-NEXT: and w0, w8, #0x1168; CHECK-NEXT: ret169 %cmp1 = icmp eq <32 x i8> %a, zeroinitializer170 %cast = bitcast <32 x i1> %cmp1 to i32171 %cmp2 = icmp eq i32 %cast, -1172 ret i1 %cmp2173}174 175define i1 @combine_setcc_eq_vecreduce_and_v64i1(<64 x i8> %a) {176; CHECK-LABEL: combine_setcc_eq_vecreduce_and_v64i1:177; CHECK: // %bb.0:178; CHECK-NEXT: orr v1.16b, v1.16b, v3.16b179; CHECK-NEXT: orr v0.16b, v0.16b, v2.16b180; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b181; CHECK-NEXT: cmeq v0.16b, v0.16b, #0182; CHECK-NEXT: uminv b0, v0.16b183; CHECK-NEXT: fmov w8, s0184; CHECK-NEXT: and w0, w8, #0x1185; CHECK-NEXT: ret186 %cmp1 = icmp eq <64 x i8> %a, zeroinitializer187 %cast = bitcast <64 x i1> %cmp1 to i64188 %cmp2 = icmp eq i64 %cast, -1189 ret i1 %cmp2190}191 192define i1 @combine_setcc_ne_vecreduce_and_v8i1(<8 x i8> %a) {193; CHECK-LABEL: combine_setcc_ne_vecreduce_and_v8i1:194; CHECK: // %bb.0:195; CHECK-NEXT: cmtst v0.8b, v0.8b, v0.8b196; CHECK-NEXT: mov w8, #1 // =0x1197; CHECK-NEXT: uminv b0, v0.8b198; CHECK-NEXT: fmov w9, s0199; CHECK-NEXT: bic w0, w8, w9200; CHECK-NEXT: ret201 %cmp1 = icmp ne <8 x i8> %a, zeroinitializer202 %cast = bitcast <8 x i1> %cmp1 to i8203 %cmp2 = icmp ne i8 %cast, -1204 ret i1 %cmp2205}206 207define i1 @combine_setcc_ne_vecreduce_and_v16i1(<16 x i8> %a) {208; CHECK-LABEL: combine_setcc_ne_vecreduce_and_v16i1:209; CHECK: // %bb.0:210; CHECK-NEXT: cmtst v0.16b, v0.16b, v0.16b211; CHECK-NEXT: mov w8, #1 // =0x1212; CHECK-NEXT: uminv b0, v0.16b213; CHECK-NEXT: fmov w9, s0214; CHECK-NEXT: bic w0, w8, w9215; CHECK-NEXT: ret216 %cmp1 = icmp ne <16 x i8> %a, zeroinitializer217 %cast = bitcast <16 x i1> %cmp1 to i16218 %cmp2 = icmp ne i16 %cast, -1219 ret i1 %cmp2220}221 222define i1 @combine_setcc_ne_vecreduce_and_v32i1(<32 x i8> %a) {223; CHECK-LABEL: combine_setcc_ne_vecreduce_and_v32i1:224; CHECK: // %bb.0:225; CHECK-NEXT: cmtst v0.16b, v0.16b, v0.16b226; CHECK-NEXT: cmeq v1.16b, v1.16b, #0227; CHECK-NEXT: mov w8, #1 // =0x1228; CHECK-NEXT: bic v0.16b, v0.16b, v1.16b229; CHECK-NEXT: uminv b0, v0.16b230; CHECK-NEXT: fmov w9, s0231; CHECK-NEXT: bic w0, w8, w9232; CHECK-NEXT: ret233 %cmp1 = icmp ne <32 x i8> %a, zeroinitializer234 %cast = bitcast <32 x i1> %cmp1 to i32235 %cmp2 = icmp ne i32 %cast, -1236 ret i1 %cmp2237}238 239define i1 @combine_setcc_ne_vecreduce_and_v64i1(<64 x i8> %a) {240; CHECK-LABEL: combine_setcc_ne_vecreduce_and_v64i1:241; CHECK: // %bb.0:242; CHECK-NEXT: cmtst v1.16b, v1.16b, v1.16b243; CHECK-NEXT: cmtst v0.16b, v0.16b, v0.16b244; CHECK-NEXT: mov w9, #1 // =0x1245; CHECK-NEXT: cmeq v2.16b, v2.16b, #0246; CHECK-NEXT: cmeq v3.16b, v3.16b, #0247; CHECK-NEXT: bic v1.16b, v1.16b, v3.16b248; CHECK-NEXT: bic v0.16b, v0.16b, v2.16b249; CHECK-NEXT: and v0.16b, v0.16b, v1.16b250; CHECK-NEXT: uminv b0, v0.16b251; CHECK-NEXT: fmov w8, s0252; CHECK-NEXT: bic w0, w9, w8253; CHECK-NEXT: ret254 %cmp1 = icmp ne <64 x i8> %a, zeroinitializer255 %cast = bitcast <64 x i1> %cmp1 to i64256 %cmp2 = icmp ne i64 %cast, -1257 ret i1 %cmp2258}259 260define i1 @combine_setcc_eq0_conjunction_xor_or(ptr %a, ptr %b) {261; CHECK-LABEL: combine_setcc_eq0_conjunction_xor_or:262; CHECK: // %bb.0:263; CHECK-NEXT: ldp x8, x11, [x1]264; CHECK-NEXT: ldp x9, x10, [x0]265; CHECK-NEXT: cmp x9, x8266; CHECK-NEXT: ccmp x10, x11, #0, eq267; CHECK-NEXT: cset w0, eq268; CHECK-NEXT: ret269 %bcmp = tail call i32 @bcmp(ptr dereferenceable(16) %a, ptr dereferenceable(16) %b, i64 16)270 %cmp = icmp eq i32 %bcmp, 0271 ret i1 %cmp272}273 274define i1 @combine_setcc_ne0_conjunction_xor_or(ptr %a, ptr %b) {275; CHECK-LABEL: combine_setcc_ne0_conjunction_xor_or:276; CHECK: // %bb.0:277; CHECK-NEXT: ldp x8, x11, [x1]278; CHECK-NEXT: ldp x9, x10, [x0]279; CHECK-NEXT: cmp x9, x8280; CHECK-NEXT: ccmp x10, x11, #0, eq281; CHECK-NEXT: cset w0, ne282; CHECK-NEXT: ret283 %bcmp = tail call i32 @bcmp(ptr dereferenceable(16) %a, ptr dereferenceable(16) %b, i64 16)284 %cmp = icmp ne i32 %bcmp, 0285 ret i1 %cmp286}287 288; Doesn't increase the number of instructions, where the LHS has multiple uses289define i32 @combine_setcc_multiuse(i32 %0, i32 %1, i32 %2, i32 %3) {290; CHECK-LABEL: combine_setcc_multiuse:291; CHECK: // %bb.0:292; CHECK-NEXT: eor w8, w3, w2293; CHECK-NEXT: eor w9, w1, w0294; CHECK-NEXT: orr w8, w8, w9295; CHECK-NEXT: cbz w8, .LBB18_2296; CHECK-NEXT: // %bb.1:297; CHECK-NEXT: mov w0, w8298; CHECK-NEXT: b use299; CHECK-NEXT: .LBB18_2:300; CHECK-NEXT: ret301 %5 = xor i32 %1, %0302 %6 = xor i32 %3, %2303 %7 = or i32 %6, %5304 %8 = icmp eq i32 %7, 0305 br i1 %8, label %11, label %9306 3079: ; preds = %4308 %10 = tail call i32 @use(i32 %7) #2309 br label %11310 31111: ; preds = %4, %9312 %12 = phi i32 [ %10, %9 ], [ %0, %4 ]313 ret i32 %12314}315 316; There may be issues with the CMP/CCMP with the scheduling of instructions317; that ISel will create out of the DAG318define i32 @combine_setcc_glue(i128 noundef %x, i128 noundef %y) {319; CHECK-LABEL: combine_setcc_glue:320; CHECK: // %bb.0: // %entry321; CHECK-NEXT: cmp x0, x2322; CHECK-NEXT: cset w0, eq323; CHECK-NEXT: ret324entry:325 %cmp3 = icmp eq i128 %x, %y326 %conv = trunc i128 %x to i64327 %conv1 = trunc i128 %y to i64328 %cmp = icmp eq i64 %conv, %conv1329 %or7 = or i1 %cmp3, %cmp330 %or = zext i1 %or7 to i32331 ret i32 %or332}333 334; Reduced test from https://github.com/llvm/llvm-project/issues/58675335define [2 x i64] @PR58675(i128 %a.addr, i128 %b.addr) {336; CHECK-LABEL: PR58675:337; CHECK: // %bb.0: // %entry338; CHECK-NEXT: mov x8, xzr339; CHECK-NEXT: mov x9, xzr340; CHECK-NEXT: .LBB20_1: // %do.body341; CHECK-NEXT: // =>This Inner Loop Header: Depth=1342; CHECK-NEXT: cmp x0, x8343; CHECK-NEXT: sbcs xzr, x1, x9344; CHECK-NEXT: csel x10, x0, x8, lo345; CHECK-NEXT: csel x11, x1, x9, lo346; CHECK-NEXT: subs x8, x2, x10347; CHECK-NEXT: sbc x9, x3, x11348; CHECK-NEXT: cmp x3, x11349; CHECK-NEXT: ccmp x2, x10, #0, eq350; CHECK-NEXT: b.ne .LBB20_1351; CHECK-NEXT: // %bb.2: // %do.end352; CHECK-NEXT: mov x0, xzr353; CHECK-NEXT: mov x1, xzr354; CHECK-NEXT: ret355entry:356 br label %do.body357 358do.body: ; preds = %do.body, %entry359 %a.addr.i1 = phi i128 [ 1, %do.body ], [ 0, %entry ]360 %b.addr.i2 = phi i128 [ %sub, %do.body ], [ 0, %entry ]361 %0 = tail call i128 @llvm.umin.i128(i128 %a.addr, i128 %b.addr.i2)362 %1 = tail call i128 @llvm.umax.i128(i128 0, i128 %a.addr)363 %sub = sub i128 %b.addr, %0364 %cmp18.not = icmp eq i128 %b.addr, %0365 br i1 %cmp18.not, label %do.end, label %do.body366 367do.end: ; preds = %do.body368 ret [2 x i64] zeroinitializer369}370 371declare i128 @llvm.umin.i128(i128, i128)372declare i128 @llvm.umax.i128(i128, i128)373declare i32 @bcmp(ptr nocapture, ptr nocapture, i64)374declare i32 @use(i32 noundef)375