| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s | |
| define <vscale x 8 x i32> @interleave_of_deinterleave_f2(<vscale x 8 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_f2( | |
| ; CHECK-NEXT: ret <vscale x 8 x i32> [[X:%.*]] | |
| ; | |
| %d = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> %x) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 1 | |
| %r = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> %e0, <vscale x 4 x i32> %e1) | |
| ret <vscale x 8 x i32> %r | |
| } | |
| define <vscale x 16 x i32> @interleave_of_deinterleave_f4(<vscale x 16 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_f4( | |
| ; CHECK-NEXT: ret <vscale x 16 x i32> [[X:%.*]] | |
| ; | |
| %d = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave4.nxv16i32(<vscale x 16 x i32> %x) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 1 | |
| %e2 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 2 | |
| %e3 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 3 | |
| %r = call <vscale x 16 x i32> @llvm.vector.interleave4.nxv16i32(<vscale x 4 x i32> %e0, <vscale x 4 x i32> %e1, <vscale x 4 x i32> %e2, <vscale x 4 x i32> %e3) | |
| ret <vscale x 16 x i32> %r | |
| } | |
| define <vscale x 20 x i32> @interleave_of_deinterleave_f5(<vscale x 20 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_f5( | |
| ; CHECK-NEXT: ret <vscale x 20 x i32> [[X:%.*]] | |
| ; | |
| %d = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave5.nxv20i32(<vscale x 20 x i32> %x) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 1 | |
| %e2 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 2 | |
| %e3 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 3 | |
| %e4 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 4 | |
| %r = call <vscale x 20 x i32> @llvm.vector.interleave5.nxv20i32(<vscale x 4 x i32> %e0, <vscale x 4 x i32> %e1, <vscale x 4 x i32> %e2, <vscale x 4 x i32> %e3, <vscale x 4 x i32> %e4) | |
| ret <vscale x 20 x i32> %r | |
| } | |
| define void @interleave_of_deinterleave_load_store(ptr %src, ptr %dst) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_load_store( | |
| ; CHECK-NEXT: [[V:%.*]] = load <vscale x 8 x i32>, ptr [[SRC:%.*]], align 32 | |
| ; CHECK-NEXT: store <vscale x 8 x i32> [[V]], ptr [[DST:%.*]], align 32 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %v = load <vscale x 8 x i32>, ptr %src | |
| %d = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> %v) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 1 | |
| %r = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> %e0, <vscale x 4 x i32> %e1) | |
| store <vscale x 8 x i32> %r, ptr %dst | |
| ret void | |
| } | |
| define <vscale x 8 x i32> @interleave_of_deinterleave_extra_uses(<vscale x 8 x i32> %x, ptr %p0, ptr %p1) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_extra_uses( | |
| ; CHECK-NEXT: [[D:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } [[D]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } [[D]], 1 | |
| ; CHECK-NEXT: store <vscale x 4 x i32> [[E0]], ptr [[P0:%.*]], align 16 | |
| ; CHECK-NEXT: store <vscale x 4 x i32> [[E1]], ptr [[P1:%.*]], align 16 | |
| ; CHECK-NEXT: ret <vscale x 8 x i32> [[X]] | |
| ; | |
| %d = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> %x) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 1 | |
| store <vscale x 4 x i32> %e0, ptr %p0 | |
| store <vscale x 4 x i32> %e1, ptr %p1 | |
| %r = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> %e0, <vscale x 4 x i32> %e1) | |
| ret <vscale x 8 x i32> %r | |
| } | |
| define <vscale x 8 x i32> @interleave_of_deinterleave_swapped(<vscale x 8 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_swapped( | |
| ; CHECK-NEXT: [[D:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } [[D]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } [[D]], 1 | |
| ; CHECK-NEXT: [[R:%.*]] = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> [[E1]], <vscale x 4 x i32> [[E0]]) | |
| ; CHECK-NEXT: ret <vscale x 8 x i32> [[R]] | |
| ; | |
| %d = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> %x) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %d, 1 | |
| %r = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> %e1, <vscale x 4 x i32> %e0) | |
| ret <vscale x 8 x i32> %r | |
| } | |
| define <vscale x 8 x i32> @interleave_of_two_deinterleaves(<vscale x 8 x i32> %x, <vscale x 8 x i32> %y) { | |
| ; CHECK-LABEL: @interleave_of_two_deinterleaves( | |
| ; CHECK-NEXT: [[DX:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[DY:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> [[Y:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } [[DX]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } [[DY]], 1 | |
| ; CHECK-NEXT: [[R:%.*]] = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> [[E0]], <vscale x 4 x i32> [[E1]]) | |
| ; CHECK-NEXT: ret <vscale x 8 x i32> [[R]] | |
| ; | |
| %dx = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> %x) | |
| %dy = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> %y) | |
| %e0 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %dx, 0 | |
| %e1 = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32> } %dy, 1 | |
| %r = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> %e0, <vscale x 4 x i32> %e1) | |
| ret <vscale x 8 x i32> %r | |
| } | |
| define <vscale x 8 x i32> @interleave_of_deinterleave_mismatched_factor(<vscale x 8 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_mismatched_factor( | |
| ; CHECK-NEXT: [[D:%.*]] = call { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } @llvm.vector.deinterleave4.nxv8i32(<vscale x 8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } [[D]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } [[D]], 1 | |
| ; CHECK-NEXT: [[R:%.*]] = call <vscale x 4 x i32> @llvm.vector.interleave2.nxv4i32(<vscale x 2 x i32> [[E0]], <vscale x 2 x i32> [[E1]]) | |
| ; CHECK-NEXT: [[W:%.*]] = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> [[R]], <vscale x 4 x i32> [[R]]) | |
| ; CHECK-NEXT: ret <vscale x 8 x i32> [[W]] | |
| ; | |
| %d = call { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } @llvm.vector.deinterleave4.nxv8i32(<vscale x 8 x i32> %x) | |
| %e0 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %d, 0 | |
| %e1 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %d, 1 | |
| %r = call <vscale x 4 x i32> @llvm.vector.interleave2.nxv4i32(<vscale x 2 x i32> %e0, <vscale x 2 x i32> %e1) | |
| %w = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> %r, <vscale x 4 x i32> %r) | |
| ret <vscale x 8 x i32> %w | |
| } | |
| define <8 x i32> @interleave_of_deinterleave_fixed_f2(<8 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_fixed_f2( | |
| ; CHECK-NEXT: ret <8 x i32> [[X:%.*]] | |
| ; | |
| %d = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %x) | |
| %e0 = extractvalue { <4 x i32>, <4 x i32> } %d, 0 | |
| %e1 = extractvalue { <4 x i32>, <4 x i32> } %d, 1 | |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %e0, <4 x i32> %e1) | |
| ret <8 x i32> %r | |
| } | |
| define <16 x i32> @interleave_of_deinterleave_fixed_f4(<16 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_fixed_f4( | |
| ; CHECK-NEXT: ret <16 x i32> [[X:%.*]] | |
| ; | |
| %d = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.vector.deinterleave4.v16i32(<16 x i32> %x) | |
| %e0 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %d, 0 | |
| %e1 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %d, 1 | |
| %e2 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %d, 2 | |
| %e3 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %d, 3 | |
| %r = call <16 x i32> @llvm.vector.interleave4.v16i32(<4 x i32> %e0, <4 x i32> %e1, <4 x i32> %e2, <4 x i32> %e3) | |
| ret <16 x i32> %r | |
| } | |
| define void @interleave_of_deinterleave_fixed_load_store(ptr %src, ptr %dst) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_fixed_load_store( | |
| ; CHECK-NEXT: [[V:%.*]] = load <8 x i32>, ptr [[SRC:%.*]], align 32 | |
| ; CHECK-NEXT: store <8 x i32> [[V]], ptr [[DST:%.*]], align 32 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %v = load <8 x i32>, ptr %src | |
| %d = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %v) | |
| %e0 = extractvalue { <4 x i32>, <4 x i32> } %d, 0 | |
| %e1 = extractvalue { <4 x i32>, <4 x i32> } %d, 1 | |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %e0, <4 x i32> %e1) | |
| store <8 x i32> %r, ptr %dst | |
| ret void | |
| } | |
| define <8 x i32> @interleave_of_deinterleave_fixed_extra_uses(<8 x i32> %x, ptr %p0, ptr %p1) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_fixed_extra_uses( | |
| ; CHECK-NEXT: [[D:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[D]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[D]], 1 | |
| ; CHECK-NEXT: store <4 x i32> [[E0]], ptr [[P0:%.*]], align 16 | |
| ; CHECK-NEXT: store <4 x i32> [[E1]], ptr [[P1:%.*]], align 16 | |
| ; CHECK-NEXT: ret <8 x i32> [[X]] | |
| ; | |
| %d = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %x) | |
| %e0 = extractvalue { <4 x i32>, <4 x i32> } %d, 0 | |
| %e1 = extractvalue { <4 x i32>, <4 x i32> } %d, 1 | |
| store <4 x i32> %e0, ptr %p0 | |
| store <4 x i32> %e1, ptr %p1 | |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %e0, <4 x i32> %e1) | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @interleave_of_deinterleave_fixed_swapped(<8 x i32> %x) { | |
| ; CHECK-LABEL: @interleave_of_deinterleave_fixed_swapped( | |
| ; CHECK-NEXT: [[D:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[D]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[D]], 1 | |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> [[E1]], <4 x i32> [[E0]]) | |
| ; CHECK-NEXT: ret <8 x i32> [[R]] | |
| ; | |
| %d = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %x) | |
| %e0 = extractvalue { <4 x i32>, <4 x i32> } %d, 0 | |
| %e1 = extractvalue { <4 x i32>, <4 x i32> } %d, 1 | |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %e1, <4 x i32> %e0) | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @interleave_of_two_deinterleaves_fixed(<8 x i32> %x, <8 x i32> %y) { | |
| ; CHECK-LABEL: @interleave_of_two_deinterleaves_fixed( | |
| ; CHECK-NEXT: [[DX:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[X:%.*]]) | |
| ; CHECK-NEXT: [[DY:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[Y:%.*]]) | |
| ; CHECK-NEXT: [[E0:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DX]], 0 | |
| ; CHECK-NEXT: [[E1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DY]], 1 | |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> [[E0]], <4 x i32> [[E1]]) | |
| ; CHECK-NEXT: ret <8 x i32> [[R]] | |
| ; | |
| %dx = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %x) | |
| %dy = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %y) | |
| %e0 = extractvalue { <4 x i32>, <4 x i32> } %dx, 0 | |
| %e1 = extractvalue { <4 x i32>, <4 x i32> } %dy, 1 | |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %e0, <4 x i32> %e1) | |
| ret <8 x i32> %r | |
| } |