| # 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: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: $w0 = COPY [[DEF]](s32) |
| ; CHECK: $w1 = COPY [[DEF1]](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: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: $w0 = COPY [[DEF]](s32) |
| ; CHECK: $w1 = COPY [[DEF1]](s32) |
| ; CHECK: $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: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: $w0 = COPY [[DEF]](s32) |
| ; CHECK: $w1 = COPY [[DEF1]](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: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: $w0 = COPY [[DEF]](s32) |
| ; CHECK: $w1 = COPY [[DEF1]](s32) |
| ; CHECK: $w2 = COPY [[DEF2]](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: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY $w1 |
| ; CHECK: $w0 = COPY [[COPY]](<2 x s16>) |
| ; CHECK: $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: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: $w0 = COPY [[DEF]](s32) |
| ; CHECK: $w1 = COPY [[DEF1]](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]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF |
| ; CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]](s32), [[DEF1]](s32) |
| ; CHECK: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[MV]](s64) |
| ; CHECK: $h0 = COPY [[UV]](s16) |
| ; CHECK: $h1 = COPY [[UV1]](s16) |
| ; CHECK: $h2 = COPY [[UV2]](s16) |
| ; CHECK: $h3 = COPY [[UV3]](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: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY $w1 |
| ; CHECK: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>) |
| ; CHECK: [[BITCAST1:%[0-9]+]]:_(s32) = G_BITCAST [[COPY1]](<2 x s16>) |
| ; CHECK: $w0 = COPY [[BITCAST]](s32) |
| ; CHECK: $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: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 15 |
| ; CHECK: [[C2:%[0-9]+]]:_(s8) = G_CONSTANT i8 14 |
| ; CHECK: [[C3:%[0-9]+]]:_(s8) = G_CONSTANT i8 13 |
| ; CHECK: [[C4:%[0-9]+]]:_(s8) = G_CONSTANT i8 12 |
| ; CHECK: [[C5:%[0-9]+]]:_(s8) = G_CONSTANT i8 11 |
| ; CHECK: [[C6:%[0-9]+]]:_(s8) = G_CONSTANT i8 10 |
| ; CHECK: [[C7:%[0-9]+]]:_(s8) = G_CONSTANT i8 9 |
| ; CHECK: [[C8:%[0-9]+]]:_(s8) = G_CONSTANT i8 8 |
| ; CHECK: [[C9:%[0-9]+]]:_(s8) = G_CONSTANT i8 7 |
| ; CHECK: [[C10:%[0-9]+]]:_(s8) = G_CONSTANT i8 6 |
| ; CHECK: [[C11:%[0-9]+]]:_(s8) = G_CONSTANT i8 5 |
| ; CHECK: [[C12:%[0-9]+]]:_(s8) = G_CONSTANT i8 4 |
| ; CHECK: [[C13:%[0-9]+]]:_(s8) = G_CONSTANT i8 3 |
| ; CHECK: [[C14:%[0-9]+]]:_(s8) = G_CONSTANT i8 2 |
| ; CHECK: [[C15:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 |
| ; CHECK: $b0 = COPY [[C]](s8) |
| ; CHECK: $b1 = COPY [[C1]](s8) |
| ; CHECK: $b2 = COPY [[C2]](s8) |
| ; CHECK: $b3 = COPY [[C3]](s8) |
| ; CHECK: $b4 = COPY [[C4]](s8) |
| ; CHECK: $b5 = COPY [[C5]](s8) |
| ; CHECK: $b6 = COPY [[C6]](s8) |
| ; CHECK: $b7 = COPY [[C7]](s8) |
| ; CHECK: $b8 = COPY [[C8]](s8) |
| ; CHECK: $b9 = COPY [[C9]](s8) |
| ; CHECK: $b10 = COPY [[C10]](s8) |
| ; CHECK: $b11 = COPY [[C11]](s8) |
| ; CHECK: $b12 = COPY [[C12]](s8) |
| ; CHECK: $b13 = COPY [[C13]](s8) |
| ; CHECK: $b14 = COPY [[C14]](s8) |
| ; CHECK: $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]+]]:_(s13) = G_CONSTANT i13 1 |
| ; CHECK: [[C1:%[0-9]+]]:_(s13) = G_CONSTANT i13 2 |
| ; CHECK: [[C2:%[0-9]+]]:_(s13) = G_CONSTANT i13 3 |
| ; CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[C]](s13) |
| ; CHECK: [[ZEXT1:%[0-9]+]]:_(s16) = G_ZEXT [[C1]](s13) |
| ; CHECK: [[ZEXT2:%[0-9]+]]:_(s16) = G_ZEXT [[C2]](s13) |
| ; CHECK: $h0 = COPY [[ZEXT]](s16) |
| ; CHECK: $h1 = COPY [[ZEXT1]](s16) |
| ; CHECK: $h2 = COPY [[ZEXT2]](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: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2 |
| ; CHECK: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3 |
| ; CHECK: [[C3:%[0-9]+]]:_(s16) = G_CONSTANT i16 4 |
| ; CHECK: $h0 = COPY [[C]](s16) |
| ; CHECK: $h1 = COPY [[C1]](s16) |
| ; CHECK: $h2 = COPY [[C2]](s16) |
| ; CHECK: $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: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64) |
| ; CHECK: $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: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](s64) |
| ; CHECK: $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]+]]:_(<2 x s32>) = COPY $x0 |
| ; CHECK: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<2 x s32>) |
| ; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[BITCAST]](s64) |
| ; CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[TRUNC]](s32) |
| ; CHECK: $w0 = COPY [[BITCAST1]](<2 x s16>) |
| %0:_(<2 x s32>) = COPY $x0 |
| %1:_(<2 x s16>),%2:_(<2 x s16>) = G_UNMERGE_VALUES %0(<2 x s32>) |
| $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: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<2 x s32>) |
| ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST]](s64) |
| ; CHECK: $h0 = COPY [[TRUNC]](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 into trunc when only the first definition is live, even |
| # if the output type are vector. |
| --- |
| name: test_combine_unmerge_dead_to_trunc_vec_out |
| body: | |
| bb.1: |
| ; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc_vec_out |
| ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 |
| ; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) |
| ; CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[TRUNC]](s32) |
| ; CHECK: $w0 = COPY [[BITCAST]](<2 x s16>) |
| %0:_(s64) = COPY $x0 |
| %1:_(<2 x s16>),%2:_(<2 x s16>) = G_UNMERGE_VALUES %0(s64) |
| $w0 = COPY %1(<2 x 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: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 |
| ; CHECK: $w0 = COPY [[COPY]](s32) |
| ; CHECK: $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: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[COPY]](s8) |
| ; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0 |
| ; CHECK: $h0 = COPY [[ZEXT]](s16) |
| ; CHECK: $h1 = COPY [[C]](s16) |
| ; CHECK: $h2 = COPY [[C]](s16) |
| ; CHECK: $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: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) |
| ; CHECK: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[ZEXT]](s64) |
| ; CHECK: $h0 = COPY [[UV]](s16) |
| ; CHECK: $h1 = COPY [[UV1]](s16) |
| ; CHECK: $h2 = COPY [[UV2]](s16) |
| ; CHECK: $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: [[ZEXT:%[0-9]+]]:_(<2 x s32>) = G_ZEXT [[COPY]](<2 x s16>) |
| ; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ZEXT]](<2 x s32>) |
| ; CHECK: $w0 = COPY [[UV]](s32) |
| ; CHECK: $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 don't apply the unmerge(zext) to zext transformation |
| # when the destination type is a vector type. |
| # We could actually handle this case but we would need to insert a cast. |
| --- |
| name: test_dont_combine_unmerge_zext_to_zext_dst_vector |
| body: | |
| bb.1: |
| ; CHECK-LABEL: name: test_dont_combine_unmerge_zext_to_zext_dst_vector |
| ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 |
| ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) |
| ; CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[ZEXT]](s64) |
| ; CHECK: $w0 = COPY [[UV]](<2 x s16>) |
| ; CHECK: $w1 = COPY [[UV1]](<2 x s16>) |
| %0:_(s32) = COPY $w0 |
| %3:_(s64) = G_ZEXT %0(s32) |
| %1:_(<2 x s16>),%2:_(<2 x s16>) = G_UNMERGE_VALUES %3(s64) |
| $w0 = COPY %1(<2 x s16>) |
| $w1 = COPY %2(<2 x s16>) |
| ... |