Files
TheRock/compiler/amd-llvm/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

616 lines
23 KiB
YAML

# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -o - -mtriple=aarch64-unknown-unknown -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s | FileCheck %s
# Simple unmerge(merge) case with two operands.
# The sources of the merge can be used in place of
# the destinations of the unmerge.
---
name: test_combine_unmerge_merge
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_merge
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %2(s64)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
...
# Simple unmerge(merge) case with three operands.
# The sources of the merge can be used in place of
# the destinations of the unmerge.
---
name: test_combine_unmerge_merge_3ops
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_merge_3ops
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
; CHECK-NEXT: $w2 = COPY [[DEF2]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%5:_(s32) = G_IMPLICIT_DEF
%2:_(s96) = G_MERGE_VALUES %0(s32), %1(s32), %5(s32)
%3:_(s32), %4:_(s32), %6:_(s32) = G_UNMERGE_VALUES %2(s96)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
$w2 = COPY %6(s32)
...
# Simple unmerge(buildvector) case with two operands.
# The sources of the buildvector can be used in place of
# the destinations of the unmerge.
---
name: test_combine_unmerge_build_vector
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_build_vector
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%2:_(<2 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32)
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %2(<2 x s32>)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
...
# Simple unmerge(buildvector) case with three operands.
# The sources of the buildvector can be used in place of
# the destinations of the unmerge.
---
name: test_combine_unmerge_buildvector_3ops
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_buildvector_3ops
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
; CHECK-NEXT: $w2 = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%5:_(s32) = G_IMPLICIT_DEF
%2:_(<3 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %5(s32)
%3:_(s32), %4:_(s32), %6:_(s32) = G_UNMERGE_VALUES %2(<3 x s32>)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
$w2 = COPY %6(s32)
...
# Simple unmerge(concatvectors) case.
# The sources of the concatvectors can be used in place of
# the destinations of the unmerge.
---
name: test_combine_unmerge_concat_vectors
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_concat_vectors
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY $w1
; CHECK-NEXT: $w0 = COPY [[COPY]](<2 x s16>)
; CHECK-NEXT: $w1 = COPY [[COPY1]](<2 x s16>)
%0:_(<2 x s16>) = COPY $w0
%1:_(<2 x s16>) = COPY $w1
%2:_(<4 x s16>) = G_CONCAT_VECTORS %0(<2 x s16>), %1(<2 x s16>)
%3:_(<2 x s16>), %4:_(<2 x s16>) = G_UNMERGE_VALUES %2(<4 x s16>)
$w0 = COPY %3(<2 x s16>)
$w1 = COPY %4(<2 x s16>)
...
# Unmerge(merge) case with two operands and a bitcast in the middle.
# The sources of the merge can be used in place of
# the destinations of the unmerge.
---
name: test_combine_unmerge_bitcast_merge
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_bitcast_merge
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
%5:_(<2 x s32>) = G_BITCAST %2(s64)
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %5(<2 x s32>)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
...
# Unmerge(merge) with incompatible types: unmerge destTy != merge inputTy.
# The sources of the merge cannot be used in place of
# the destinations of the unmerge, since the types don't match.
---
name: test_combine_unmerge_merge_incompatible_types
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_merge_incompatible_types
; CHECK: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; CHECK-NEXT: $h0 = COPY [[DEF]](s16)
; CHECK-NEXT: $h1 = COPY [[DEF]](s16)
; CHECK-NEXT: $h2 = COPY [[DEF]](s16)
; CHECK-NEXT: $h3 = COPY [[DEF]](s16)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
%3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %2(s64)
$h0 = COPY %3(s16)
$h1 = COPY %4(s16)
$h2 = COPY %5(s16)
$h3 = COPY %6(s16)
...
# Unmerge(concatvectors) with incompatible types: unmerge destTy != merge inputTy
# but destTy.size() == inputTy.size().
# The sources of the concatvectors can be used in place of
# the destinations of the unmerge with a bitcast since the sizes
# match.
---
name: test_combine_unmerge_merge_incompatible_types_but_same_size
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_merge_incompatible_types_but_same_size
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY $w1
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(s32) = G_BITCAST [[COPY1]](<2 x s16>)
; CHECK-NEXT: $w0 = COPY [[BITCAST]](s32)
; CHECK-NEXT: $w1 = COPY [[BITCAST1]](s32)
%0:_(<2 x s16>) = COPY $w0
%1:_(<2 x s16>) = COPY $w1
%2:_(<4 x s16>) = G_CONCAT_VECTORS %0(<2 x s16>), %1(<2 x s16>)
%5:_(s64) = G_BITCAST %2(<4 x s16>)
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %5(s64)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
...
# Unmerge a constant into a bunch of smaller constant.
# Constant is 0x0102030405060708090a0b0c0d0e0f10 and we break it down into
# bytes:
# cst1 0x10
# cst2 0x0f
# cst3 0x0e
# ...
---
name: test_combine_unmerge_cst
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_cst
; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 16
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 15
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s8) = G_CONSTANT i8 14
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s8) = G_CONSTANT i8 13
; CHECK-NEXT: [[C4:%[0-9]+]]:_(s8) = G_CONSTANT i8 12
; CHECK-NEXT: [[C5:%[0-9]+]]:_(s8) = G_CONSTANT i8 11
; CHECK-NEXT: [[C6:%[0-9]+]]:_(s8) = G_CONSTANT i8 10
; CHECK-NEXT: [[C7:%[0-9]+]]:_(s8) = G_CONSTANT i8 9
; CHECK-NEXT: [[C8:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
; CHECK-NEXT: [[C9:%[0-9]+]]:_(s8) = G_CONSTANT i8 7
; CHECK-NEXT: [[C10:%[0-9]+]]:_(s8) = G_CONSTANT i8 6
; CHECK-NEXT: [[C11:%[0-9]+]]:_(s8) = G_CONSTANT i8 5
; CHECK-NEXT: [[C12:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
; CHECK-NEXT: [[C13:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
; CHECK-NEXT: [[C14:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
; CHECK-NEXT: [[C15:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
; CHECK-NEXT: $b0 = COPY [[C]](s8)
; CHECK-NEXT: $b1 = COPY [[C1]](s8)
; CHECK-NEXT: $b2 = COPY [[C2]](s8)
; CHECK-NEXT: $b3 = COPY [[C3]](s8)
; CHECK-NEXT: $b4 = COPY [[C4]](s8)
; CHECK-NEXT: $b5 = COPY [[C5]](s8)
; CHECK-NEXT: $b6 = COPY [[C6]](s8)
; CHECK-NEXT: $b7 = COPY [[C7]](s8)
; CHECK-NEXT: $b8 = COPY [[C8]](s8)
; CHECK-NEXT: $b9 = COPY [[C9]](s8)
; CHECK-NEXT: $b10 = COPY [[C10]](s8)
; CHECK-NEXT: $b11 = COPY [[C11]](s8)
; CHECK-NEXT: $b12 = COPY [[C12]](s8)
; CHECK-NEXT: $b13 = COPY [[C13]](s8)
; CHECK-NEXT: $b14 = COPY [[C14]](s8)
; CHECK-NEXT: $b15 = COPY [[C15]](s8)
%0:_(s128) = G_CONSTANT i128 1339673755198158349044581307228491536
%1:_(s8),%2:_(s8),%3:_(s8),%4:_(s8),%5:_(s8),%6:_(s8),%7:_(s8),%8:_(s8),%9:_(s8),%10:_(s8),%11:_(s8),%12:_(s8),%13:_(s8),%14:_(s8),%15:_(s8),%16:_(s8) = G_UNMERGE_VALUES %0(s128)
$b0 = COPY %1(s8)
$b1 = COPY %2(s8)
$b2 = COPY %3(s8)
$b3 = COPY %4(s8)
$b4 = COPY %5(s8)
$b5 = COPY %6(s8)
$b6 = COPY %7(s8)
$b7 = COPY %8(s8)
$b8 = COPY %9(s8)
$b9 = COPY %10(s8)
$b10 = COPY %11(s8)
$b11 = COPY %12(s8)
$b12 = COPY %13(s8)
$b13 = COPY %14(s8)
$b14 = COPY %15(s8)
$b15 = COPY %16(s8)
...
# Unmerge a constant on a non-power of 2 type into a bunch of smaller constant.
# Constant is a 3 | 2 | 1 in chunks of 13-bit.
---
name: test_combine_unmerge_cst_36bit
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_cst_36bit
; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3
; CHECK-NEXT: $h0 = COPY [[C]](s16)
; CHECK-NEXT: $h1 = COPY [[C1]](s16)
; CHECK-NEXT: $h2 = COPY [[C2]](s16)
%0:_(s39) = G_CONSTANT i39 201342977
%1:_(s13),%2:_(s13),%3:_(s13) = G_UNMERGE_VALUES %0(s39)
%4:_(s16) = G_ZEXT %1(s13)
%5:_(s16) = G_ZEXT %2(s13)
%6:_(s16) = G_ZEXT %3(s13)
$h0 = COPY %4(s16)
$h1 = COPY %5(s16)
$h2 = COPY %6(s16)
...
# Unmerge floating point constant.
---
name: test_combine_unmerge_fpcst
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_fpcst
; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
; CHECK-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3
; CHECK-NEXT: [[C3:%[0-9]+]]:_(s16) = G_CONSTANT i16 4
; CHECK-NEXT: $h0 = COPY [[C]](s16)
; CHECK-NEXT: $h1 = COPY [[C1]](s16)
; CHECK-NEXT: $h2 = COPY [[C2]](s16)
; CHECK-NEXT: $h3 = COPY [[C3]](s16)
%0:_(s64) = G_FCONSTANT double 0x0004000300020001
%1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(s64)
$h0 = COPY %1(s16)
$h1 = COPY %2(s16)
$h2 = COPY %3(s16)
$h3 = COPY %4(s16)
...
# Transform unmerge into trunc when only the first definition is live.
---
name: test_combine_unmerge_dead_to_trunc
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
; CHECK-NEXT: $h0 = COPY [[TRUNC]](s16)
%0:_(s64) = COPY $x0
%1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(s64)
$h0 = COPY %1(s16)
...
# Don't transform unmerge into trunc when middle lanes are live.
---
name: test_dont_combine_unmerge_dead_to_trunc
body: |
bb.1:
; CHECK-LABEL: name: test_dont_combine_unmerge_dead_to_trunc
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](s64)
; CHECK-NEXT: $h0 = COPY [[UV2]](s16)
%0:_(s64) = COPY $x0
%1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(s64)
$h0 = COPY %3(s16)
...
# Transform unmerge into trunc when only the first definition is live, even
# if the input and output types are vectors.
---
name: test_combine_unmerge_dead_to_trunc_vec_in_n_out
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc_vec_in_n_out
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $x0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
; CHECK-NEXT: $w0 = COPY [[UV]](<2 x s16>)
%0:_(<4 x s16>) = COPY $x0
%1:_(<2 x s16>),%2:_(<2 x s16>) = G_UNMERGE_VALUES %0(<4 x s16>)
$w0 = COPY %1(<2 x s16>)
...
# Transform unmerge into trunc when only the first definition is live, even
# if the input type is vector.
---
name: test_combine_unmerge_dead_to_trunc_vec_in
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc_vec_in
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $x0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
; CHECK-NEXT: $h0 = COPY [[UV]](s16)
%0:_(<2 x s32>) = COPY $x0
%1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(<2 x s32>)
$h0 = COPY %1(s16)
...
# Transform unmerge(zext) into zext.
# In that test, the source of the zext is same size as the first definition
# of the unmerge. Therefore a we can just reuse the input of the zext for
# this definition.
---
name: test_combine_unmerge_zext_to_zext_same_size
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_zext_to_zext_same_size
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
; CHECK-NEXT: $w1 = COPY [[C]](s32)
%0:_(s32) = COPY $w0
%3:_(s64) = G_ZEXT %0(s32)
%1:_(s32),%2:_(s32) = G_UNMERGE_VALUES %3(s64)
$w0 = COPY %1(s32)
$w1 = COPY %2(s32)
...
# Transform unmerge(zext) into zext.
# In that test, the source of the zext is smaller than the first definition
# of the unmerge. Therefore a G_ZEXT is required.
---
name: test_combine_unmerge_zext_to_zext
body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_zext_to_zext
; CHECK: [[COPY:%[0-9]+]]:_(s8) = COPY $b0
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[COPY]](s8)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
; CHECK-NEXT: $h0 = COPY [[ZEXT]](s16)
; CHECK-NEXT: $h1 = COPY [[C]](s16)
; CHECK-NEXT: $h2 = COPY [[C]](s16)
; CHECK-NEXT: $h3 = COPY [[C]](s16)
%0:_(s8) = COPY $b0
%3:_(s64) = G_ZEXT %0(s8)
%1:_(s16),%2:_(s16),%4:_(s16),%5:_(s16) = G_UNMERGE_VALUES %3(s64)
$h0 = COPY %1(s16)
$h1 = COPY %2(s16)
$h2 = COPY %4(s16)
$h3 = COPY %5(s16)
...
# Check that we don't apply the unmerge(zext) to zext transformation
# when the first destination of the unmerge is smaller than the source
# of the zext.
---
name: test_dont_combine_unmerge_zext_to_zext_src_bigger
body: |
bb.1:
; CHECK-LABEL: name: test_dont_combine_unmerge_zext_to_zext_src_bigger
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32)
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[ZEXT]](s64)
; CHECK-NEXT: $h0 = COPY [[UV]](s16)
; CHECK-NEXT: $h1 = COPY [[UV1]](s16)
; CHECK-NEXT: $h2 = COPY [[UV2]](s16)
; CHECK-NEXT: $h3 = COPY [[UV3]](s16)
%0:_(s32) = COPY $w0
%3:_(s64) = G_ZEXT %0(s32)
%1:_(s16),%2:_(s16),%4:_(s16),%5:_(s16) = G_UNMERGE_VALUES %3(s64)
$h0 = COPY %1(s16)
$h1 = COPY %2(s16)
$h2 = COPY %4(s16)
$h3 = COPY %5(s16)
...
# Check that we don't apply the unmerge(zext) to zext transformation
# when the input zext deals with a vector type.
---
name: test_dont_combine_unmerge_zext_to_zext_src_vector
body: |
bb.1:
; CHECK-LABEL: name: test_dont_combine_unmerge_zext_to_zext_src_vector
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $w0
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(<2 x s32>) = G_ZEXT [[COPY]](<2 x s16>)
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ZEXT]](<2 x s32>)
; CHECK-NEXT: $w0 = COPY [[UV]](s32)
; CHECK-NEXT: $w1 = COPY [[UV1]](s32)
%0:_(<2 x s16>) = COPY $w0
%3:_(<2 x s32>) = G_ZEXT %0(<2 x s16>)
%1:_(s32),%2:_(s32) = G_UNMERGE_VALUES %3(<2 x s32>)
$w0 = COPY %1(s32)
$w1 = COPY %2(s32)
...
# Check that we unmerge the build vector on the anyext
---
name: test_anyext_buildvector
body: |
bb.1:
; CHECK-LABEL: name: test_anyext_buildvector
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY]](s32)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY1]](s32)
; CHECK-NEXT: %un1:_(<2 x s64>) = G_BUILD_VECTOR [[ANYEXT]](s64), [[ANYEXT1]](s64)
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY2]](s32)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY3]](s32)
; CHECK-NEXT: %un2:_(<2 x s64>) = G_BUILD_VECTOR [[ANYEXT2]](s64), [[ANYEXT3]](s64)
; CHECK-NEXT: $q0 = COPY %un1(<2 x s64>)
; CHECK-NEXT: $q1 = COPY %un2(<2 x s64>)
%0:_(s32) = COPY $w0
%1:_(s32) = COPY $w0
%2:_(s32) = COPY $w0
%3:_(s32) = COPY $w0
%bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
%any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
%un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
$q0 = COPY %un1(<2 x s64>)
$q1 = COPY %un2(<2 x s64>)
...
# Check that we unmerge the build vector on the anyext and undef
---
name: test_anyext_buildvector_undef
body: |
bb.1:
; CHECK-LABEL: name: test_anyext_buildvector_undef
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY]](s32)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY1]](s32)
; CHECK-NEXT: %un1:_(<2 x s64>) = G_BUILD_VECTOR [[ANYEXT]](s64), [[ANYEXT1]](s64)
; CHECK-NEXT: %un2:_(<2 x s64>) = G_IMPLICIT_DEF
; CHECK-NEXT: $q0 = COPY %un1(<2 x s64>)
; CHECK-NEXT: $q1 = COPY %un2(<2 x s64>)
%0:_(s32) = COPY $w0
%1:_(s32) = COPY $w0
%2:_(s32) = G_IMPLICIT_DEF
%3:_(s32) = G_IMPLICIT_DEF
%bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
%any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
%un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
$q0 = COPY %un1(<2 x s64>)
$q1 = COPY %un2(<2 x s64>)
...
# Check that we don't unmerge the build vector on the anyext, multi-use
---
name: test_anyext_buildvector_multi
body: |
bb.1:
; CHECK-LABEL: name: test_anyext_buildvector_multi
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: %bv:_(<4 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY1]](s32), [[DEF]](s32), [[DEF1]](s32)
; CHECK-NEXT: %any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
; CHECK-NEXT: %un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
; CHECK-NEXT: $q0 = COPY %un1(<2 x s64>)
; CHECK-NEXT: $q1 = COPY %un2(<2 x s64>)
; CHECK-NEXT: $q2 = COPY %bv(<4 x s32>)
%0:_(s32) = COPY $w0
%1:_(s32) = COPY $w0
%2:_(s32) = G_IMPLICIT_DEF
%3:_(s32) = G_IMPLICIT_DEF
%bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
%any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
%un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
$q0 = COPY %un1(<2 x s64>)
$q1 = COPY %un2(<2 x s64>)
$q2 = COPY %bv(<4 x s32>)
...
# Check that we don't unmerge the build vector on the anyext into scalar
---
name: test_anyext_buildvector_scalar
body: |
bb.1:
; CHECK-LABEL: name: test_anyext_buildvector_scalar
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: %bv:_(<4 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY1]](s32), [[COPY2]](s32), [[COPY3]](s32)
; CHECK-NEXT: %any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
; CHECK-NEXT: %un1:_(s128), %un2:_(s128) = G_UNMERGE_VALUES %any(<4 x s64>)
; CHECK-NEXT: $q0 = COPY %un1(s128)
; CHECK-NEXT: $q1 = COPY %un2(s128)
%0:_(s32) = COPY $w0
%1:_(s32) = COPY $w0
%2:_(s32) = COPY $w0
%3:_(s32) = COPY $w0
%bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
%any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
%un1:_(s128), %un2:_(s128) = G_UNMERGE_VALUES %any(<4 x s64>)
$q0 = COPY %un1(s128)
$q1 = COPY %un2(s128)
...
# Check that we anyext the merge
---
name: test_merge_undef
body: |
bb.1:
; CHECK-LABEL: name: test_merge_undef
; CHECK: %opaque:_(s64) = COPY $x0
; CHECK-NEXT: %me:_(s128) = G_ANYEXT %opaque(s64)
; CHECK-NEXT: $q0 = COPY %me(s128)
%opaque:_(s64) = COPY $x0
%def:_(s64) = G_IMPLICIT_DEF
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
$q0 = COPY %me(s128)
...
# Check that we don't anyext the merge, multi-use
---
name: test_merge_undef_multi_use
body: |
bb.1:
; CHECK-LABEL: name: test_merge_undef_multi_use
; CHECK: %opaque:_(s64) = COPY $x0
; CHECK-NEXT: %def:_(s64) = G_IMPLICIT_DEF
; CHECK-NEXT: %me:_(s128) = G_ANYEXT %opaque(s64)
; CHECK-NEXT: $q0 = COPY %me(s128)
; CHECK-NEXT: $x0 = COPY %def(s64)
%opaque:_(s64) = COPY $x0
%def:_(s64) = G_IMPLICIT_DEF
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
$q0 = COPY %me(s128)
$x0 = COPY %def(s64)
...
# Check that we zext the merge
---
name: test_merge_zero
body: |
bb.1:
; CHECK-LABEL: name: test_merge_zero
; CHECK: %opaque:_(s64) = COPY $x0
; CHECK-NEXT: %me:_(s128) = G_ZEXT %opaque(s64)
; CHECK-NEXT: $q0 = COPY %me(s128)
%opaque:_(s64) = COPY $x0
%def:_(s64) = G_CONSTANT i64 0
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
$q0 = COPY %me(s128)
...
# Check that we still zext the merge, multi-use
---
name: test_merge_zero_multi_use
body: |
bb.1:
; CHECK-LABEL: name: test_merge_zero_multi_use
; CHECK: %opaque:_(s64) = COPY $x0
; CHECK-NEXT: %def:_(s64) = G_CONSTANT i64 0
; CHECK-NEXT: %me:_(s128) = G_ZEXT %opaque(s64)
; CHECK-NEXT: $q0 = COPY %me(s128)
; CHECK-NEXT: $x0 = COPY %def(s64)
%opaque:_(s64) = COPY $x0
%def:_(s64) = G_CONSTANT i64 0
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
$q0 = COPY %me(s128)
$x0 = COPY %def(s64)
...
# Check that we don't zext the merge with one
---
name: test_merge_one
body: |
bb.1:
; CHECK-LABEL: name: test_merge_one
; CHECK: %opaque:_(s64) = COPY $x0
; CHECK-NEXT: %def:_(s64) = G_CONSTANT i64 1
; CHECK-NEXT: %me:_(s128) = G_MERGE_VALUES %opaque(s64), %def(s64)
; CHECK-NEXT: $q0 = COPY %me(s128)
%opaque:_(s64) = COPY $x0
%def:_(s64) = G_CONSTANT i64 1
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
$q0 = COPY %me(s128)
...