From 29293e6f9d8d20464ffcb9f9401c968674c90ea2 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 15 Jun 2023 22:40:42 +0100 Subject: [PATCH] [GlobalISel][X86] Add i128 add/sub test coverage for narrowing on x86_64 triples --- llvm/test/CodeGen/X86/GlobalISel/add-scalar.ll | 33 +++++ llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir | 59 +++++++- llvm/test/CodeGen/X86/GlobalISel/legalize-sub.mir | 161 ++++++++++++---------- llvm/test/CodeGen/X86/GlobalISel/sub-scalar.ll | 87 +++++++++++- 4 files changed, 257 insertions(+), 83 deletions(-) diff --git a/llvm/test/CodeGen/X86/GlobalISel/add-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/add-scalar.ll index 95becd7..7805a3c8 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/add-scalar.ll +++ b/llvm/test/CodeGen/X86/GlobalISel/add-scalar.ll @@ -2,6 +2,39 @@ ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=2 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64 ; RUN: llc -mtriple=i386-linux-gnu -global-isel -global-isel-abort=2 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X86 +define i128 @test_add_i128(i128 %arg1, i128 %arg2) nounwind { +; X64-LABEL: test_add_i128: +; X64: # %bb.0: +; X64-NEXT: movq %rdi, %rax +; X64-NEXT: addq %rdx, %rax +; X64-NEXT: adcq %rcx, %rsi +; X64-NEXT: movq %rsi, %rdx +; X64-NEXT: retq +; +; X86-LABEL: test_add_i128: +; X86: # %bb.0: +; X86-NEXT: pushl %edi +; X86-NEXT: pushl %esi +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %esi +; X86-NEXT: movl {{[0-9]+}}(%esp), %edi +; X86-NEXT: addl {{[0-9]+}}(%esp), %esi +; X86-NEXT: adcl {{[0-9]+}}(%esp), %edi +; X86-NEXT: adcl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: adcl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl %ecx, 8(%eax) +; X86-NEXT: movl %edi, 4(%eax) +; X86-NEXT: movl %esi, (%eax) +; X86-NEXT: movl %edx, 12(%eax) +; X86-NEXT: popl %esi +; X86-NEXT: popl %edi +; X86-NEXT: retl $4 + %ret = add i128 %arg1, %arg2 + ret i128 %ret +} + define i64 @test_add_i64(i64 %arg1, i64 %arg2) { ; X64-LABEL: test_add_i64: ; X64: # %bb.0: diff --git a/llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir b/llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir index 70e3af3..4027bc3 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir +++ b/llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir @@ -1,10 +1,15 @@ # 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 --check-prefixes=CHECK,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-prefixes=CHECK,X32 +# RUN: llc -O0 -mtriple=x86_64-linux-gnu -run-pass=legalizer -global-isel-abort=2 -pass-remarks-missed='gisel*' %s 2>%t -o - | FileCheck %s --check-prefixes=CHECK,X64 +# RUN: FileCheck -check-prefix=ERR64 %s < %t + +# 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-prefixes=CHECK,X32 # RUN: FileCheck -check-prefix=ERR32 %s < %t +# ERR64: remark: :0:0: unable to legalize instruction: %9:_(s64), %10:_(s1) = G_UADDO %5:_, %7:_ (in function: test_add_i128) + # ERR32: remark: :0:0: unable to legalize instruction: %11:_(s32), %12:_(s1) = G_UADDO %7:_, %9:_ (in function: test_add_i42) # ERR32: remark: :0:0: unable to legalize instruction: %7:_(s32), %8:_(s1) = G_UADDO %3:_, %5:_ (in function: test_add_i64) +# ERR32: remark: :0:0: unable to legalize instruction: %13:_(s32), %14:_(s1) = G_UADDO %5:_, %9:_ (in function: test_add_i128) --- | @@ -15,6 +20,7 @@ define void @test_add_i32() { ret void } define void @test_add_i42() { ret void } define void @test_add_i64() { ret void } + define void @test_add_i128() { ret void } ... --- @@ -209,3 +215,52 @@ body: | $rax = COPY %2 RET 0 ... +--- +name: test_add_i128 +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_i128 + ; X64: [[DEF:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X64-NEXT: [[DEF1:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X64-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[DEF]](s128) + ; X64-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[DEF1]](s128) + ; X64-NEXT: [[UADDO:%[0-9]+]]:_(s64), [[UADDO1:%[0-9]+]]:_(s1) = G_UADDO [[UV]], [[UV2]] + ; X64-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[UV1]](s64) + ; X64-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[UV3]](s64) + ; X64-NEXT: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV4]], [[UV6]], [[UADDO1]] + ; X64-NEXT: [[UADDE2:%[0-9]+]]:_(s32), [[UADDE3:%[0-9]+]]:_(s1) = G_UADDE [[UV5]], [[UV7]], [[UADDE1]] + ; X64-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[UADDE]](s32), [[UADDE2]](s32) + ; X64-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[UADDO]](s64), [[MV]](s64) + ; X64-NEXT: [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV1]](s128) + ; X64-NEXT: $rax = COPY [[UV8]](s64) + ; X64-NEXT: $rdx = COPY [[UV9]](s64) + ; X64-NEXT: RET 0 + ; X32-LABEL: name: test_add_i128 + ; X32: [[DEF:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X32-NEXT: [[DEF1:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32), [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](s128) + ; X32-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32), [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF1]](s128) + ; X32-NEXT: [[UADDO:%[0-9]+]]:_(s32), [[UADDO1:%[0-9]+]]:_(s1) = G_UADDO [[UV]], [[UV4]] + ; X32-NEXT: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV1]], [[UV5]], [[UADDO1]] + ; X32-NEXT: [[UADDE2:%[0-9]+]]:_(s32), [[UADDE3:%[0-9]+]]:_(s1) = G_UADDE [[UV2]], [[UV6]], [[UADDE1]] + ; X32-NEXT: [[UADDE4:%[0-9]+]]:_(s32), [[UADDE5:%[0-9]+]]:_(s1) = G_UADDE [[UV3]], [[UV7]], [[UADDE3]] + ; X32-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[UADDO]](s32), [[UADDE]](s32), [[UADDE2]](s32), [[UADDE4]](s32) + ; X32-NEXT: [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s128) + ; X32-NEXT: $rax = COPY [[UV8]](s64) + ; X32-NEXT: $rdx = COPY [[UV9]](s64) + ; X32-NEXT: RET 0 + %0(s128) = IMPLICIT_DEF + %1(s128) = IMPLICIT_DEF + %2(s128) = G_ADD %0, %1 + %3:_(s64), %4:_(s64) = G_UNMERGE_VALUES %2(s128) + $rax = COPY %3 + $rdx = COPY %4 + RET 0 +... diff --git a/llvm/test/CodeGen/X86/GlobalISel/legalize-sub.mir b/llvm/test/CodeGen/X86/GlobalISel/legalize-sub.mir index d48b5ff..eeb89eb 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/legalize-sub.mir +++ b/llvm/test/CodeGen/X86/GlobalISel/legalize-sub.mir @@ -1,10 +1,15 @@ # 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 --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: llc -O0 -mtriple=x86_64-linux-gnu -run-pass=legalizer -global-isel-abort=2 -pass-remarks-missed='gisel*' %s 2>%t -o - | FileCheck %s --check-prefixes=CHECK,X64 +# RUN: FileCheck -check-prefix=ERR64 %s < %t + +# 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-prefixes=CHECK,X32 # RUN: FileCheck -check-prefix=ERR32 %s < %t +# ERR64: remark: :0:0: unable to legalize instruction: %11:_(s64), %12:_(s1) = G_USUBE %6:_, %8:_, %10:_ (in function: test_sub_i128) + # ERR32: remark: :0:0: unable to legalize instruction: %13:_(s32), %14:_(s1) = G_USUBE %8:_, %10:_, %12:_ (in function: test_sub_i42) # ERR32: remark: :0:0: unable to legalize instruction: %9:_(s32), %10:_(s1) = G_USUBE %4:_, %6:_, %8:_ (in function: test_sub_i64) +# ERR32: remark: :0:0: unable to legalize instruction: %19:_(s32), %20:_(s1) = G_USUBE %8:_, %12:_, %18:_ (in function: test_sub_i128) --- | @@ -15,11 +20,11 @@ define void @test_sub_i32() { ret void } define void @test_sub_i42() { ret void } define void @test_sub_i64() { ret void } + define void @test_sub_i128() { ret void } ... --- name: test_sub_i1 -# CHECK-LABEL: name: test_sub_i1 alignment: 16 legalized: false regBankSelected: false @@ -29,22 +34,14 @@ registers: - { id: 2, class: _, preferred-register: '' } body: | bb.1 (%ir-block.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 + ; CHECK-LABEL: name: test_sub_i1 + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edx + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32) + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC1]] + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s8) + ; CHECK-NEXT: $eax = COPY [[ANYEXT]](s32) + ; CHECK-NEXT: RET 0 %0(s32) = COPY $edx %1(s1) = G_TRUNC %0(s32) %2(s1) = G_SUB %1, %1 @@ -54,7 +51,6 @@ body: | ... --- name: test_sub_i8 -# CHECK-LABEL: name: test_sub_i1 alignment: 16 legalized: false regBankSelected: false @@ -62,27 +58,15 @@ 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 + ; CHECK-LABEL: name: test_sub_i8 + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edx + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s8) = G_SUB [[TRUNC]], [[TRUNC]] + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s8) + ; CHECK-NEXT: $eax = COPY [[ANYEXT]](s32) + ; CHECK-NEXT: RET 0 %0(s32) = COPY $edx %1(s8) = G_TRUNC %0(s32) %2(s8) = G_SUB %1, %1 @@ -101,20 +85,13 @@ registers: - { 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 + ; CHECK-LABEL: name: test_sub_i16 + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edx + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[TRUNC]], [[TRUNC]] + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUB]](s16) + ; CHECK-NEXT: $eax = COPY [[ANYEXT]](s32) + ; CHECK-NEXT: RET 0 %0(s32) = COPY $edx %1(s16) = G_TRUNC %0(s32) %2(s16) = G_SUB %1, %1 @@ -133,16 +110,11 @@ registers: - { 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 + ; CHECK-LABEL: name: test_sub_i27 + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edx + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY]] + ; CHECK-NEXT: $eax = COPY [[SUB]](s32) + ; CHECK-NEXT: RET 0 %0(s32) = COPY $edx %1(s27) = G_TRUNC %0(s32) %2(s27) = G_SUB %1, %1 @@ -161,18 +133,12 @@ registers: - { id: 2, class: _ } body: | bb.1 (%ir-block.0): - ; 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 + ; CHECK-LABEL: name: test_sub_i32 + ; CHECK: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = IMPLICIT_DEF + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[DEF]], [[DEF1]] + ; CHECK-NEXT: $eax = COPY [[SUB]](s32) + ; CHECK-NEXT: RET 0 %0(s32) = IMPLICIT_DEF %1(s32) = IMPLICIT_DEF %2(s32) = G_SUB %0, %1 @@ -249,3 +215,48 @@ body: | $rax = COPY %2 RET 0 ... +--- +name: test_sub_i128 +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_i128 + ; X64: [[DEF:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X64-NEXT: [[DEF1:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X64-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[DEF]](s128) + ; X64-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[DEF1]](s128) + ; X64-NEXT: [[USUBO:%[0-9]+]]:_(s64), [[USUBO1:%[0-9]+]]:_(s1) = G_USUBO [[UV]], [[UV2]] + ; X64-NEXT: [[USUBE:%[0-9]+]]:_(s64), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[UV1]], [[UV3]], [[USUBO1]] + ; X64-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[USUBO]](s64), [[USUBE]](s64) + ; X64-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s128) + ; X64-NEXT: $rax = COPY [[UV4]](s64) + ; X64-NEXT: $rdx = COPY [[UV5]](s64) + ; X64-NEXT: RET 0 + ; X32-LABEL: name: test_sub_i128 + ; X32: [[DEF:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X32-NEXT: [[DEF1:%[0-9]+]]:_(s128) = IMPLICIT_DEF + ; X32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32), [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](s128) + ; X32-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32), [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF1]](s128) + ; X32-NEXT: [[USUBO:%[0-9]+]]:_(s32), [[USUBO1:%[0-9]+]]:_(s1) = G_USUBO [[UV]], [[UV4]] + ; X32-NEXT: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[UV1]], [[UV5]], [[USUBO1]] + ; X32-NEXT: [[USUBE2:%[0-9]+]]:_(s32), [[USUBE3:%[0-9]+]]:_(s1) = G_USUBE [[UV2]], [[UV6]], [[USUBE1]] + ; X32-NEXT: [[USUBE4:%[0-9]+]]:_(s32), [[USUBE5:%[0-9]+]]:_(s1) = G_USUBE [[UV3]], [[UV7]], [[USUBE3]] + ; X32-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[USUBO]](s32), [[USUBE]](s32), [[USUBE2]](s32), [[USUBE4]](s32) + ; X32-NEXT: [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s128) + ; X32-NEXT: $rax = COPY [[UV8]](s64) + ; X32-NEXT: $rdx = COPY [[UV9]](s64) + ; X32-NEXT: RET 0 + %0(s128) = IMPLICIT_DEF + %1(s128) = IMPLICIT_DEF + %2(s128) = G_SUB %0, %1 + %3:_(s64), %4:_(s64) = G_UNMERGE_VALUES %2(s128) + $rax = COPY %3 + $rdx = COPY %4 + RET 0 +... diff --git a/llvm/test/CodeGen/X86/GlobalISel/sub-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/sub-scalar.ll index 8bf1b2fd..982567c 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/sub-scalar.ll +++ b/llvm/test/CodeGen/X86/GlobalISel/sub-scalar.ll @@ -1,5 +1,39 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64 +; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=2 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64 +; RUN: llc -mtriple=i386-linux-gnu -global-isel -global-isel-abort=2 -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X86 + +define i128 @test_sub_i128(i128 %arg1, i128 %arg2) nounwind { +; X64-LABEL: test_sub_i128: +; X64: # %bb.0: +; X64-NEXT: movq %rdi, %rax +; X64-NEXT: subq %rdx, %rax +; X64-NEXT: sbbq %rcx, %rsi +; X64-NEXT: movq %rsi, %rdx +; X64-NEXT: retq +; +; X86-LABEL: test_sub_i128: +; X86: # %bb.0: +; X86-NEXT: pushl %edi +; X86-NEXT: pushl %esi +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %esi +; X86-NEXT: movl {{[0-9]+}}(%esp), %edi +; X86-NEXT: subl {{[0-9]+}}(%esp), %esi +; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edi +; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl %ecx, 8(%eax) +; X86-NEXT: movl %edi, 4(%eax) +; X86-NEXT: movl %esi, (%eax) +; X86-NEXT: movl %edx, 12(%eax) +; X86-NEXT: popl %esi +; X86-NEXT: popl %edi +; X86-NEXT: retl $4 + %ret = sub i128 %arg1, %arg2 + ret i128 %ret +} define i64 @test_sub_i64(i64 %arg1, i64 %arg2) { ; X64-LABEL: test_sub_i64: @@ -7,6 +41,14 @@ define i64 @test_sub_i64(i64 %arg1, i64 %arg2) { ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax ; X64-NEXT: retq +; +; X86-LABEL: test_sub_i64: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: subl {{[0-9]+}}(%esp), %eax +; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx +; X86-NEXT: retl %ret = sub i64 %arg1, %arg2 ret i64 %ret } @@ -17,6 +59,12 @@ define i32 @test_sub_i32(i32 %arg1, i32 %arg2) { ; X64-NEXT: movl %edi, %eax ; X64-NEXT: subl %esi, %eax ; X64-NEXT: retq +; +; X86-LABEL: test_sub_i32: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: subl {{[0-9]+}}(%esp), %eax +; X86-NEXT: retl %ret = sub i32 %arg1, %arg2 ret i32 %ret } @@ -28,6 +76,14 @@ define i16 @test_sub_i16(i16 %arg1, i16 %arg2) { ; X64-NEXT: subw %si, %ax ; X64-NEXT: # kill: def $ax killed $ax killed $eax ; X64-NEXT: retq +; +; X86-LABEL: test_sub_i16: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: subw %cx, %ax +; X86-NEXT: # kill: def $ax killed $ax killed $eax +; X86-NEXT: retl %ret = sub i16 %arg1, %arg2 ret i16 %ret } @@ -39,6 +95,14 @@ define i8 @test_sub_i8(i8 %arg1, i8 %arg2) { ; X64-NEXT: subb %sil, %al ; X64-NEXT: # kill: def $al killed $al killed $eax ; X64-NEXT: retq +; +; X86-LABEL: test_sub_i8: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: subb %cl, %al +; X86-NEXT: # kill: def $al killed $al killed $eax +; X86-NEXT: retl %ret = sub i8 %arg1, %arg2 ret i8 %ret } @@ -46,13 +110,24 @@ define i8 @test_sub_i8(i8 %arg1, i8 %arg2) { define i32 @test_sub_i1(i32 %arg1, i32 %arg2) { ; X64-LABEL: test_sub_i1: ; X64: # %bb.0: -; X64-NEXT: subb %sil, %dil -; X64-NEXT: movzbl %dil, %eax +; X64-NEXT: cmpl %esi, %edi +; X64-NEXT: sete %al +; X64-NEXT: subb %al, %al +; X64-NEXT: movzbl %al, %eax ; X64-NEXT: andl $1, %eax ; X64-NEXT: retq - %a1 = trunc i32 %arg1 to i1 - %a2 = trunc i32 %arg2 to i1 - %x = sub i1 %a1 , %a2 +; +; X86-LABEL: test_sub_i1: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: cmpl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: sete %al +; X86-NEXT: subb %al, %al +; X86-NEXT: movzbl %al, %eax +; X86-NEXT: andl $1, %eax +; X86-NEXT: retl + %c = icmp eq i32 %arg1, %arg2 + %x = sub i1 %c , %c %ret = zext i1 %x to i32 ret i32 %ret } -- 2.7.4