1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s 3; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t 4 5; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. 6; WARN-NOT: warning 7 8; For all the functions below should the operation is a nop 9define <vscale x 8 x i8> @trunc_i16toi8(<vscale x 8 x i16> %in) { 10; CHECK-LABEL: trunc_i16toi8: 11; CHECK: // %bb.0: // %entry 12; CHECK-NEXT: ret 13entry: 14 %out = trunc <vscale x 8 x i16> %in to <vscale x 8 x i8> 15 ret <vscale x 8 x i8> %out 16} 17 18define <vscale x 4 x i8> @trunc_i32toi8(<vscale x 4 x i32> %in) { 19; CHECK-LABEL: trunc_i32toi8: 20; CHECK: // %bb.0: // %entry 21; CHECK-NEXT: ret 22entry: 23 %out = trunc <vscale x 4 x i32> %in to <vscale x 4 x i8> 24 ret <vscale x 4 x i8> %out 25} 26 27define <vscale x 2 x i8> @trunc_i64toi8(<vscale x 2 x i64> %in) { 28; CHECK-LABEL: trunc_i64toi8: 29; CHECK: // %bb.0: // %entry 30; CHECK-NEXT: ret 31entry: 32 %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i8> 33 ret <vscale x 2 x i8> %out 34} 35 36define <vscale x 4 x i16> @trunc_i32toi16(<vscale x 4 x i32> %in) { 37; CHECK-LABEL: trunc_i32toi16: 38; CHECK: // %bb.0: // %entry 39; CHECK-NEXT: ret 40entry: 41 %out = trunc <vscale x 4 x i32> %in to <vscale x 4 x i16> 42 ret <vscale x 4 x i16> %out 43} 44 45define <vscale x 2 x i16> @trunc_i64toi16(<vscale x 2 x i64> %in) { 46; CHECK-LABEL: trunc_i64toi16: 47; CHECK: // %bb.0: // %entry 48; CHECK-NEXT: ret 49entry: 50 %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i16> 51 ret <vscale x 2 x i16> %out 52} 53 54define <vscale x 2 x i32> @trunc_i64toi32(<vscale x 2 x i64> %in) { 55; CHECK-LABEL: trunc_i64toi32: 56; CHECK: // %bb.0: // %entry 57; CHECK-NEXT: ret 58entry: 59 %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i32> 60 ret <vscale x 2 x i32> %out 61} 62 63; Truncating to i1 requires convert it to a cmp 64 65define <vscale x 2 x i1> @trunc_i64toi1(<vscale x 2 x i64> %in) { 66; CHECK-LABEL: trunc_i64toi1: 67; CHECK: // %bb.0: // %entry 68; CHECK-NEXT: ptrue p0.d 69; CHECK-NEXT: and z0.d, z0.d, #0x1 70; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0 71; CHECK-NEXT: ret 72entry: 73 %out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i1> 74 ret <vscale x 2 x i1> %out 75} 76 77define <vscale x 4 x i1> @trunc_i64toi1_split(<vscale x 4 x i64> %in) { 78; CHECK-LABEL: trunc_i64toi1_split: 79; CHECK: // %bb.0: // %entry 80; CHECK-NEXT: ptrue p0.d 81; CHECK-NEXT: and z1.d, z1.d, #0x1 82; CHECK-NEXT: and z0.d, z0.d, #0x1 83; CHECK-NEXT: cmpne p1.d, p0/z, z1.d, #0 84; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0 85; CHECK-NEXT: uzp1 p0.s, p0.s, p1.s 86; CHECK-NEXT: ret 87entry: 88 %out = trunc <vscale x 4 x i64> %in to <vscale x 4 x i1> 89 ret <vscale x 4 x i1> %out 90} 91 92define <vscale x 8 x i1> @trunc_i64toi1_split2(<vscale x 8 x i64> %in) { 93; CHECK-LABEL: trunc_i64toi1_split2: 94; CHECK: // %bb.0: // %entry 95; CHECK-NEXT: ptrue p0.d 96; CHECK-NEXT: and z3.d, z3.d, #0x1 97; CHECK-NEXT: and z2.d, z2.d, #0x1 98; CHECK-NEXT: and z1.d, z1.d, #0x1 99; CHECK-NEXT: and z0.d, z0.d, #0x1 100; CHECK-NEXT: cmpne p1.d, p0/z, z3.d, #0 101; CHECK-NEXT: cmpne p2.d, p0/z, z2.d, #0 102; CHECK-NEXT: uzp1 p1.s, p2.s, p1.s 103; CHECK-NEXT: cmpne p2.d, p0/z, z1.d, #0 104; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0 105; CHECK-NEXT: uzp1 p0.s, p0.s, p2.s 106; CHECK-NEXT: uzp1 p0.h, p0.h, p1.h 107; CHECK-NEXT: ret 108entry: 109 %out = trunc <vscale x 8 x i64> %in to <vscale x 8 x i1> 110 ret <vscale x 8 x i1> %out 111} 112 113define <vscale x 16 x i1> @trunc_i64toi1_split3(<vscale x 16 x i64> %in) { 114; CHECK-LABEL: trunc_i64toi1_split3: 115; CHECK: // %bb.0: // %entry 116; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill 117; CHECK-NEXT: addvl sp, sp, #-1 118; CHECK-NEXT: str p4, [sp, #7, mul vl] // 2-byte Folded Spill 119; CHECK-NEXT: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 8 * VG 120; CHECK-NEXT: .cfi_offset w29, -16 121; CHECK-NEXT: ptrue p0.d 122; CHECK-NEXT: and z7.d, z7.d, #0x1 123; CHECK-NEXT: and z6.d, z6.d, #0x1 124; CHECK-NEXT: and z5.d, z5.d, #0x1 125; CHECK-NEXT: and z4.d, z4.d, #0x1 126; CHECK-NEXT: and z3.d, z3.d, #0x1 127; CHECK-NEXT: and z2.d, z2.d, #0x1 128; CHECK-NEXT: cmpne p1.d, p0/z, z7.d, #0 129; CHECK-NEXT: cmpne p2.d, p0/z, z6.d, #0 130; CHECK-NEXT: cmpne p3.d, p0/z, z5.d, #0 131; CHECK-NEXT: cmpne p4.d, p0/z, z4.d, #0 132; CHECK-NEXT: and z1.d, z1.d, #0x1 133; CHECK-NEXT: and z0.d, z0.d, #0x1 134; CHECK-NEXT: uzp1 p1.s, p2.s, p1.s 135; CHECK-NEXT: cmpne p2.d, p0/z, z3.d, #0 136; CHECK-NEXT: uzp1 p3.s, p4.s, p3.s 137; CHECK-NEXT: cmpne p4.d, p0/z, z2.d, #0 138; CHECK-NEXT: uzp1 p2.s, p4.s, p2.s 139; CHECK-NEXT: cmpne p4.d, p0/z, z1.d, #0 140; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0 141; CHECK-NEXT: uzp1 p0.s, p0.s, p4.s 142; CHECK-NEXT: ldr p4, [sp, #7, mul vl] // 2-byte Folded Reload 143; CHECK-NEXT: uzp1 p1.h, p3.h, p1.h 144; CHECK-NEXT: uzp1 p0.h, p0.h, p2.h 145; CHECK-NEXT: uzp1 p0.b, p0.b, p1.b 146; CHECK-NEXT: addvl sp, sp, #1 147; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload 148; CHECK-NEXT: ret 149entry: 150 %out = trunc <vscale x 16 x i64> %in to <vscale x 16 x i1> 151 ret <vscale x 16 x i1> %out 152} 153 154 155define <vscale x 4 x i1> @trunc_i32toi1(<vscale x 4 x i32> %in) { 156; CHECK-LABEL: trunc_i32toi1: 157; CHECK: // %bb.0: // %entry 158; CHECK-NEXT: ptrue p0.s 159; CHECK-NEXT: and z0.s, z0.s, #0x1 160; CHECK-NEXT: cmpne p0.s, p0/z, z0.s, #0 161; CHECK-NEXT: ret 162entry: 163 %out = trunc <vscale x 4 x i32> %in to <vscale x 4 x i1> 164 ret <vscale x 4 x i1> %out 165} 166 167define <vscale x 8 x i1> @trunc_i16toi1(<vscale x 8 x i16> %in) { 168; CHECK-LABEL: trunc_i16toi1: 169; CHECK: // %bb.0: // %entry 170; CHECK-NEXT: ptrue p0.h 171; CHECK-NEXT: and z0.h, z0.h, #0x1 172; CHECK-NEXT: cmpne p0.h, p0/z, z0.h, #0 173; CHECK-NEXT: ret 174entry: 175 %out = trunc <vscale x 8 x i16> %in to <vscale x 8 x i1> 176 ret <vscale x 8 x i1> %out 177} 178 179define <vscale x 16 x i1> @trunc_i8toi1(<vscale x 16 x i8> %in) { 180; CHECK-LABEL: trunc_i8toi1: 181; CHECK: // %bb.0: // %entry 182; CHECK-NEXT: ptrue p0.b 183; CHECK-NEXT: and z0.b, z0.b, #0x1 184; CHECK-NEXT: cmpne p0.b, p0/z, z0.b, #0 185; CHECK-NEXT: ret 186entry: 187 %out = trunc <vscale x 16 x i8> %in to <vscale x 16 x i1> 188 ret <vscale x 16 x i1> %out 189} 190