| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | |
| ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s | |
| define <vscale x 16 x i8> @repeat_quad_i8(<16 x i8> %a) { | |
| ; CHECK-LABEL: repeat_quad_i8: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 16 x i8> @llvm.vector.repeat.nxv16i8.v16i8(<16 x i8> %a) | |
| ret <vscale x 16 x i8> %out | |
| } | |
| define <vscale x 16 x i8> @repeat_double_i8(<8 x i8> %a) { | |
| ; CHECK-LABEL: repeat_double_i8: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %tmp = shufflevector <8 x i8> %a, <8 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> | |
| %out = call <vscale x 16 x i8> @llvm.vector.repeat.nxv16i8.v16i8(<16 x i8> %tmp) | |
| ret <vscale x 16 x i8> %out | |
| } | |
| define <vscale x 8 x i16> @repeat_double_i8_to_double_sve(<8 x i8> %a) { | |
| ; CHECK-LABEL: repeat_double_i8_to_double_sve: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: ushll v0.8h, v0.8b, #0 | |
| ; CHECK-NEXT: ptrue p0.h | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: sxtb z0.h, p0/m, z0.h | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 8 x i8> @llvm.vector.repeat.nxv8i8.v8i8(<8 x i8> %a) | |
| %out.legal = sext <vscale x 8 x i8> %out to <vscale x 8 x i16> | |
| ret <vscale x 8 x i16> %out.legal | |
| } | |
| define <vscale x 16 x i8> @repeat_one_i8(<8 x i8> %a.legal) { | |
| ; CHECK-LABEL: repeat_one_i8: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.b, b0 | |
| ; CHECK-NEXT: ret | |
| %a = call <1 x i8> @llvm.vector.extract.v1i8.nxv1i8(<8 x i8> %a.legal, i64 0) | |
| %out = call <vscale x 1 x i8> @llvm.vector.repeat.nxv1i8.v1i8(<1 x i8> %a) | |
| %out.legal = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.nxv1i8(<vscale x 16 x i8> poison, <vscale x 1 x i8> %out, i64 0) | |
| ret <vscale x 16 x i8> %out.legal | |
| } | |
| define <vscale x 8 x i16> @repeat_quad_i16(<8 x i16> %a) { | |
| ; CHECK-LABEL: repeat_quad_i16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 8 x i16> @llvm.vector.repeat.nxv8i16.v8i16(<8 x i16> %a) | |
| ret <vscale x 8 x i16> %out | |
| } | |
| define <vscale x 16 x i8> @repeat_wide_i16(<8 x i16> %a.lo, <8 x i16> %a.hi) { | |
| ; CHECK-LABEL: repeat_wide_i16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: uzp2 v2.8h, v0.8h, v1.8h | |
| ; CHECK-NEXT: uzp1 v0.8h, v0.8h, v1.8h | |
| ; CHECK-NEXT: mov z1.q, q2 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: zip2 z2.h, z0.h, z1.h | |
| ; CHECK-NEXT: zip1 z0.h, z0.h, z1.h | |
| ; CHECK-NEXT: uzp1 z0.b, z0.b, z2.b | |
| ; CHECK-NEXT: ret | |
| %a = shufflevector <8 x i16> %a.lo, <8 x i16> %a.hi, | |
| <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> | |
| %out = call <vscale x 16 x i16> @llvm.vector.repeat.nxv16i16.v16i16(<16 x i16> %a) | |
| %out.legal = trunc <vscale x 16 x i16> %out to <vscale x 16 x i8> | |
| ret <vscale x 16 x i8> %out.legal | |
| } | |
| define <vscale x 8 x i16> @repeat_double_i16(<4 x i16> %a) { | |
| ; CHECK-LABEL: repeat_double_i16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %tmp = shufflevector <4 x i16> %a, <4 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3> | |
| %out = call <vscale x 8 x i16> @llvm.vector.repeat.nxv8i16.v8i16(<8 x i16> %tmp) | |
| ret <vscale x 8 x i16> %out | |
| } | |
| define <vscale x 8 x i16> @repeat_one_i16(<4 x i16> %a.legal) { | |
| ; CHECK-LABEL: repeat_one_i16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.h, h0 | |
| ; CHECK-NEXT: ret | |
| %a = call <1 x i16> @llvm.vector.extract.v1i16.nxv1i16(<4 x i16> %a.legal, i64 0) | |
| %out = call <vscale x 1 x i16> @llvm.vector.repeat.nxv1i16.v1i16(<1 x i16> %a) | |
| %out.legal = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv1i16(<vscale x 8 x i16> poison, <vscale x 1 x i16> %out, i64 0) | |
| ret <vscale x 8 x i16> %out.legal | |
| } | |
| define <vscale x 4 x i32> @repeat_double_i16_to_double_sve(<4 x i16> %a) { | |
| ; CHECK-LABEL: repeat_double_i16_to_double_sve: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: ushll v0.4s, v0.4h, #0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.s, z0.s, #0xffff | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 4 x i16> @llvm.vector.repeat.nxv4i16.v4i16(<4 x i16> %a) | |
| %out.legal = zext <vscale x 4 x i16> %out to <vscale x 4 x i32> | |
| ret <vscale x 4 x i32> %out.legal | |
| } | |
| define <vscale x 4 x i32> @repeat_quad_i32(<4 x i32> %a) { | |
| ; CHECK-LABEL: repeat_quad_i32: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 4 x i32> @llvm.vector.repeat.nxv4i32.v4i32(<4 x i32> %a) | |
| ret <vscale x 4 x i32> %out | |
| } | |
| define <vscale x 4 x i32> @repeat_double_i32(<2 x i32> %a) { | |
| ; CHECK-LABEL: repeat_double_i32: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %tmp = shufflevector <2 x i32> %a, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1> | |
| %out = call <vscale x 4 x i32> @llvm.vector.repeat.nxv4i32.v4i32(<4 x i32> %tmp) | |
| ret <vscale x 4 x i32> %out | |
| } | |
| define <vscale x 4 x i32> @repeat_one_i32(<2 x i32> %a.legal) { | |
| ; CHECK-LABEL: repeat_one_i32: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.s, s0 | |
| ; CHECK-NEXT: ret | |
| %a = call <1 x i32> @llvm.vector.extract.v1i32.nxv1i32(<2 x i32> %a.legal, i64 0) | |
| %out = call <vscale x 1 x i32> @llvm.vector.repeat.nxv1i32.v1i32(<1 x i32> %a) | |
| %out.legal = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.nxv1i32(<vscale x 4 x i32> poison, <vscale x 1 x i32> %out, i64 0) | |
| ret <vscale x 4 x i32> %out.legal | |
| } | |
| define <vscale x 2 x i64> @repeat_quad_i64(<2 x i64> %a) { | |
| ; CHECK-LABEL: repeat_quad_i64: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 2 x i64> @llvm.vector.repeat.nxv2i64.v2i64(<2 x i64> %a) | |
| ret <vscale x 2 x i64> %out | |
| } | |
| define <vscale x 2 x i64> @repeat_double_i64(<1 x i64> %a) { | |
| ; CHECK-LABEL: repeat_double_i64: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-NEXT: dup v0.2d, v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %tmp = shufflevector <1 x i64> %a, <1 x i64> poison, <2 x i32> zeroinitializer | |
| %out = call <vscale x 2 x i64> @llvm.vector.repeat.nxv2i64.v2i64(<2 x i64> %tmp) | |
| ret <vscale x 2 x i64> %out | |
| } | |
| define <vscale x 2 x i64> @repeat_one_i64(<1 x i64> %a) { | |
| ; CHECK-LABEL: repeat_one_i64: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.d, d0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 1 x i64> @llvm.vector.repeat.nxv1i64.v1i64(<1 x i64> %a) | |
| %out.legal = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.nxv1i64(<vscale x 2 x i64> poison, <vscale x 1 x i64> %out, i64 0) | |
| ret <vscale x 2 x i64> %out.legal | |
| } | |
| ; vscale_range tests | |
| ; wider-than-NEON fixed-length source and wide destination | |
| define <vscale x 4 x i32> @repeat_v4i64_to_nxv4i64(<vscale x 2 x i64> %a.legal) vscale_range(2,8) { | |
| ; CHECK-LABEL: repeat_v4i64_to_nxv4i64: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: movprfx z1, z0 | |
| ; CHECK-NEXT: ext z1.b, z1.b, z0.b, #16 | |
| ; CHECK-NEXT: zip2 v2.2d, v0.2d, v1.2d | |
| ; CHECK-NEXT: zip1 v0.2d, v0.2d, v1.2d | |
| ; CHECK-NEXT: mov z1.q, q2 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: zip2 z2.d, z0.d, z1.d | |
| ; CHECK-NEXT: zip1 z0.d, z0.d, z1.d | |
| ; CHECK-NEXT: uzp1 z0.s, z0.s, z2.s | |
| ; CHECK-NEXT: ret | |
| %a = call <4 x i64> @llvm.vector.extract.v4i64.nxv2i64(<vscale x 2 x i64> %a.legal, i64 0) | |
| %r = call <vscale x 4 x i64> @llvm.vector.repeat.nxv4i64.v4i64(<4 x i64> %a) | |
| %r.legal = trunc <vscale x 4 x i64> %r to <vscale x 4 x i32> | |
| ret <vscale x 4 x i32> %r.legal | |
| } | |
| ; FP / BFP types | |
| define <vscale x 8 x half> @repeat_quad_f16(<8 x half> %a) { | |
| ; CHECK-LABEL: repeat_quad_f16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 8 x half> @llvm.vector.repeat.nxv8f16(<8 x half> %a) | |
| ret <vscale x 8 x half> %out | |
| } | |
| define <vscale x 8 x half> @repeat_double_f16(<4 x half> %a) { | |
| ; CHECK-LABEL: repeat_double_f16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %tmp = shufflevector <4 x half> %a, <4 x half> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3> | |
| %out = call <vscale x 8 x half> @llvm.vector.repeat.nxv8f16(<8 x half> %tmp) | |
| ret <vscale x 8 x half> %out | |
| } | |
| define <vscale x 4 x half> @repeat_double_f16_to_double_sve(<4 x half> %a) { | |
| ; CHECK-LABEL: repeat_double_f16_to_double_sve: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.d, d0 | |
| ; CHECK-NEXT: uunpklo z0.s, z0.h | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 4 x half> @llvm.vector.repeat.nxv4f16(<4 x half> %a) | |
| ret <vscale x 4 x half> %out | |
| } | |
| define <vscale x 2 x half> @repeat_2f16_to_nxv2f16(<4 x half> %a) { | |
| ; CHECK-LABEL: repeat_2f16_to_nxv2f16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-NEXT: dup v0.2s, v0.s[0] | |
| ; CHECK-NEXT: mov z0.d, d0 | |
| ; CHECK-NEXT: uunpklo z0.s, z0.h | |
| ; CHECK-NEXT: uunpklo z0.d, z0.s | |
| ; CHECK-NEXT: ret | |
| %a.legal = call <2 x half> @llvm.vector.extract.v2f16.v4f16(<4 x half> %a, i64 0) | |
| %out = call <vscale x 2 x half> @llvm.vector.repeat.nxv2f16(<2 x half> %a.legal) | |
| ret <vscale x 2 x half> %out | |
| } | |
| define <vscale x 8 x half> @repeat_one_f16(<4 x half> %a.legal) { | |
| ; CHECK-LABEL: repeat_one_f16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.h, h0 | |
| ; CHECK-NEXT: ret | |
| %a = call <1 x half> @llvm.vector.extract.v1f16.v4f16(<4 x half> %a.legal, i64 0) | |
| %out = call <vscale x 1 x half> @llvm.vector.repeat.nxv1f16.v1f16(<1 x half> %a) | |
| %out.legal = call <vscale x 8 x half> @llvm.vector.insert.nxv8f16.nxv1f16(<vscale x 8 x half> poison, <vscale x 1 x half> %out, i64 0) | |
| ret <vscale x 8 x half> %out.legal | |
| } | |
| define <vscale x 8 x bfloat> @repeat_quad_bf16(<8 x bfloat> %a) #0 { | |
| ; CHECK-LABEL: repeat_quad_bf16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 8 x bfloat> @llvm.vector.repeat.nxv8bf16.v8bf16(<8 x bfloat> %a) | |
| ret <vscale x 8 x bfloat> %out | |
| } | |
| define <vscale x 8 x bfloat> @repeat_one_bf16(<4 x bfloat> %a.legal) #0 { | |
| ; CHECK-LABEL: repeat_one_bf16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.h, h0 | |
| ; CHECK-NEXT: ret | |
| %a = call <1 x bfloat> @llvm.vector.extract.v1bf16.v4bf16(<4 x bfloat> %a.legal, i64 0) | |
| %out = call <vscale x 1 x bfloat> @llvm.vector.repeat.nxv1bf16.v1bf16(<1 x bfloat> %a) | |
| %out.legal = call <vscale x 8 x bfloat> @llvm.vector.insert.nxv8bf16.nxv1bf16(<vscale x 8 x bfloat> poison, <vscale x 1 x bfloat> %out, i64 0) | |
| ret <vscale x 8 x bfloat> %out.legal | |
| } | |
| define <vscale x 4 x float> @repeat_quad_f32(<4 x float> %a) { | |
| ; CHECK-LABEL: repeat_quad_f32: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 4 x float> @llvm.vector.repeat.nxv4f32.v4f32(<4 x float> %a) | |
| ret <vscale x 4 x float> %out | |
| } | |
| define <vscale x 2 x float> @repeat_double_f32_to_nxv2f32(<2 x float> %a) { | |
| ; CHECK-LABEL: repeat_double_f32_to_nxv2f32: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.d, d0 | |
| ; CHECK-NEXT: uunpklo z0.d, z0.s | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 2 x float> @llvm.vector.repeat.nxv2f32.v2f32(<2 x float> %a) | |
| ret <vscale x 2 x float> %out | |
| } | |
| define <vscale x 4 x float> @repeat_one_f32(<2 x float> %a.legal) { | |
| ; CHECK-LABEL: repeat_one_f32: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.s, s0 | |
| ; CHECK-NEXT: ret | |
| %a = call <1 x float> @llvm.vector.extract.v1f32.v2f32(<2 x float> %a.legal, i64 0) | |
| %out = call <vscale x 1 x float> @llvm.vector.repeat.nxv1f32.v1f32(<1 x float> %a) | |
| %out.legal = call <vscale x 4 x float> @llvm.vector.insert.nxv4f32.nxv1f32(<vscale x 4 x float> poison, <vscale x 1 x float> %out, i64 0) | |
| ret <vscale x 4 x float> %out.legal | |
| } | |
| define <vscale x 4 x bfloat> @repeat_double_bf16_to_nxv4bf16(<4 x bfloat> %a) #0 { | |
| ; CHECK-LABEL: repeat_double_bf16_to_nxv4bf16: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.d, d0 | |
| ; CHECK-NEXT: uunpklo z0.s, z0.h | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 4 x bfloat> @llvm.vector.repeat.nxv4bf16.v4bf16(<4 x bfloat> %a) | |
| ret <vscale x 4 x bfloat> %out | |
| } | |
| define <vscale x 2 x double> @repeat_quad_f64(<2 x double> %a) { | |
| ; CHECK-LABEL: repeat_quad_f64: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 2 x double> @llvm.vector.repeat.nxv2f64.v2f64(<2 x double> %a) | |
| ret <vscale x 2 x double> %out | |
| } | |
| define <vscale x 2 x double> @repeat_one_f64(<1 x double> %a) { | |
| ; CHECK-LABEL: repeat_one_f64: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: mov z0.d, d0 | |
| ; CHECK-NEXT: ret | |
| %out = call <vscale x 1 x double> @llvm.vector.repeat.nxv1f64.v1f64(<1 x double> %a) | |
| %out.legal = call <vscale x 2 x double> @llvm.vector.insert.nxv2f64.nxv1f64(<vscale x 2 x double> poison, <vscale x 1 x double> %out, i64 0) | |
| ret <vscale x 2 x double> %out.legal | |
| } | |
| ; Predicates | |
| define <vscale x 16 x i1> @repeat_v16i1_to_nxv16i1(<16 x i8> %a) { | |
| ; CHECK-LABEL: repeat_v16i1_to_nxv16i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.b | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.b, z0.b, #0x1 | |
| ; CHECK-NEXT: cmpne p0.b, p0/z, z0.b, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <16 x i8> %a to <16 x i1> | |
| %out = call <vscale x 16 x i1> @llvm.vector.repeat.nxv16i1.v16i1(<16 x i1> %a.legal) | |
| ret <vscale x 16 x i1> %out | |
| } | |
| define <vscale x 16 x i1> @repeat_v8i1_to_nxv16i1(<8 x i8> %a) { | |
| ; CHECK-LABEL: repeat_v8i1_to_nxv16i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.b | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.b, z0.b, #0x1 | |
| ; CHECK-NEXT: cmpne p0.b, p0/z, z0.b, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <8 x i8> %a to <8 x i1> | |
| %tmp = shufflevector <8 x i1> %a.legal, <8 x i1> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> | |
| %out = call <vscale x 16 x i1> @llvm.vector.repeat.nxv16i1.v16i1(<16 x i1> %tmp) | |
| ret <vscale x 16 x i1> %out | |
| } | |
| define <vscale x 8 x i1> @repeat_v8i1_double_to_nxv8i1(<8 x i8> %a) { | |
| ; CHECK-LABEL: repeat_v8i1_double_to_nxv8i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: ushll v0.8h, v0.8b, #0 | |
| ; CHECK-NEXT: ptrue p0.h | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.h, z0.h, #0x1 | |
| ; CHECK-NEXT: cmpne p0.h, p0/z, z0.h, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <8 x i8> %a to <8 x i1> | |
| %out = call <vscale x 8 x i1> @llvm.vector.repeat.nxv8i1.v8i1(<8 x i1> %a.legal) | |
| ret <vscale x 8 x i1> %out | |
| } | |
| define <vscale x 8 x i1> @repeat_v8i1_quad_to_nxv8i1(<8 x i16> %a) { | |
| ; CHECK-LABEL: repeat_v8i1_quad_to_nxv8i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.h | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.h, z0.h, #0x1 | |
| ; CHECK-NEXT: cmpne p0.h, p0/z, z0.h, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <8 x i16> %a to <8 x i1> | |
| %out = call <vscale x 8 x i1> @llvm.vector.repeat.nxv8i1.v8i1(<8 x i1> %a.legal) | |
| ret <vscale x 8 x i1> %out | |
| } | |
| define <vscale x 8 x i1> @repeat_v4i1_double_to_nxv8i1(<4 x i16> %a) { | |
| ; CHECK-LABEL: repeat_v4i1_double_to_nxv8i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.h | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.h, z0.h, #0x1 | |
| ; CHECK-NEXT: cmpne p0.h, p0/z, z0.h, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <4 x i16> %a to <4 x i1> | |
| %tmp = shufflevector <4 x i1> %a.legal, <4 x i1> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3> | |
| %out = call <vscale x 8 x i1> @llvm.vector.repeat.nxv8i1.v8i1(<8 x i1> %tmp) | |
| ret <vscale x 8 x i1> %out | |
| } | |
| define <vscale x 4 x i1> @repeat_v4i1_double_to_nxv4i1(<4 x i16> %a) { | |
| ; CHECK-LABEL: repeat_v4i1_double_to_nxv4i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: ushll v0.4s, v0.4h, #0 | |
| ; CHECK-NEXT: ptrue p0.s | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.s, z0.s, #0x1 | |
| ; CHECK-NEXT: cmpne p0.s, p0/z, z0.s, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <4 x i16> %a to <4 x i1> | |
| %out = call <vscale x 4 x i1> @llvm.vector.repeat.nxv4i1.v4i1(<4 x i1> %a.legal) | |
| ret <vscale x 4 x i1> %out | |
| } | |
| define <vscale x 4 x i1> @repeat_v4i1_quad_to_nxv4i1(<4 x i32> %a) { | |
| ; CHECK-LABEL: repeat_v4i1_quad_to_nxv4i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.s | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.s, z0.s, #0x1 | |
| ; CHECK-NEXT: cmpne p0.s, p0/z, z0.s, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <4 x i32> %a to <4 x i1> | |
| %out = call <vscale x 4 x i1> @llvm.vector.repeat.nxv4i1.v4i1(<4 x i1> %a.legal) | |
| ret <vscale x 4 x i1> %out | |
| } | |
| define <vscale x 4 x i1> @repeat_v2i1_double_to_nxv4i1(<2 x i32> %a) { | |
| ; CHECK-LABEL: repeat_v2i1_double_to_nxv4i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.s | |
| ; CHECK-NEXT: mov v0.d[1], v0.d[0] | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.s, z0.s, #0x1 | |
| ; CHECK-NEXT: cmpne p0.s, p0/z, z0.s, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <2 x i32> %a to <2 x i1> | |
| %tmp = shufflevector <2 x i1> %a.legal, <2 x i1> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1> | |
| %out = call <vscale x 4 x i1> @llvm.vector.repeat.nxv4i1.v4i1(<4 x i1> %tmp) | |
| ret <vscale x 4 x i1> %out | |
| } | |
| define <vscale x 2 x i1> @repeat_v2i1_double_to_nxv2i1(<2 x i32> %a) { | |
| ; CHECK-LABEL: repeat_v2i1_double_to_nxv2i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: ushll v0.2d, v0.2s, #0 | |
| ; CHECK-NEXT: ptrue p0.d | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.d, z0.d, #0x1 | |
| ; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <2 x i32> %a to <2 x i1> | |
| %out = call <vscale x 2 x i1> @llvm.vector.repeat.nxv2i1.v2i1(<2 x i1> %a.legal) | |
| ret <vscale x 2 x i1> %out | |
| } | |
| define <vscale x 2 x i1> @repeat_v2i1_quad_to_nxv2i1(<2 x i64> %a) { | |
| ; CHECK-LABEL: repeat_v2i1_quad_to_nxv2i1: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 | |
| ; CHECK-NEXT: ptrue p0.d | |
| ; CHECK-NEXT: mov z0.q, q0 | |
| ; CHECK-NEXT: and z0.d, z0.d, #0x1 | |
| ; CHECK-NEXT: cmpne p0.d, p0/z, z0.d, #0 | |
| ; CHECK-NEXT: ret | |
| %a.legal = trunc <2 x i64> %a to <2 x i1> | |
| %out = call <vscale x 2 x i1> @llvm.vector.repeat.nxv2i1.v2i1(<2 x i1> %a.legal) | |
| ret <vscale x 2 x i1> %out | |
| } |