294 changes: 165 additions & 129 deletions llvm/test/CodeGen/X86/GlobalISel/legalize-add-v512.mir

Large diffs are not rendered by default.

210 changes: 171 additions & 39 deletions llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
# RUN: llc -O0 -mtriple=i386-linux-gnu -run-pass=legalizer -global-isel-abort=2 -pass-remarks-missed='gisel*' %s 2>%t -o - | FileCheck %s --check-prefix=X32
# RUN: FileCheck -check-prefix=ERR32 %s < %t

# ERR32: remark: <unknown>:0:0: unable to legalize instruction: %11:_(s32), %12:_(s1) = G_UADDO %7:_, %9:_ (in function: test_add_i42)
# ERR32: remark: <unknown>:0:0: unable to legalize instruction: %7:_(s32), %8:_(s1) = G_UADDO %3:_, %5:_ (in function: test_add_i64)

--- |

define void @test_add_i1() { ret void}
define void @test_add_i8() { ret void }
define void @test_add_i16() { ret void }
define void @test_add_i27() { ret void }
define void @test_add_i32() { ret void }
define void @test_add_i42() { ret void }
define void @test_add_i64() { ret void }

...
Expand All @@ -18,6 +23,41 @@ name: test_add_i1
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i1
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s8)
; X64-NEXT: $eax = COPY [[ANYEXT]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i1
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s8)
; X32-NEXT: $eax = COPY [[ANYEXT]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s1) = G_TRUNC %0(s32)
%2(s1) = G_ADD %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_add_i8
# CHECK-LABEL: name: test_add_i1
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
Expand All @@ -29,26 +69,83 @@ registers:
# CHECK: RET 0
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i1
; X64-LABEL: name: test_add_i8
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
; X64: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s8)
; X64: $eax = COPY [[ANYEXT]](s32)
; X64: RET 0
; X32-LABEL: name: test_add_i1
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC]]
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s8)
; X64-NEXT: $eax = COPY [[ANYEXT]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i8
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
; X32: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s8)
; X32: $eax = COPY [[ANYEXT]](s32)
; X32: RET 0
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC]]
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s8)
; X32-NEXT: $eax = COPY [[ANYEXT]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s1) = G_TRUNC %0(s32)
%2(s1) = G_ADD %1, %1
%1(s8) = G_TRUNC %0(s32)
%2(s8) = G_ADD %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_add_i16
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i16
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC]]
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s16)
; X64-NEXT: $eax = COPY [[ANYEXT]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i16
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC]]
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ADD]](s16)
; X32-NEXT: $eax = COPY [[ANYEXT]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s16) = G_TRUNC %0(s32)
%2(s16) = G_ADD %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_add_i27
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i27
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY]]
; X64-NEXT: $eax = COPY [[ADD]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i27
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY]]
; X32-NEXT: $eax = COPY [[ADD]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s27) = G_TRUNC %0(s32)
%2(s27) = G_ADD %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
Expand All @@ -66,22 +163,58 @@ body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i32
; X64: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X64: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X64: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[DEF]], [[DEF1]]
; X64: $eax = COPY [[ADD]](s32)
; X64: RET 0
; X64-NEXT: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X64-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[DEF]], [[DEF1]]
; X64-NEXT: $eax = COPY [[ADD]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i32
; X32: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X32: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X32: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[DEF]], [[DEF1]]
; X32: $eax = COPY [[ADD]](s32)
; X32: RET 0
; X32-NEXT: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[DEF]], [[DEF1]]
; X32-NEXT: $eax = COPY [[ADD]](s32)
; X32-NEXT: RET 0
%0(s32) = IMPLICIT_DEF
%1(s32) = IMPLICIT_DEF
%2(s32) = G_ADD %0, %1
$eax = COPY %2
RET 0
...
---
name: test_add_i42
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i42
; X64: [[COPY:%[0-9]+]]:_(s64) = COPY $rdx
; X64-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY]]
; X64-NEXT: $rax = COPY [[ADD]](s64)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i42
; X32: [[COPY:%[0-9]+]]:_(s64) = COPY $rdx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s42) = G_TRUNC [[COPY]](s64)
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s42)
; X32-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s42)
; X32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ANYEXT]](s64)
; X32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ANYEXT1]](s64)
; X32-NEXT: [[UADDO:%[0-9]+]]:_(s32), [[UADDO1:%[0-9]+]]:_(s1) = G_UADDO [[UV]], [[UV2]]
; X32-NEXT: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV1]], [[UV3]], [[UADDO1]]
; X32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[UADDO]](s32), [[UADDE]](s32)
; X32-NEXT: [[TRUNC1:%[0-9]+]]:_(s42) = G_TRUNC [[MV]](s64)
; X32-NEXT: [[ANYEXT2:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC1]](s42)
; X32-NEXT: $rax = COPY [[ANYEXT2]](s64)
; X32-NEXT: RET 0
%0(s64) = COPY $rdx
%1(s42) = G_TRUNC %0(s64)
%2(s42) = G_ADD %1, %1
%3:_(s64) = G_ANYEXT %2
$rax = COPY %3
RET 0
...
---
name: test_add_i64
Expand All @@ -96,24 +229,23 @@ body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_add_i64
; X64: [[DEF:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X64: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X64: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[DEF]], [[DEF1]]
; X64: $rax = COPY [[ADD]](s64)
; X64: RET 0
; X64-NEXT: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X64-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[DEF]], [[DEF1]]
; X64-NEXT: $rax = COPY [[ADD]](s64)
; X64-NEXT: RET 0
; X32-LABEL: name: test_add_i64
; X32: [[DEF:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X32: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X32: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](s64)
; X32: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF1]](s64)
; X32: [[UADDO:%[0-9]+]]:_(s32), [[UADDO1:%[0-9]+]]:_(s1) = G_UADDO [[UV]], [[UV2]]
; X32: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV1]], [[UV3]], [[UADDO1]]
; X32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[UADDO]](s32), [[UADDE]](s32)
; X32: $rax = COPY [[MV]](s64)
; X32: RET 0
; X32-NEXT: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](s64)
; X32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF1]](s64)
; X32-NEXT: [[UADDO:%[0-9]+]]:_(s32), [[UADDO1:%[0-9]+]]:_(s1) = G_UADDO [[UV]], [[UV2]]
; X32-NEXT: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV1]], [[UV3]], [[UADDO1]]
; X32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[UADDO]](s32), [[UADDE]](s32)
; X32-NEXT: $rax = COPY [[MV]](s64)
; X32-NEXT: RET 0
%0(s64) = IMPLICIT_DEF
%1(s64) = IMPLICIT_DEF
%2(s64) = G_ADD %0, %1
$rax = COPY %2
RET 0
...
48 changes: 28 additions & 20 deletions llvm/test/CodeGen/X86/GlobalISel/legalize-sub-v128.mir
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ body: |
liveins: $xmm0, $xmm1
; ALL-LABEL: name: test_sub_v16i8
; ALL: [[DEF:%[0-9]+]]:_(<16 x s8>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<16 x s8>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<16 x s8>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $xmm0 = COPY [[SUB]](<16 x s8>)
; ALL: RET 0
; ALL: liveins: $xmm0, $xmm1
; ALL-NEXT: {{ $}}
; ALL-NEXT: [[DEF:%[0-9]+]]:_(<16 x s8>) = IMPLICIT_DEF
; ALL-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s8>) = IMPLICIT_DEF
; ALL-NEXT: [[SUB:%[0-9]+]]:_(<16 x s8>) = G_SUB [[DEF]], [[DEF1]]
; ALL-NEXT: $xmm0 = COPY [[SUB]](<16 x s8>)
; ALL-NEXT: RET 0
%0(<16 x s8>) = IMPLICIT_DEF
%1(<16 x s8>) = IMPLICIT_DEF
%2(<16 x s8>) = G_SUB %0, %1
Expand All @@ -62,11 +64,13 @@ body: |
liveins: $xmm0, $xmm1
; ALL-LABEL: name: test_sub_v8i16
; ALL: [[DEF:%[0-9]+]]:_(<8 x s16>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<8 x s16>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<8 x s16>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $xmm0 = COPY [[SUB]](<8 x s16>)
; ALL: RET 0
; ALL: liveins: $xmm0, $xmm1
; ALL-NEXT: {{ $}}
; ALL-NEXT: [[DEF:%[0-9]+]]:_(<8 x s16>) = IMPLICIT_DEF
; ALL-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s16>) = IMPLICIT_DEF
; ALL-NEXT: [[SUB:%[0-9]+]]:_(<8 x s16>) = G_SUB [[DEF]], [[DEF1]]
; ALL-NEXT: $xmm0 = COPY [[SUB]](<8 x s16>)
; ALL-NEXT: RET 0
%0(<8 x s16>) = IMPLICIT_DEF
%1(<8 x s16>) = IMPLICIT_DEF
%2(<8 x s16>) = G_SUB %0, %1
Expand All @@ -88,11 +92,13 @@ body: |
liveins: $xmm0, $xmm1
; ALL-LABEL: name: test_sub_v4i32
; ALL: [[DEF:%[0-9]+]]:_(<4 x s32>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<4 x s32>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $xmm0 = COPY [[SUB]](<4 x s32>)
; ALL: RET 0
; ALL: liveins: $xmm0, $xmm1
; ALL-NEXT: {{ $}}
; ALL-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = IMPLICIT_DEF
; ALL-NEXT: [[DEF1:%[0-9]+]]:_(<4 x s32>) = IMPLICIT_DEF
; ALL-NEXT: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[DEF]], [[DEF1]]
; ALL-NEXT: $xmm0 = COPY [[SUB]](<4 x s32>)
; ALL-NEXT: RET 0
%0(<4 x s32>) = IMPLICIT_DEF
%1(<4 x s32>) = IMPLICIT_DEF
%2(<4 x s32>) = G_SUB %0, %1
Expand All @@ -114,11 +120,13 @@ body: |
liveins: $xmm0, $xmm1
; ALL-LABEL: name: test_sub_v2i64
; ALL: [[DEF:%[0-9]+]]:_(<2 x s64>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<2 x s64>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<2 x s64>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $xmm0 = COPY [[SUB]](<2 x s64>)
; ALL: RET 0
; ALL: liveins: $xmm0, $xmm1
; ALL-NEXT: {{ $}}
; ALL-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = IMPLICIT_DEF
; ALL-NEXT: [[DEF1:%[0-9]+]]:_(<2 x s64>) = IMPLICIT_DEF
; ALL-NEXT: [[SUB:%[0-9]+]]:_(<2 x s64>) = G_SUB [[DEF]], [[DEF1]]
; ALL-NEXT: $xmm0 = COPY [[SUB]](<2 x s64>)
; ALL-NEXT: RET 0
%0(<2 x s64>) = IMPLICIT_DEF
%1(<2 x s64>) = IMPLICIT_DEF
%2(<2 x s64>) = G_SUB %0, %1
Expand Down
158 changes: 133 additions & 25 deletions llvm/test/CodeGen/X86/GlobalISel/legalize-sub-v256.mir
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx2 -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=SSE2
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=AVX1
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx2 -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=AVX2

# TODO: add tests for additional configuration after the legalization supported

--- |
define void @test_sub_v32i8() {
%ret = sub <32 x i8> undef, undef
Expand Down Expand Up @@ -36,12 +40,38 @@ body: |
bb.1 (%ir-block.0):
liveins: $ymm0, $ymm1
; ALL-LABEL: name: test_sub_v32i8
; ALL: [[DEF:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<32 x s8>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $ymm0 = COPY [[SUB]](<32 x s8>)
; ALL: RET 0
; SSE2-LABEL: name: test_sub_v32i8
; SSE2: liveins: $ymm0, $ymm1
; SSE2-NEXT: {{ $}}
; SSE2-NEXT: [[DEF:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; SSE2-NEXT: [[DEF1:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; SSE2-NEXT: [[UV:%[0-9]+]]:_(<16 x s8>), [[UV1:%[0-9]+]]:_(<16 x s8>) = G_UNMERGE_VALUES [[DEF]](<32 x s8>)
; SSE2-NEXT: [[UV2:%[0-9]+]]:_(<16 x s8>), [[UV3:%[0-9]+]]:_(<16 x s8>) = G_UNMERGE_VALUES [[DEF1]](<32 x s8>)
; SSE2-NEXT: [[SUB:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV]], [[UV2]]
; SSE2-NEXT: [[SUB1:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV1]], [[UV3]]
; SSE2-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<32 x s8>) = G_CONCAT_VECTORS [[SUB]](<16 x s8>), [[SUB1]](<16 x s8>)
; SSE2-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<32 x s8>)
; SSE2-NEXT: RET 0
; AVX1-LABEL: name: test_sub_v32i8
; AVX1: liveins: $ymm0, $ymm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<16 x s8>), [[UV1:%[0-9]+]]:_(<16 x s8>) = G_UNMERGE_VALUES [[DEF]](<32 x s8>)
; AVX1-NEXT: [[UV2:%[0-9]+]]:_(<16 x s8>), [[UV3:%[0-9]+]]:_(<16 x s8>) = G_UNMERGE_VALUES [[DEF1]](<32 x s8>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV]], [[UV2]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV1]], [[UV3]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<32 x s8>) = G_CONCAT_VECTORS [[SUB]](<16 x s8>), [[SUB1]](<16 x s8>)
; AVX1-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<32 x s8>)
; AVX1-NEXT: RET 0
; AVX2-LABEL: name: test_sub_v32i8
; AVX2: liveins: $ymm0, $ymm1
; AVX2-NEXT: {{ $}}
; AVX2-NEXT: [[DEF:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; AVX2-NEXT: [[DEF1:%[0-9]+]]:_(<32 x s8>) = IMPLICIT_DEF
; AVX2-NEXT: [[SUB:%[0-9]+]]:_(<32 x s8>) = G_SUB [[DEF]], [[DEF1]]
; AVX2-NEXT: $ymm0 = COPY [[SUB]](<32 x s8>)
; AVX2-NEXT: RET 0
%0(<32 x s8>) = IMPLICIT_DEF
%1(<32 x s8>) = IMPLICIT_DEF
%2(<32 x s8>) = G_SUB %0, %1
Expand All @@ -62,12 +92,38 @@ body: |
bb.1 (%ir-block.0):
liveins: $ymm0, $ymm1
; ALL-LABEL: name: test_sub_v16i16
; ALL: [[DEF:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<16 x s16>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $ymm0 = COPY [[SUB]](<16 x s16>)
; ALL: RET 0
; SSE2-LABEL: name: test_sub_v16i16
; SSE2: liveins: $ymm0, $ymm1
; SSE2-NEXT: {{ $}}
; SSE2-NEXT: [[DEF:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; SSE2-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; SSE2-NEXT: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[DEF]](<16 x s16>)
; SSE2-NEXT: [[UV2:%[0-9]+]]:_(<8 x s16>), [[UV3:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[DEF1]](<16 x s16>)
; SSE2-NEXT: [[SUB:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV]], [[UV2]]
; SSE2-NEXT: [[SUB1:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV1]], [[UV3]]
; SSE2-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s16>) = G_CONCAT_VECTORS [[SUB]](<8 x s16>), [[SUB1]](<8 x s16>)
; SSE2-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<16 x s16>)
; SSE2-NEXT: RET 0
; AVX1-LABEL: name: test_sub_v16i16
; AVX1: liveins: $ymm0, $ymm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[DEF]](<16 x s16>)
; AVX1-NEXT: [[UV2:%[0-9]+]]:_(<8 x s16>), [[UV3:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[DEF1]](<16 x s16>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV]], [[UV2]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV1]], [[UV3]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s16>) = G_CONCAT_VECTORS [[SUB]](<8 x s16>), [[SUB1]](<8 x s16>)
; AVX1-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<16 x s16>)
; AVX1-NEXT: RET 0
; AVX2-LABEL: name: test_sub_v16i16
; AVX2: liveins: $ymm0, $ymm1
; AVX2-NEXT: {{ $}}
; AVX2-NEXT: [[DEF:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; AVX2-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s16>) = IMPLICIT_DEF
; AVX2-NEXT: [[SUB:%[0-9]+]]:_(<16 x s16>) = G_SUB [[DEF]], [[DEF1]]
; AVX2-NEXT: $ymm0 = COPY [[SUB]](<16 x s16>)
; AVX2-NEXT: RET 0
%0(<16 x s16>) = IMPLICIT_DEF
%1(<16 x s16>) = IMPLICIT_DEF
%2(<16 x s16>) = G_SUB %0, %1
Expand All @@ -88,12 +144,38 @@ body: |
bb.1 (%ir-block.0):
liveins: $ymm0, $ymm1
; ALL-LABEL: name: test_sub_v8i32
; ALL: [[DEF:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<8 x s32>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $ymm0 = COPY [[SUB]](<8 x s32>)
; ALL: RET 0
; SSE2-LABEL: name: test_sub_v8i32
; SSE2: liveins: $ymm0, $ymm1
; SSE2-NEXT: {{ $}}
; SSE2-NEXT: [[DEF:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; SSE2-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; SSE2-NEXT: [[UV:%[0-9]+]]:_(<4 x s32>), [[UV1:%[0-9]+]]:_(<4 x s32>) = G_UNMERGE_VALUES [[DEF]](<8 x s32>)
; SSE2-NEXT: [[UV2:%[0-9]+]]:_(<4 x s32>), [[UV3:%[0-9]+]]:_(<4 x s32>) = G_UNMERGE_VALUES [[DEF1]](<8 x s32>)
; SSE2-NEXT: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV]], [[UV2]]
; SSE2-NEXT: [[SUB1:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV1]], [[UV3]]
; SSE2-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<8 x s32>) = G_CONCAT_VECTORS [[SUB]](<4 x s32>), [[SUB1]](<4 x s32>)
; SSE2-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<8 x s32>)
; SSE2-NEXT: RET 0
; AVX1-LABEL: name: test_sub_v8i32
; AVX1: liveins: $ymm0, $ymm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<4 x s32>), [[UV1:%[0-9]+]]:_(<4 x s32>) = G_UNMERGE_VALUES [[DEF]](<8 x s32>)
; AVX1-NEXT: [[UV2:%[0-9]+]]:_(<4 x s32>), [[UV3:%[0-9]+]]:_(<4 x s32>) = G_UNMERGE_VALUES [[DEF1]](<8 x s32>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV]], [[UV2]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV1]], [[UV3]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<8 x s32>) = G_CONCAT_VECTORS [[SUB]](<4 x s32>), [[SUB1]](<4 x s32>)
; AVX1-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<8 x s32>)
; AVX1-NEXT: RET 0
; AVX2-LABEL: name: test_sub_v8i32
; AVX2: liveins: $ymm0, $ymm1
; AVX2-NEXT: {{ $}}
; AVX2-NEXT: [[DEF:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; AVX2-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s32>) = IMPLICIT_DEF
; AVX2-NEXT: [[SUB:%[0-9]+]]:_(<8 x s32>) = G_SUB [[DEF]], [[DEF1]]
; AVX2-NEXT: $ymm0 = COPY [[SUB]](<8 x s32>)
; AVX2-NEXT: RET 0
%0(<8 x s32>) = IMPLICIT_DEF
%1(<8 x s32>) = IMPLICIT_DEF
%2(<8 x s32>) = G_SUB %0, %1
Expand All @@ -114,12 +196,38 @@ body: |
bb.1 (%ir-block.0):
liveins: $ymm0, $ymm1
; ALL-LABEL: name: test_sub_v4i64
; ALL: [[DEF:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<4 x s64>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $ymm0 = COPY [[SUB]](<4 x s64>)
; ALL: RET 0
; SSE2-LABEL: name: test_sub_v4i64
; SSE2: liveins: $ymm0, $ymm1
; SSE2-NEXT: {{ $}}
; SSE2-NEXT: [[DEF:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; SSE2-NEXT: [[DEF1:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; SSE2-NEXT: [[UV:%[0-9]+]]:_(<2 x s64>), [[UV1:%[0-9]+]]:_(<2 x s64>) = G_UNMERGE_VALUES [[DEF]](<4 x s64>)
; SSE2-NEXT: [[UV2:%[0-9]+]]:_(<2 x s64>), [[UV3:%[0-9]+]]:_(<2 x s64>) = G_UNMERGE_VALUES [[DEF1]](<4 x s64>)
; SSE2-NEXT: [[SUB:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV]], [[UV2]]
; SSE2-NEXT: [[SUB1:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV1]], [[UV3]]
; SSE2-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s64>) = G_CONCAT_VECTORS [[SUB]](<2 x s64>), [[SUB1]](<2 x s64>)
; SSE2-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<4 x s64>)
; SSE2-NEXT: RET 0
; AVX1-LABEL: name: test_sub_v4i64
; AVX1: liveins: $ymm0, $ymm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<2 x s64>), [[UV1:%[0-9]+]]:_(<2 x s64>) = G_UNMERGE_VALUES [[DEF]](<4 x s64>)
; AVX1-NEXT: [[UV2:%[0-9]+]]:_(<2 x s64>), [[UV3:%[0-9]+]]:_(<2 x s64>) = G_UNMERGE_VALUES [[DEF1]](<4 x s64>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV]], [[UV2]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV1]], [[UV3]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s64>) = G_CONCAT_VECTORS [[SUB]](<2 x s64>), [[SUB1]](<2 x s64>)
; AVX1-NEXT: $ymm0 = COPY [[CONCAT_VECTORS]](<4 x s64>)
; AVX1-NEXT: RET 0
; AVX2-LABEL: name: test_sub_v4i64
; AVX2: liveins: $ymm0, $ymm1
; AVX2-NEXT: {{ $}}
; AVX2-NEXT: [[DEF:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; AVX2-NEXT: [[DEF1:%[0-9]+]]:_(<4 x s64>) = IMPLICIT_DEF
; AVX2-NEXT: [[SUB:%[0-9]+]]:_(<4 x s64>) = G_SUB [[DEF]], [[DEF1]]
; AVX2-NEXT: $ymm0 = COPY [[SUB]](<4 x s64>)
; AVX2-NEXT: RET 0
%0(<4 x s64>) = IMPLICIT_DEF
%1(<4 x s64>) = IMPLICIT_DEF
%2(<4 x s64>) = G_SUB %0, %1
Expand Down
158 changes: 133 additions & 25 deletions llvm/test/CodeGen/X86/GlobalISel/legalize-sub-v512.mir
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f,+avx512bw -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=AVX1
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=AVX512F
# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f,+avx512bw -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=AVX512BW

# TODO: add tests for additional configuration after the legalization supported

--- |
define void @test_sub_v64i8() {
%ret = sub <64 x i8> undef, undef
Expand Down Expand Up @@ -36,12 +40,40 @@ body: |
bb.1 (%ir-block.0):
liveins: $zmm0, $zmm1
; ALL-LABEL: name: test_sub_v64i8
; ALL: [[DEF:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<64 x s8>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $zmm0 = COPY [[SUB]](<64 x s8>)
; ALL: RET 0
; AVX1-LABEL: name: test_sub_v64i8
; AVX1: liveins: $zmm0, $zmm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<16 x s8>), [[UV1:%[0-9]+]]:_(<16 x s8>), [[UV2:%[0-9]+]]:_(<16 x s8>), [[UV3:%[0-9]+]]:_(<16 x s8>) = G_UNMERGE_VALUES [[DEF]](<64 x s8>)
; AVX1-NEXT: [[UV4:%[0-9]+]]:_(<16 x s8>), [[UV5:%[0-9]+]]:_(<16 x s8>), [[UV6:%[0-9]+]]:_(<16 x s8>), [[UV7:%[0-9]+]]:_(<16 x s8>) = G_UNMERGE_VALUES [[DEF1]](<64 x s8>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV]], [[UV4]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV1]], [[UV5]]
; AVX1-NEXT: [[SUB2:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV2]], [[UV6]]
; AVX1-NEXT: [[SUB3:%[0-9]+]]:_(<16 x s8>) = G_SUB [[UV3]], [[UV7]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<64 x s8>) = G_CONCAT_VECTORS [[SUB]](<16 x s8>), [[SUB1]](<16 x s8>), [[SUB2]](<16 x s8>), [[SUB3]](<16 x s8>)
; AVX1-NEXT: $zmm0 = COPY [[CONCAT_VECTORS]](<64 x s8>)
; AVX1-NEXT: RET 0
; AVX512F-LABEL: name: test_sub_v64i8
; AVX512F: liveins: $zmm0, $zmm1
; AVX512F-NEXT: {{ $}}
; AVX512F-NEXT: [[DEF:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; AVX512F-NEXT: [[DEF1:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; AVX512F-NEXT: [[UV:%[0-9]+]]:_(<32 x s8>), [[UV1:%[0-9]+]]:_(<32 x s8>) = G_UNMERGE_VALUES [[DEF]](<64 x s8>)
; AVX512F-NEXT: [[UV2:%[0-9]+]]:_(<32 x s8>), [[UV3:%[0-9]+]]:_(<32 x s8>) = G_UNMERGE_VALUES [[DEF1]](<64 x s8>)
; AVX512F-NEXT: [[SUB:%[0-9]+]]:_(<32 x s8>) = G_SUB [[UV]], [[UV2]]
; AVX512F-NEXT: [[SUB1:%[0-9]+]]:_(<32 x s8>) = G_SUB [[UV1]], [[UV3]]
; AVX512F-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<64 x s8>) = G_CONCAT_VECTORS [[SUB]](<32 x s8>), [[SUB1]](<32 x s8>)
; AVX512F-NEXT: $zmm0 = COPY [[CONCAT_VECTORS]](<64 x s8>)
; AVX512F-NEXT: RET 0
; AVX512BW-LABEL: name: test_sub_v64i8
; AVX512BW: liveins: $zmm0, $zmm1
; AVX512BW-NEXT: {{ $}}
; AVX512BW-NEXT: [[DEF:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[DEF1:%[0-9]+]]:_(<64 x s8>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[SUB:%[0-9]+]]:_(<64 x s8>) = G_SUB [[DEF]], [[DEF1]]
; AVX512BW-NEXT: $zmm0 = COPY [[SUB]](<64 x s8>)
; AVX512BW-NEXT: RET 0
%0(<64 x s8>) = IMPLICIT_DEF
%1(<64 x s8>) = IMPLICIT_DEF
%2(<64 x s8>) = G_SUB %0, %1
Expand All @@ -62,12 +94,40 @@ body: |
bb.1 (%ir-block.0):
liveins: $zmm0, $zmm1
; ALL-LABEL: name: test_sub_v32i16
; ALL: [[DEF:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<32 x s16>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $zmm0 = COPY [[SUB]](<32 x s16>)
; ALL: RET 0
; AVX1-LABEL: name: test_sub_v32i16
; AVX1: liveins: $zmm0, $zmm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>), [[UV2:%[0-9]+]]:_(<8 x s16>), [[UV3:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[DEF]](<32 x s16>)
; AVX1-NEXT: [[UV4:%[0-9]+]]:_(<8 x s16>), [[UV5:%[0-9]+]]:_(<8 x s16>), [[UV6:%[0-9]+]]:_(<8 x s16>), [[UV7:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[DEF1]](<32 x s16>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV]], [[UV4]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV1]], [[UV5]]
; AVX1-NEXT: [[SUB2:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV2]], [[UV6]]
; AVX1-NEXT: [[SUB3:%[0-9]+]]:_(<8 x s16>) = G_SUB [[UV3]], [[UV7]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<32 x s16>) = G_CONCAT_VECTORS [[SUB]](<8 x s16>), [[SUB1]](<8 x s16>), [[SUB2]](<8 x s16>), [[SUB3]](<8 x s16>)
; AVX1-NEXT: $zmm0 = COPY [[CONCAT_VECTORS]](<32 x s16>)
; AVX1-NEXT: RET 0
; AVX512F-LABEL: name: test_sub_v32i16
; AVX512F: liveins: $zmm0, $zmm1
; AVX512F-NEXT: {{ $}}
; AVX512F-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; AVX512F-NEXT: [[DEF1:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; AVX512F-NEXT: [[UV:%[0-9]+]]:_(<16 x s16>), [[UV1:%[0-9]+]]:_(<16 x s16>) = G_UNMERGE_VALUES [[DEF]](<32 x s16>)
; AVX512F-NEXT: [[UV2:%[0-9]+]]:_(<16 x s16>), [[UV3:%[0-9]+]]:_(<16 x s16>) = G_UNMERGE_VALUES [[DEF1]](<32 x s16>)
; AVX512F-NEXT: [[SUB:%[0-9]+]]:_(<16 x s16>) = G_SUB [[UV]], [[UV2]]
; AVX512F-NEXT: [[SUB1:%[0-9]+]]:_(<16 x s16>) = G_SUB [[UV1]], [[UV3]]
; AVX512F-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<32 x s16>) = G_CONCAT_VECTORS [[SUB]](<16 x s16>), [[SUB1]](<16 x s16>)
; AVX512F-NEXT: $zmm0 = COPY [[CONCAT_VECTORS]](<32 x s16>)
; AVX512F-NEXT: RET 0
; AVX512BW-LABEL: name: test_sub_v32i16
; AVX512BW: liveins: $zmm0, $zmm1
; AVX512BW-NEXT: {{ $}}
; AVX512BW-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[DEF1:%[0-9]+]]:_(<32 x s16>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[SUB:%[0-9]+]]:_(<32 x s16>) = G_SUB [[DEF]], [[DEF1]]
; AVX512BW-NEXT: $zmm0 = COPY [[SUB]](<32 x s16>)
; AVX512BW-NEXT: RET 0
%0(<32 x s16>) = IMPLICIT_DEF
%1(<32 x s16>) = IMPLICIT_DEF
%2(<32 x s16>) = G_SUB %0, %1
Expand All @@ -88,12 +148,36 @@ body: |
bb.1 (%ir-block.0):
liveins: $zmm0, $zmm1
; ALL-LABEL: name: test_sub_v16i32
; ALL: [[DEF:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<16 x s32>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $zmm0 = COPY [[SUB]](<16 x s32>)
; ALL: RET 0
; AVX1-LABEL: name: test_sub_v16i32
; AVX1: liveins: $zmm0, $zmm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<4 x s32>), [[UV1:%[0-9]+]]:_(<4 x s32>), [[UV2:%[0-9]+]]:_(<4 x s32>), [[UV3:%[0-9]+]]:_(<4 x s32>) = G_UNMERGE_VALUES [[DEF]](<16 x s32>)
; AVX1-NEXT: [[UV4:%[0-9]+]]:_(<4 x s32>), [[UV5:%[0-9]+]]:_(<4 x s32>), [[UV6:%[0-9]+]]:_(<4 x s32>), [[UV7:%[0-9]+]]:_(<4 x s32>) = G_UNMERGE_VALUES [[DEF1]](<16 x s32>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV]], [[UV4]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV1]], [[UV5]]
; AVX1-NEXT: [[SUB2:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV2]], [[UV6]]
; AVX1-NEXT: [[SUB3:%[0-9]+]]:_(<4 x s32>) = G_SUB [[UV3]], [[UV7]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[SUB]](<4 x s32>), [[SUB1]](<4 x s32>), [[SUB2]](<4 x s32>), [[SUB3]](<4 x s32>)
; AVX1-NEXT: $zmm0 = COPY [[CONCAT_VECTORS]](<16 x s32>)
; AVX1-NEXT: RET 0
; AVX512F-LABEL: name: test_sub_v16i32
; AVX512F: liveins: $zmm0, $zmm1
; AVX512F-NEXT: {{ $}}
; AVX512F-NEXT: [[DEF:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; AVX512F-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; AVX512F-NEXT: [[SUB:%[0-9]+]]:_(<16 x s32>) = G_SUB [[DEF]], [[DEF1]]
; AVX512F-NEXT: $zmm0 = COPY [[SUB]](<16 x s32>)
; AVX512F-NEXT: RET 0
; AVX512BW-LABEL: name: test_sub_v16i32
; AVX512BW: liveins: $zmm0, $zmm1
; AVX512BW-NEXT: {{ $}}
; AVX512BW-NEXT: [[DEF:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[DEF1:%[0-9]+]]:_(<16 x s32>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[SUB:%[0-9]+]]:_(<16 x s32>) = G_SUB [[DEF]], [[DEF1]]
; AVX512BW-NEXT: $zmm0 = COPY [[SUB]](<16 x s32>)
; AVX512BW-NEXT: RET 0
%0(<16 x s32>) = IMPLICIT_DEF
%1(<16 x s32>) = IMPLICIT_DEF
%2(<16 x s32>) = G_SUB %0, %1
Expand All @@ -114,12 +198,36 @@ body: |
bb.1 (%ir-block.0):
liveins: $zmm0, $zmm1
; ALL-LABEL: name: test_sub_v8i64
; ALL: [[DEF:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; ALL: [[DEF1:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; ALL: [[SUB:%[0-9]+]]:_(<8 x s64>) = G_SUB [[DEF]], [[DEF1]]
; ALL: $zmm0 = COPY [[SUB]](<8 x s64>)
; ALL: RET 0
; AVX1-LABEL: name: test_sub_v8i64
; AVX1: liveins: $zmm0, $zmm1
; AVX1-NEXT: {{ $}}
; AVX1-NEXT: [[DEF:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; AVX1-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; AVX1-NEXT: [[UV:%[0-9]+]]:_(<2 x s64>), [[UV1:%[0-9]+]]:_(<2 x s64>), [[UV2:%[0-9]+]]:_(<2 x s64>), [[UV3:%[0-9]+]]:_(<2 x s64>) = G_UNMERGE_VALUES [[DEF]](<8 x s64>)
; AVX1-NEXT: [[UV4:%[0-9]+]]:_(<2 x s64>), [[UV5:%[0-9]+]]:_(<2 x s64>), [[UV6:%[0-9]+]]:_(<2 x s64>), [[UV7:%[0-9]+]]:_(<2 x s64>) = G_UNMERGE_VALUES [[DEF1]](<8 x s64>)
; AVX1-NEXT: [[SUB:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV]], [[UV4]]
; AVX1-NEXT: [[SUB1:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV1]], [[UV5]]
; AVX1-NEXT: [[SUB2:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV2]], [[UV6]]
; AVX1-NEXT: [[SUB3:%[0-9]+]]:_(<2 x s64>) = G_SUB [[UV3]], [[UV7]]
; AVX1-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<8 x s64>) = G_CONCAT_VECTORS [[SUB]](<2 x s64>), [[SUB1]](<2 x s64>), [[SUB2]](<2 x s64>), [[SUB3]](<2 x s64>)
; AVX1-NEXT: $zmm0 = COPY [[CONCAT_VECTORS]](<8 x s64>)
; AVX1-NEXT: RET 0
; AVX512F-LABEL: name: test_sub_v8i64
; AVX512F: liveins: $zmm0, $zmm1
; AVX512F-NEXT: {{ $}}
; AVX512F-NEXT: [[DEF:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; AVX512F-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; AVX512F-NEXT: [[SUB:%[0-9]+]]:_(<8 x s64>) = G_SUB [[DEF]], [[DEF1]]
; AVX512F-NEXT: $zmm0 = COPY [[SUB]](<8 x s64>)
; AVX512F-NEXT: RET 0
; AVX512BW-LABEL: name: test_sub_v8i64
; AVX512BW: liveins: $zmm0, $zmm1
; AVX512BW-NEXT: {{ $}}
; AVX512BW-NEXT: [[DEF:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s64>) = IMPLICIT_DEF
; AVX512BW-NEXT: [[SUB:%[0-9]+]]:_(<8 x s64>) = G_SUB [[DEF]], [[DEF1]]
; AVX512BW-NEXT: $zmm0 = COPY [[SUB]](<8 x s64>)
; AVX512BW-NEXT: RET 0
%0(<8 x s64>) = IMPLICIT_DEF
%1(<8 x s64>) = IMPLICIT_DEF
%2(<8 x s64>) = G_SUB %0, %1
Expand Down
249 changes: 215 additions & 34 deletions llvm/test/CodeGen/X86/GlobalISel/legalize-sub.mir
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -O0 -mtriple=x86_64-linux-gnu -run-pass=legalizer %s -o - | FileCheck %s
# RUN: llc -O0 -mtriple=x86_64-linux-gnu -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=X64
# RUN: llc -O0 -mtriple=i386-linux-gnu -run-pass=legalizer -global-isel-abort=2 -pass-remarks-missed='gisel*' %s 2>%t -o - | FileCheck %s --check-prefix=X32
# RUN: FileCheck -check-prefix=ERR32 %s < %t

# ERR32: remark: <unknown>:0:0: unable to legalize instruction: %13:_(s32), %14:_(s1) = G_USUBE %8:_, %10:_, %12:_ (in function: test_sub_i42)
# ERR32: remark: <unknown>:0:0: unable to legalize instruction: %9:_(s32), %10:_(s1) = G_USUBE %4:_, %6:_, %8:_ (in function: test_sub_i64)

--- |

define void @test_sub_i1() { ret void}

define i32 @test_sub_i32(i32 %arg1, i32 %arg2) {
%ret = sub i32 %arg1, %arg2
ret i32 %ret
}
define void @test_sub_i8() { ret void }
define void @test_sub_i16() { ret void }
define void @test_sub_i27() { ret void }
define void @test_sub_i32() { ret void }
define void @test_sub_i42() { ret void }
define void @test_sub_i64() { ret void }

...
---
name: test_sub_i1
# CHECK-LABEL: name: test_sub_i1
alignment: 16
legalized: false
regBankSelected: false
Expand All @@ -22,49 +29,223 @@ registers:
- { id: 2, class: _, preferred-register: '' }
body: |
bb.1 (%ir-block.0):
; CHECK-LABEL: name: test_sub_i1
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; CHECK: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC1]]
; CHECK: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
; CHECK: [[AND:%[0-9]+]]:_(s8) = G_AND [[SUB]], [[C]]
; CHECK: G_STORE [[AND]](s8), [[DEF]](p0) :: (store (s1))
; CHECK: RET 0
; X64-LABEL: name: test_sub_i1
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC1]]
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s8)
; X64-NEXT: $eax = COPY [[ANYEXT]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i1
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC1]]
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s8)
; X32-NEXT: $eax = COPY [[ANYEXT]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s1) = G_TRUNC %0(s32)
%2(s1) = G_SUB %1, %1
%3:_(p0) = G_IMPLICIT_DEF
G_STORE %2, %3 :: (store (s1))
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_sub_i8
# CHECK-LABEL: name: test_sub_i1
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
# CHECK: %0(s32) = COPY $edx
# CHECK-NEXT: %3(s8) = G_TRUNC %0(s32)
# CHECK-NEXT: %4(s8) = G_TRUNC %0(s32)
# CHECK-NEXT: %5(s8) = G_SUB %3, %4
# CHECK: RET 0
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_sub_i8
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC]]
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s8)
; X64-NEXT: $eax = COPY [[ANYEXT]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i8
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC]]
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s8)
; X32-NEXT: $eax = COPY [[ANYEXT]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s8) = G_TRUNC %0(s32)
%2(s8) = G_SUB %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_sub_i16
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_sub_i16
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
; X64-NEXT: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[TRUNC]], [[TRUNC]]
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s16)
; X64-NEXT: $eax = COPY [[ANYEXT]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i16
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
; X32-NEXT: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[TRUNC]], [[TRUNC]]
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s16)
; X32-NEXT: $eax = COPY [[ANYEXT]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s16) = G_TRUNC %0(s32)
%2(s16) = G_SUB %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_sub_i27
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_sub_i27
; X64: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X64-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY]]
; X64-NEXT: $eax = COPY [[SUB]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i27
; X32: [[COPY:%[0-9]+]]:_(s32) = COPY $edx
; X32-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY]]
; X32-NEXT: $eax = COPY [[SUB]](s32)
; X32-NEXT: RET 0
%0(s32) = COPY $edx
%1(s27) = G_TRUNC %0(s32)
%2(s27) = G_SUB %1, %1
%3:_(s32) = G_ANYEXT %2
$eax = COPY %3
RET 0
...
---
name: test_sub_i32
alignment: 16
legalized: false
regBankSelected: false
tracksRegLiveness: true
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
liveins: $edi, $esi
; CHECK-LABEL: name: test_sub_i32
; CHECK: liveins: $edi, $esi
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
; CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY1]]
; CHECK: $eax = COPY [[SUB]](s32)
; CHECK: RET 0, implicit $eax
%0(s32) = COPY $edi
%1(s32) = COPY $esi
; X64-LABEL: name: test_sub_i32
; X64: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X64-NEXT: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X64-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[DEF]], [[DEF1]]
; X64-NEXT: $eax = COPY [[SUB]](s32)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i32
; X32: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X32-NEXT: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF
; X32-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[DEF]], [[DEF1]]
; X32-NEXT: $eax = COPY [[SUB]](s32)
; X32-NEXT: RET 0
%0(s32) = IMPLICIT_DEF
%1(s32) = IMPLICIT_DEF
%2(s32) = G_SUB %0, %1
$eax = COPY %2(s32)
RET 0, implicit $eax
$eax = COPY %2
RET 0
...
---
name: test_sub_i42
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_sub_i42
; X64: [[COPY:%[0-9]+]]:_(s64) = COPY $rdx
; X64-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[COPY]], [[COPY]]
; X64-NEXT: $rax = COPY [[SUB]](s64)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i42
; X32: [[COPY:%[0-9]+]]:_(s64) = COPY $rdx
; X32-NEXT: [[TRUNC:%[0-9]+]]:_(s42) = G_TRUNC [[COPY]](s64)
; X32-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s42)
; X32-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s42)
; X32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ANYEXT]](s64)
; X32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ANYEXT1]](s64)
; X32-NEXT: [[USUBO:%[0-9]+]]:_(s32), [[USUBO1:%[0-9]+]]:_(s1) = G_USUBO [[UV]], [[UV2]]
; X32-NEXT: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[UV1]], [[UV3]], [[USUBO1]]
; X32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[USUBO]](s32), [[USUBE]](s32)
; X32-NEXT: [[TRUNC1:%[0-9]+]]:_(s42) = G_TRUNC [[MV]](s64)
; X32-NEXT: [[ANYEXT2:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC1]](s42)
; X32-NEXT: $rax = COPY [[ANYEXT2]](s64)
; X32-NEXT: RET 0
%0(s64) = COPY $rdx
%1(s42) = G_TRUNC %0(s64)
%2(s42) = G_SUB %1, %1
%3:_(s64) = G_ANYEXT %2
$rax = COPY %3
RET 0
...
---
name: test_sub_i64
alignment: 16
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
; X64-LABEL: name: test_sub_i64
; X64: [[DEF:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X64-NEXT: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X64-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[DEF]], [[DEF1]]
; X64-NEXT: $rax = COPY [[SUB]](s64)
; X64-NEXT: RET 0
; X32-LABEL: name: test_sub_i64
; X32: [[DEF:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X32-NEXT: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
; X32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](s64)
; X32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF1]](s64)
; X32-NEXT: [[USUBO:%[0-9]+]]:_(s32), [[USUBO1:%[0-9]+]]:_(s1) = G_USUBO [[UV]], [[UV2]]
; X32-NEXT: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[UV1]], [[UV3]], [[USUBO1]]
; X32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[USUBO]](s32), [[USUBE]](s32)
; X32-NEXT: $rax = COPY [[MV]](s64)
; X32-NEXT: RET 0
%0(s64) = IMPLICIT_DEF
%1(s64) = IMPLICIT_DEF
%2(s64) = G_SUB %0, %1
$rax = COPY %2
RET 0
...