| ; 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 |
| } |