| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-IAENABLED | |
| ; RUN: llc -mtriple=aarch64-linux-gnu -lower-interleaved-accesses=false < %s | FileCheck %s --check-prefixes=CHECK,CHECK-IADISABLED | |
| define void @aarch64_vector_deinterleave_idx_ld2(ptr %ptr, i64 %idx) { | |
| ; CHECK-LABEL: aarch64_vector_deinterleave_idx_ld2: | |
| ; CHECK: // %bb.0: // %entry | |
| ; CHECK-NEXT: lsl x8, x1, #2 | |
| ; CHECK-NEXT: and x9, x8, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: add x8, x8, #16 | |
| ; CHECK-NEXT: add x10, x0, x9 | |
| ; CHECK-NEXT: and x8, x8, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: ld2 { v0.4s, v1.4s }, [x10] | |
| ; CHECK-NEXT: str q0, [x0, x9] | |
| ; CHECK-NEXT: str q1, [x0, x8] | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %idx1 = lshr i64 %idx, 2 | |
| %a1 = add i64 %idx, 4 | |
| %idx2 = lshr i64 %a1, 2 | |
| %gep1 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx1 | |
| %gep2 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx2 | |
| %load = load <8 x float>, ptr %gep1, align 16 | |
| %deinterleave = call { <4 x float>, <4 x float> } @llvm.vector.deinterleave2.v8f32(<8 x float> %load) | |
| %m0_3 = extractvalue { <4 x float>, <4 x float> } %deinterleave, 0 | |
| %m4_7 = extractvalue { <4 x float>, <4 x float> } %deinterleave, 1 | |
| store <4 x float> %m0_3, ptr %gep1, align 16 | |
| store <4 x float> %m4_7, ptr %gep2, align 16 | |
| ret void | |
| } | |
| define void @aarch64_vector_deinterleave_idx_ld3(ptr %ptr, i64 %idx) { | |
| ; CHECK-LABEL: aarch64_vector_deinterleave_idx_ld3: | |
| ; CHECK: // %bb.0: // %entry | |
| ; CHECK-NEXT: lsl x8, x1, #2 | |
| ; CHECK-NEXT: and x9, x8, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: add x10, x0, x9 | |
| ; CHECK-NEXT: ld3 { v0.4s, v1.4s, v2.4s }, [x10] | |
| ; CHECK-NEXT: add x10, x8, #16 | |
| ; CHECK-NEXT: add x8, x8, #32 | |
| ; CHECK-NEXT: and x10, x10, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: and x8, x8, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: str q0, [x0, x9] | |
| ; CHECK-NEXT: str q1, [x0, x10] | |
| ; CHECK-NEXT: str q2, [x0, x8] | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %idx1 = lshr i64 %idx, 2 | |
| %a1 = add i64 %idx, 4 | |
| %idx2 = lshr i64 %a1, 2 | |
| %a2 = add i64 %idx, 8 | |
| %idx3 = lshr i64 %a2, 2 | |
| %gep1 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx1 | |
| %gep2 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx2 | |
| %gep3 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx3 | |
| %load = load <12 x float>, ptr %gep1, align 16 | |
| %deinterleave = call { <4 x float>, <4 x float>, <4 x float> } @llvm.vector.deinterleave3.v12f32(<12 x float> %load) | |
| %m0_3 = extractvalue { <4 x float>, <4 x float>, <4 x float> } %deinterleave, 0 | |
| %m4_7 = extractvalue { <4 x float>, <4 x float>, <4 x float> } %deinterleave, 1 | |
| %m8_11 = extractvalue { <4 x float>, <4 x float>, <4 x float> } %deinterleave, 2 | |
| store <4 x float> %m0_3, ptr %gep1, align 16 | |
| store <4 x float> %m4_7, ptr %gep2, align 16 | |
| store <4 x float> %m8_11, ptr %gep3, align 16 | |
| ret void | |
| } | |
| define void @aarch64_vector_deinterleave_idx_ld4(ptr %ptr, i64 %idx) { | |
| ; CHECK-LABEL: aarch64_vector_deinterleave_idx_ld4: | |
| ; CHECK: // %bb.0: // %entry | |
| ; CHECK-NEXT: lsl x8, x1, #2 | |
| ; CHECK-NEXT: add x9, x8, #64 | |
| ; CHECK-NEXT: add x11, x8, #96 | |
| ; CHECK-NEXT: and x9, x9, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: add x10, x0, x9 | |
| ; CHECK-NEXT: ld4 { v0.4s, v1.4s, v2.4s, v3.4s }, [x10] | |
| ; CHECK-NEXT: add x10, x8, #80 | |
| ; CHECK-NEXT: add x8, x8, #112 | |
| ; CHECK-NEXT: and x10, x10, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: and x8, x8, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: str q0, [x0, x9] | |
| ; CHECK-NEXT: and x9, x11, #0xfffffffffffffff0 | |
| ; CHECK-NEXT: str q1, [x0, x10] | |
| ; CHECK-NEXT: str q2, [x0, x9] | |
| ; CHECK-NEXT: str q3, [x0, x8] | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %a1 = add i64 %idx, 16 | |
| %idx1 = lshr i64 %a1, 2 | |
| %a2 = add i64 %idx, 20 | |
| %idx2 = lshr i64 %a2, 2 | |
| %a3 = add i64 %idx, 24 | |
| %idx3 = lshr i64 %a3, 2 | |
| %a4 = add i64 %idx, 28 | |
| %idx4 = lshr i64 %a4, 2 | |
| %gep1 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx1 | |
| %gep2 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx2 | |
| %gep3 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx3 | |
| %gep4 = getelementptr inbounds <4 x float>, ptr %ptr, i64 %idx4 | |
| %load = load <16 x float>, ptr %gep1, align 16 | |
| %deinterleave = call { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @llvm.vector.deinterleave4.v16f32(<16 x float> %load) | |
| %m0_3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 0 | |
| %m4_7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 1 | |
| %m8_11 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 2 | |
| %m12_15 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %deinterleave, 3 | |
| store <4 x float> %m0_3, ptr %gep1, align 16 | |
| store <4 x float> %m4_7, ptr %gep2, align 16 | |
| store <4 x float> %m8_11, ptr %gep3, align 16 | |
| store <4 x float> %m12_15, ptr %gep4, align 16 | |
| ret void | |
| } | |
| define void @aarch64_vector_deinterleave_v8f64_load(ptr %src, ptr %dst0, ptr %dst1) { | |
| ; CHECK-LABEL: aarch64_vector_deinterleave_v8f64_load: | |
| ; CHECK: // %bb.0: // %entry | |
| ; CHECK-NEXT: ld2 { v0.2d, v1.2d }, [x0], #32 | |
| ; CHECK-NEXT: ld2 { v2.2d, v3.2d }, [x0] | |
| ; CHECK-NEXT: stp q0, q2, [x1] | |
| ; CHECK-NEXT: stp q1, q3, [x2] | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %wide.vec = load <8 x double>, ptr %src, align 8 | |
| %strided.vec = tail call { <4 x double>, <4 x double> } @llvm.vector.deinterleave2.v8f64(<8 x double> %wide.vec) | |
| %even = extractvalue { <4 x double>, <4 x double> } %strided.vec, 0 | |
| %odd = extractvalue { <4 x double>, <4 x double> } %strided.vec, 1 | |
| store <4 x double> %even, ptr %dst0, align 8 | |
| store <4 x double> %odd, ptr %dst1, align 8 | |
| ret void | |
| } | |
| define void @aarch64_vector_deinterleave_v12f64_load(ptr %src, ptr %dst0, ptr %dst1, ptr %dst2) { | |
| ; CHECK-LABEL: aarch64_vector_deinterleave_v12f64_load: | |
| ; CHECK: // %bb.0: // %entry | |
| ; CHECK-NEXT: ld3 { v0.2d, v1.2d, v2.2d }, [x0], #48 | |
| ; CHECK-NEXT: ld3 { v3.2d, v4.2d, v5.2d }, [x0] | |
| ; CHECK-NEXT: stp q0, q3, [x1] | |
| ; CHECK-NEXT: stp q1, q4, [x2] | |
| ; CHECK-NEXT: stp q2, q5, [x3] | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %wide.vec = load <12 x double>, ptr %src, align 8 | |
| %strided.vec = tail call { <4 x double>, <4 x double>, <4 x double> } @llvm.vector.deinterleave3.v12f64(<12 x double> %wide.vec) | |
| %stream0 = extractvalue { <4 x double>, <4 x double>, <4 x double> } %strided.vec, 0 | |
| %stream1 = extractvalue { <4 x double>, <4 x double>, <4 x double> } %strided.vec, 1 | |
| %stream2 = extractvalue { <4 x double>, <4 x double>, <4 x double> } %strided.vec, 2 | |
| store <4 x double> %stream0, ptr %dst0, align 8 | |
| store <4 x double> %stream1, ptr %dst1, align 8 | |
| store <4 x double> %stream2, ptr %dst2, align 8 | |
| ret void | |
| } | |
| define void @aarch64_vector_deinterleave_v16f64_load(ptr %src, ptr %dst0, ptr %dst1, ptr %dst2, ptr %dst3) { | |
| ; CHECK-LABEL: aarch64_vector_deinterleave_v16f64_load: | |
| ; CHECK: // %bb.0: // %entry | |
| ; CHECK-NEXT: ld4 { v0.2d, v1.2d, v2.2d, v3.2d }, [x0], #64 | |
| ; CHECK-NEXT: ld4 { v4.2d, v5.2d, v6.2d, v7.2d }, [x0] | |
| ; CHECK-NEXT: stp q0, q4, [x1] | |
| ; CHECK-NEXT: stp q1, q5, [x2] | |
| ; CHECK-NEXT: stp q2, q6, [x3] | |
| ; CHECK-NEXT: stp q3, q7, [x4] | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %wide.vec = load <16 x double>, ptr %src, align 8 | |
| %strided.vec = tail call { <4 x double>, <4 x double>, <4 x double>, <4 x double> } @llvm.vector.deinterleave4.v16f64(<16 x double> %wide.vec) | |
| %stream0 = extractvalue { <4 x double>, <4 x double>, <4 x double>, <4 x double> } %strided.vec, 0 | |
| %stream1 = extractvalue { <4 x double>, <4 x double>, <4 x double>, <4 x double> } %strided.vec, 1 | |
| %stream2 = extractvalue { <4 x double>, <4 x double>, <4 x double>, <4 x double> } %strided.vec, 2 | |
| %stream3 = extractvalue { <4 x double>, <4 x double>, <4 x double>, <4 x double> } %strided.vec, 3 | |
| store <4 x double> %stream0, ptr %dst0, align 8 | |
| store <4 x double> %stream1, ptr %dst1, align 8 | |
| store <4 x double> %stream2, ptr %dst2, align 8 | |
| store <4 x double> %stream3, ptr %dst3, align 8 | |
| ret void | |
| } | |
| ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | |
| ; CHECK-IADISABLED: {{.*}} | |
| ; CHECK-IAENABLED: {{.*}} |