| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -mtriple=armv8-none-eabihf -mattr=+neon,+fullfp16 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-IAENABLED | |
| ; RUN: llc -mtriple=armv8-none-eabihf -mattr=+neon,+fullfp16 -lower-interleaved-accesses=false -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-IADISABLED | |
| define void @arm_vector_deinterleave_idx_ld2(ptr %src) { | |
| ; CHECK-LABEL: arm_vector_deinterleave_idx_ld2: | |
| ; CHECK: @ %bb.0: @ %entry | |
| ; CHECK-NEXT: vld2.32 {d16, d17, d18, d19}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 $q8_q9 | |
| ; CHECK-NEXT: bx lr | |
| entry: | |
| %load = load <8 x float>, ptr %src | |
| %deinterleave = call { <4 x float>, <4 x float> } @llvm.vector.deinterleave2.v8f32(<8 x float> %load) | |
| %f0 = extractvalue { <4 x float>, <4 x float> } %deinterleave, 0 | |
| %f1 = extractvalue { <4 x float>, <4 x float> } %deinterleave, 1 | |
| call void (...) @llvm.fake.use(<4 x float> %f0) | |
| call void (...) @llvm.fake.use(<4 x float> %f1) | |
| ret void | |
| } | |
| define void @arm_vector_deinterleave_idx_ld3(ptr %src) { | |
| ; CHECK-LABEL: arm_vector_deinterleave_idx_ld3: | |
| ; CHECK: @ %bb.0: @ %entry | |
| ; CHECK-NEXT: vld3.32 {d16, d18, d20}, [r0:64]! | |
| ; CHECK-NEXT: vld3.32 {d17, d19, d21}, [r0:64] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| entry: | |
| %load = load <12 x float>, ptr %src | |
| %deinterleave = call { <4 x float>, <4 x float>, <4 x float> } @llvm.vector.deinterleave3.v12f32(<12 x float> %load) | |
| %f0 = extractvalue { <4 x float>, <4 x float>, <4 x float> } %deinterleave, 0 | |
| %f1 = extractvalue { <4 x float>, <4 x float>, <4 x float> } %deinterleave, 1 | |
| %f2 = extractvalue { <4 x float>, <4 x float>, <4 x float> } %deinterleave, 2 | |
| call void (...) @llvm.fake.use(<4 x float> %f0) | |
| call void (...) @llvm.fake.use(<4 x float> %f1) | |
| call void (...) @llvm.fake.use(<4 x float> %f2) | |
| ret void | |
| } | |
| define void @arm_vector_deinterleave_idx_ld4(ptr %src) { | |
| ; CHECK-LABEL: arm_vector_deinterleave_idx_ld4: | |
| ; CHECK: @ %bb.0: @ %entry | |
| ; CHECK-NEXT: vld4.32 {d16, d18, d20, d22}, [r0:256]! | |
| ; CHECK-NEXT: vld4.32 {d17, d19, d21, d23}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| entry: | |
| %load = load <16 x float>, ptr %src | |
| %deinterleave = call { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @llvm.vector.deinterleave4.v16f32(<16 x float> %load) | |
| %f0 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 0 | |
| %f1 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 1 | |
| %f2 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 2 | |
| %f3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<4 x float> %f0) | |
| call void (...) @llvm.fake.use(<4 x float> %f1) | |
| call void (...) @llvm.fake.use(<4 x float> %f2) | |
| call void (...) @llvm.fake.use(<4 x float> %f3) | |
| ret void | |
| } | |
| define void @factor2_v4i32(ptr %src) { | |
| ; CHECK-LABEL: factor2_v4i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld2.32 {d16, d17, d18, d19}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 $q8_q9 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <8 x i32>, ptr %src | |
| %deinterleave = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %load) | |
| %v0 = extractvalue { <4 x i32>, <4 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <4 x i32>, <4 x i32> } %deinterleave, 1 | |
| call void (...) @llvm.fake.use(<4 x i32> %v0) | |
| call void (...) @llvm.fake.use(<4 x i32> %v1) | |
| ret void | |
| } | |
| define void @factor3_v2i32(ptr %src) { | |
| ; CHECK-LABEL: factor3_v2i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld3.32 {d16, d17, d18}, [r0:64] | |
| ; CHECK-NEXT: @ fake_use: $d16 | |
| ; CHECK-NEXT: @ fake_use: $d17 | |
| ; CHECK-NEXT: @ fake_use: $d18 $q8_q9 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <6 x i32>, ptr %src | |
| %deinterleave = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.vector.deinterleave3.v6i32(<6 x i32> %load) | |
| %v0 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 1 | |
| %v2 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 2 | |
| call void (...) @llvm.fake.use(<2 x i32> %v0) | |
| call void (...) @llvm.fake.use(<2 x i32> %v1) | |
| call void (...) @llvm.fake.use(<2 x i32> %v2) | |
| ret void | |
| } | |
| define void @factor3_v4i32(ptr %src) { | |
| ; CHECK-LABEL: factor3_v4i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld3.32 {d16, d18, d20}, [r0:64]! | |
| ; CHECK-NEXT: vld3.32 {d17, d19, d21}, [r0:64] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <12 x i32>, ptr %src | |
| %deinterleave = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.vector.deinterleave3.v12i32(<12 x i32> %load) | |
| %v0 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 1 | |
| %v2 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 2 | |
| call void (...) @llvm.fake.use(<4 x i32> %v0) | |
| call void (...) @llvm.fake.use(<4 x i32> %v1) | |
| call void (...) @llvm.fake.use(<4 x i32> %v2) | |
| ret void | |
| } | |
| define void @factor3_v8i32(ptr %src) { | |
| ; CHECK-LABEL: factor3_v8i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld3.32 {d16, d18, d20}, [r0]! | |
| ; CHECK-NEXT: vld3.32 {d17, d19, d21}, [r0]! | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: vld3.32 {d24, d26, d28}, [r0]! | |
| ; CHECK-NEXT: vld3.32 {d25, d27, d29}, [r0] | |
| ; CHECK-NEXT: @ fake_use: $q12 | |
| ; CHECK-NEXT: vorr q12, q13, q13 | |
| ; CHECK-NEXT: @ fake_use: $q12 | |
| ; CHECK-NEXT: vorr q0, q14, q14 | |
| ; CHECK-NEXT: @ fake_use: $q0 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <24 x i32>, ptr %src, align 4 | |
| %deinterleave = call { <8 x i32>, <8 x i32>, <8 x i32> } @llvm.vector.deinterleave3.v24i32(<24 x i32> %load) | |
| %v0 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 1 | |
| %v2 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 2 | |
| call void (...) @llvm.fake.use(<8 x i32> %v0) | |
| call void (...) @llvm.fake.use(<8 x i32> %v1) | |
| call void (...) @llvm.fake.use(<8 x i32> %v2) | |
| ret void | |
| } | |
| define void @factor4_v2i32(ptr %src) { | |
| ; CHECK-LABEL: factor4_v2i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.32 {d16, d17, d18, d19}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $d16 | |
| ; CHECK-NEXT: @ fake_use: $d17 | |
| ; CHECK-NEXT: @ fake_use: $d18 | |
| ; CHECK-NEXT: @ fake_use: $d19 $q8_q9 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <8 x i32>, ptr %src | |
| %deinterleave = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.vector.deinterleave4.v8i32(<8 x i32> %load) | |
| %v0 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 1 | |
| %v2 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 2 | |
| %v3 = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<2 x i32> %v0) | |
| call void (...) @llvm.fake.use(<2 x i32> %v1) | |
| call void (...) @llvm.fake.use(<2 x i32> %v2) | |
| call void (...) @llvm.fake.use(<2 x i32> %v3) | |
| ret void | |
| } | |
| define void @factor4_v4i32(ptr %src) { | |
| ; CHECK-LABEL: factor4_v4i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.32 {d16, d18, d20, d22}, [r0:256]! | |
| ; CHECK-NEXT: vld4.32 {d17, d19, d21, d23}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <16 x i32>, ptr %src | |
| %deinterleave = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.vector.deinterleave4.v16i32(<16 x i32> %load) | |
| %v0 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 1 | |
| %v2 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 2 | |
| %v3 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<4 x i32> %v0) | |
| call void (...) @llvm.fake.use(<4 x i32> %v1) | |
| call void (...) @llvm.fake.use(<4 x i32> %v2) | |
| call void (...) @llvm.fake.use(<4 x i32> %v3) | |
| ret void | |
| } | |
| define void @factor4_v8i32(ptr %src) { | |
| ; CHECK-LABEL: factor4_v8i32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.32 {d16, d18, d20, d22}, [r0:256]! | |
| ; CHECK-NEXT: vld4.32 {d17, d19, d21, d23}, [r0:256]! | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: vld4.32 {d24, d26, d28, d30}, [r0:256]! | |
| ; CHECK-NEXT: vld4.32 {d25, d27, d29, d31}, [r0:256] | |
| ; CHECK-NEXT: vorr q0, q12, q12 | |
| ; CHECK-NEXT: @ fake_use: $q0 | |
| ; CHECK-NEXT: vorr q0, q15, q15 | |
| ; CHECK-NEXT: @ fake_use: $q0 | |
| ; CHECK-NEXT: vorr q1, q14, q14 | |
| ; CHECK-NEXT: @ fake_use: $q1 | |
| ; CHECK-NEXT: vorr q12, q13, q13 | |
| ; CHECK-NEXT: @ fake_use: $q12 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <32 x i32>, ptr %src | |
| %deinterleave = call { <8 x i32>, <8 x i32>, <8 x i32>, <8 x i32> } @llvm.vector.deinterleave4.v32i32(<32 x i32> %load) | |
| %v0 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 0 | |
| %v1 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 1 | |
| %v2 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 2 | |
| %v3 = extractvalue { <8 x i32>, <8 x i32>, <8 x i32>, <8 x i32> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<8 x i32> %v0) | |
| call void (...) @llvm.fake.use(<8 x i32> %v1) | |
| call void (...) @llvm.fake.use(<8 x i32> %v2) | |
| call void (...) @llvm.fake.use(<8 x i32> %v3) | |
| ret void | |
| } | |
| define void @factor4_v16i8(ptr %src) { | |
| ; CHECK-LABEL: factor4_v16i8: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.8 {d16, d18, d20, d22}, [r0:256]! | |
| ; CHECK-NEXT: vld4.8 {d17, d19, d21, d23}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <64 x i8>, ptr %src | |
| %deinterleave = call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.vector.deinterleave4.v64i8(<64 x i8> %load) | |
| %v0 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %deinterleave, 0 | |
| %v1 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %deinterleave, 1 | |
| %v2 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %deinterleave, 2 | |
| %v3 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<16 x i8> %v0) | |
| call void (...) @llvm.fake.use(<16 x i8> %v1) | |
| call void (...) @llvm.fake.use(<16 x i8> %v2) | |
| call void (...) @llvm.fake.use(<16 x i8> %v3) | |
| ret void | |
| } | |
| define void @factor4_v8i16(ptr %src) { | |
| ; CHECK-LABEL: factor4_v8i16: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.16 {d16, d18, d20, d22}, [r0:256]! | |
| ; CHECK-NEXT: vld4.16 {d17, d19, d21, d23}, [r0:256] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <32 x i16>, ptr %src | |
| %deinterleave = call { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.vector.deinterleave4.v32i16(<32 x i16> %load) | |
| %v0 = extractvalue { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deinterleave, 0 | |
| %v1 = extractvalue { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deinterleave, 1 | |
| %v2 = extractvalue { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deinterleave, 2 | |
| %v3 = extractvalue { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<8 x i16> %v0) | |
| call void (...) @llvm.fake.use(<8 x i16> %v1) | |
| call void (...) @llvm.fake.use(<8 x i16> %v2) | |
| call void (...) @llvm.fake.use(<8 x i16> %v3) | |
| ret void | |
| } | |
| define void @factor4_v8f16(ptr %src) { | |
| ; CHECK-LABEL: factor4_v8f16: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.16 {d16, d18, d20, d22}, [r0]! | |
| ; CHECK-NEXT: vld4.16 {d17, d19, d21, d23}, [r0] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <32 x half>, ptr %src, align 2 | |
| %deinterleave = call { <8 x half>, <8 x half>, <8 x half>, <8 x half> } @llvm.vector.deinterleave4.v32f16(<32 x half> %load) | |
| %v0 = extractvalue { <8 x half>, <8 x half>, <8 x half>, <8 x half> } %deinterleave, 0 | |
| %v1 = extractvalue { <8 x half>, <8 x half>, <8 x half>, <8 x half> } %deinterleave, 1 | |
| %v2 = extractvalue { <8 x half>, <8 x half>, <8 x half>, <8 x half> } %deinterleave, 2 | |
| %v3 = extractvalue { <8 x half>, <8 x half>, <8 x half>, <8 x half> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<8 x half> %v0) | |
| call void (...) @llvm.fake.use(<8 x half> %v1) | |
| call void (...) @llvm.fake.use(<8 x half> %v2) | |
| call void (...) @llvm.fake.use(<8 x half> %v3) | |
| ret void | |
| } | |
| define void @factor4_v4f32(ptr %src) { | |
| ; CHECK-LABEL: factor4_v4f32: | |
| ; CHECK: @ %bb.0: | |
| ; CHECK-NEXT: vld4.32 {d16, d18, d20, d22}, [r0]! | |
| ; CHECK-NEXT: vld4.32 {d17, d19, d21, d23}, [r0] | |
| ; CHECK-NEXT: @ fake_use: $q8 | |
| ; CHECK-NEXT: @ fake_use: $q9 | |
| ; CHECK-NEXT: @ fake_use: $q10 | |
| ; CHECK-NEXT: @ fake_use: $q11 $q8_q9_q10_q11 | |
| ; CHECK-NEXT: bx lr | |
| %load = load <16 x float>, ptr %src, align 4 | |
| %deinterleave = call { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @llvm.vector.deinterleave4.v16f32(<16 x float> %load) | |
| %v0 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 0 | |
| %v1 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 1 | |
| %v2 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 2 | |
| %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 3 | |
| call void (...) @llvm.fake.use(<4 x float> %v0) | |
| call void (...) @llvm.fake.use(<4 x float> %v1) | |
| call void (...) @llvm.fake.use(<4 x float> %v2) | |
| call void (...) @llvm.fake.use(<4 x float> %v3) | |
| ret void | |
| } | |
| ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | |
| ; CHECK-IADISABLED: {{.*}} | |
| ; CHECK-IAENABLED: {{.*}} |