blob: 6e3b8beb1e52fcc6bd7cb6e22b8afc937ae331a6 [file] [edit]
; 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
}