From: Igor Breger Date: Sun, 17 Sep 2017 11:34:17 +0000 (+0000) Subject: [GlobalISel][X86] Legalize i1 G_ADD/G_SUB/G_MUL/G_XOR/G_OR/G_AND instructions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1183423ec59f4e423ace9306df388ad65e414a32;p=llvm [GlobalISel][X86] Legalize i1 G_ADD/G_SUB/G_MUL/G_XOR/G_OR/G_AND instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313483 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86LegalizerInfo.cpp b/lib/Target/X86/X86LegalizerInfo.cpp index 6bbb3f3c7e6..98b4863134e 100644 --- a/lib/Target/X86/X86LegalizerInfo.cpp +++ b/lib/Target/X86/X86LegalizerInfo.cpp @@ -57,10 +57,13 @@ void X86LegalizerInfo::setLegalizerInfo32bit() { setAction({G_PHI, s1}, WidenScalar); - for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) + for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { for (auto Ty : {s8, s16, s32}) setAction({BinOp, Ty}, Legal); + setAction({BinOp, s1}, WidenScalar); + } + for (unsigned Op : {G_UADDE}) { setAction({Op, s32}, Legal); setAction({Op, 1, s1}, Legal); diff --git a/test/CodeGen/X86/GlobalISel/add-scalar.ll b/test/CodeGen/X86/GlobalISel/add-scalar.ll index a5dc7906363..1718bf28bfa 100644 --- a/test/CodeGen/X86/GlobalISel/add-scalar.ll +++ b/test/CodeGen/X86/GlobalISel/add-scalar.ll @@ -78,3 +78,26 @@ define i8 @test_add_i8(i8 %arg1, i8 %arg2) { %ret = add i8 %arg1, %arg2 ret i8 %ret } + +define i32 @test_add_i1(i32 %arg1, i32 %arg2) { +; X64-LABEL: test_add_i1: +; X64: # BB#0: +; X64-NEXT: cmpl %esi, %edi +; X64-NEXT: sete %al +; X64-NEXT: addb %al, %al +; X64-NEXT: andl $1, %eax +; X64-NEXT: retq +; +; X32-LABEL: test_add_i1: +; X32: # BB#0: +; X32-NEXT: movl 8(%esp), %eax +; X32-NEXT: cmpl %eax, 4(%esp) +; X32-NEXT: sete %al +; X32-NEXT: addb %al, %al +; X32-NEXT: andl $1, %eax +; X32-NEXT: retl + %c = icmp eq i32 %arg1, %arg2 + %x = add i1 %c , %c + %ret = zext i1 %x to i32 + ret i32 %ret +} diff --git a/test/CodeGen/X86/GlobalISel/and-scalar.ll b/test/CodeGen/X86/GlobalISel/and-scalar.ll index b1932142108..12d56a8a67f 100644 --- a/test/CodeGen/X86/GlobalISel/and-scalar.ll +++ b/test/CodeGen/X86/GlobalISel/and-scalar.ll @@ -1,6 +1,20 @@ ; 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=ALL +define i32 @test_and_i1(i32 %arg1, i32 %arg2) { +; ALL-LABEL: test_and_i1: +; ALL: # BB#0: +; ALL-NEXT: cmpl %esi, %edi +; ALL-NEXT: sete %al +; ALL-NEXT: andb %al, %al +; ALL-NEXT: andl $1, %eax +; ALL-NEXT: retq + %c = icmp eq i32 %arg1, %arg2 + %x = and i1 %c , %c + %ret = zext i1 %x to i32 + ret i32 %ret +} + define i8 @test_and_i8(i8 %arg1, i8 %arg2) { ; ALL-LABEL: test_and_i8: ; ALL: # BB#0: diff --git a/test/CodeGen/X86/GlobalISel/legalize-add.mir b/test/CodeGen/X86/GlobalISel/legalize-add.mir index 6a03388da94..4b4b1a8f31a 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-add.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-add.mir @@ -1,16 +1,37 @@ # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64 # RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32 --- | - define void @test_add_i32() { - ret void - } - define void @test_add_i64() { - ret void - } + define void @test_add_i1() { ret void} + define void @test_add_i32() { ret void } + define void @test_add_i64() { ret void } ... --- +name: test_add_i1 +# CHECK-LABEL: name: test_add_i1 +alignment: 4 +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_ADD %3, %4 +# CHECK-NEXT: %2(s1) = G_TRUNC %5(s8) +# CHECK-NEXT: RET 0 +body: | + bb.1 (%ir-block.0): + + %0(s32) = COPY %edx + %1(s1) = G_TRUNC %0(s32) + %2(s1) = G_ADD %1, %1 + RET 0 +... +--- name: test_add_i32 # ALL-LABEL: name: test_add_i32 alignment: 4 diff --git a/test/CodeGen/X86/GlobalISel/legalize-and-scalar.mir b/test/CodeGen/X86/GlobalISel/legalize-and-scalar.mir index b57db15d464..a34b4eacf11 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-and-scalar.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-and-scalar.mir @@ -1,6 +1,11 @@ # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --- | + define i1 @test_and_i1() { + %ret = and i1 undef, undef + ret i1 %ret + } + define i8 @test_and_i8() { %ret = and i8 undef, undef ret i8 %ret @@ -23,6 +28,30 @@ ... --- +name: test_and_i1 +# CHECK-LABEL: name: test_and_i1 +alignment: 4 +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_AND %3, %4 +# CHECK-NEXT: %2(s1) = G_TRUNC %5(s8) +# CHECK-NEXT: RET 0 +body: | + bb.1 (%ir-block.0): + + %0(s32) = COPY %edx + %1(s1) = G_TRUNC %0(s32) + %2(s1) = G_AND %1, %1 + RET 0 +... +--- name: test_and_i8 # CHECK-LABEL: name: test_and_i8 alignment: 4 diff --git a/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir b/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir index 2216e0b3699..49a317e4f76 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir @@ -1,6 +1,8 @@ # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --- | + define void @test_mul_i1() { ret void} + define i16 @test_mul_i16(i16 %arg1, i16 %arg2) { %ret = mul i16 %arg1, %arg2 ret i16 %ret @@ -18,6 +20,30 @@ ... --- +name: test_mul_i1 +# CHECK-LABEL: name: test_mul_i1 +alignment: 4 +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_MUL %3, %4 +# CHECK-NEXT: %2(s1) = G_TRUNC %5(s8) +# CHECK-NEXT: RET 0 +body: | + bb.1 (%ir-block.0): + + %0(s32) = COPY %edx + %1(s1) = G_TRUNC %0(s32) + %2(s1) = G_MUL %1, %1 + RET 0 +... +--- name: test_mul_i16 # CHECK-LABEL: name: test_mul_i16 alignment: 4 diff --git a/test/CodeGen/X86/GlobalISel/legalize-or-scalar.mir b/test/CodeGen/X86/GlobalISel/legalize-or-scalar.mir index a014f56a358..c233e8bcca7 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-or-scalar.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-or-scalar.mir @@ -1,6 +1,11 @@ # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --- | + define i1 @test_or_i1() { + %ret = or i1 undef, undef + ret i1 %ret + } + define i8 @test_or_i8() { %ret = or i8 undef, undef ret i8 %ret @@ -23,6 +28,30 @@ ... --- +name: test_or_i1 +# CHECK-LABEL: name: test_or_i1 +alignment: 4 +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_OR %3, %4 +# CHECK-NEXT: %2(s1) = G_TRUNC %5(s8) +# CHECK-NEXT: RET 0 +body: | + bb.1 (%ir-block.0): + + %0(s32) = COPY %edx + %1(s1) = G_TRUNC %0(s32) + %2(s1) = G_OR %1, %1 + RET 0 +... +--- name: test_or_i8 # CHECK-LABEL: name: test_or_i8 alignment: 4 diff --git a/test/CodeGen/X86/GlobalISel/legalize-sub.mir b/test/CodeGen/X86/GlobalISel/legalize-sub.mir index 26ef285929a..66baa8752f0 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-sub.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-sub.mir @@ -1,10 +1,8 @@ # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --- | - ; ModuleID = '' - source_filename = "" - target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" - target triple = "x86_64--linux-gnu" + + define void @test_sub_i1() { ret void} define i32 @test_sub_i32(i32 %arg1, i32 %arg2) { %ret = sub i32 %arg1, %arg2 @@ -13,23 +11,48 @@ ... --- +name: test_sub_i1 +# CHECK-LABEL: name: test_sub_i1 +alignment: 4 +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-NEXT: %2(s1) = G_TRUNC %5(s8) +# CHECK-NEXT: RET 0 +body: | + bb.1 (%ir-block.0): + + %0(s32) = COPY %edx + %1(s1) = G_TRUNC %0(s32) + %2(s1) = G_SUB %1, %1 + RET 0 +... +--- name: test_sub_i32 +# CHECK-LABEL: name: test_sub_i32 alignment: 4 legalized: false regBankSelected: false -selected: false tracksRegLiveness: true registers: - { id: 0, class: _ } - { id: 1, class: _ } - { id: 2, class: _ } +# CHECK: %0(s32) = COPY %edi +# CHECK-NEXT: %1(s32) = COPY %esi +# CHECK-NEXT: %2(s32) = G_SUB %0, %1 +# CHECK-NEXT: %eax = COPY %2(s32) +# CHECK-NEXT: RET 0, implicit %eax body: | bb.1 (%ir-block.0): liveins: %edi, %esi - ; CHECK-LABEL: name: test_sub_i32 - ; CHECK: [[VAL1:%.*]](s32) = COPY %edi - ; CHECK: [[VAL2:%.*]](s32) = COPY %esi - ; CHECK: [[RES:%.*]](s32) = G_SUB [[VAL1:%.*]], [[VAL2:%.*]] %0(s32) = COPY %edi %1(s32) = COPY %esi diff --git a/test/CodeGen/X86/GlobalISel/legalize-xor-scalar.mir b/test/CodeGen/X86/GlobalISel/legalize-xor-scalar.mir index e2af9128302..84388f8c264 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-xor-scalar.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-xor-scalar.mir @@ -1,6 +1,11 @@ # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --- | + define i1 @test_xor_i1() { + %ret = xor i1 undef, undef + ret i1 %ret + } + define i8 @test_xor_i8() { %ret = xor i8 undef, undef ret i8 %ret @@ -23,6 +28,30 @@ ... --- +name: test_xor_i1 +# CHECK-LABEL: name: test_xor_i1 +alignment: 4 +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_XOR %3, %4 +# CHECK-NEXT: %2(s1) = G_TRUNC %5(s8) +# CHECK-NEXT: RET 0 +body: | + bb.1 (%ir-block.0): + + %0(s32) = COPY %edx + %1(s1) = G_TRUNC %0(s32) + %2(s1) = G_XOR %1, %1 + RET 0 +... +--- name: test_xor_i8 # CHECK-LABEL: name: test_xor_i8 alignment: 4 diff --git a/test/CodeGen/X86/GlobalISel/or-scalar.ll b/test/CodeGen/X86/GlobalISel/or-scalar.ll index b0371457f76..72566ffc49c 100644 --- a/test/CodeGen/X86/GlobalISel/or-scalar.ll +++ b/test/CodeGen/X86/GlobalISel/or-scalar.ll @@ -1,6 +1,20 @@ ; 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=ALL +define i32 @test_or_i1(i32 %arg1, i32 %arg2) { +; ALL-LABEL: test_or_i1: +; ALL: # BB#0: +; ALL-NEXT: cmpl %esi, %edi +; ALL-NEXT: sete %al +; ALL-NEXT: orb %al, %al +; ALL-NEXT: andl $1, %eax +; ALL-NEXT: retq + %c = icmp eq i32 %arg1, %arg2 + %x = or i1 %c , %c + %ret = zext i1 %x to i32 + ret i32 %ret +} + define i8 @test_or_i8(i8 %arg1, i8 %arg2) { ; ALL-LABEL: test_or_i8: ; ALL: # BB#0: diff --git a/test/CodeGen/X86/GlobalISel/sub-scalar.ll b/test/CodeGen/X86/GlobalISel/sub-scalar.ll new file mode 100644 index 00000000000..8719e9dfb6e --- /dev/null +++ b/test/CodeGen/X86/GlobalISel/sub-scalar.ll @@ -0,0 +1,56 @@ +; 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 + +define i64 @test_sub_i64(i64 %arg1, i64 %arg2) { +; X64-LABEL: test_sub_i64: +; X64: # BB#0: +; X64-NEXT: subq %rsi, %rdi +; X64-NEXT: movq %rdi, %rax +; X64-NEXT: retq + %ret = sub i64 %arg1, %arg2 + ret i64 %ret +} + +define i32 @test_sub_i32(i32 %arg1, i32 %arg2) { +; X64-LABEL: test_sub_i32: +; X64: # BB#0: +; X64-NEXT: subl %esi, %edi +; X64-NEXT: movl %edi, %eax +; X64-NEXT: retq + %ret = sub i32 %arg1, %arg2 + ret i32 %ret +} + +define i16 @test_sub_i16(i16 %arg1, i16 %arg2) { +; X64-LABEL: test_sub_i16: +; X64: # BB#0: +; X64-NEXT: subw %si, %di +; X64-NEXT: movl %edi, %eax +; X64-NEXT: retq + %ret = sub i16 %arg1, %arg2 + ret i16 %ret +} + +define i8 @test_sub_i8(i8 %arg1, i8 %arg2) { +; X64-LABEL: test_sub_i8: +; X64: # BB#0: +; X64-NEXT: subb %sil, %dil +; X64-NEXT: movl %edi, %eax +; X64-NEXT: retq + %ret = sub i8 %arg1, %arg2 + ret i8 %ret +} + +define i32 @test_sub_i1(i32 %arg1, i32 %arg2) { +; X64-LABEL: test_sub_i1: +; X64: # BB#0: +; X64-NEXT: subb %sil, %dil +; X64-NEXT: andl $1, %edi +; X64-NEXT: movl %edi, %eax +; X64-NEXT: retq + %a1 = trunc i32 %arg1 to i1 + %a2 = trunc i32 %arg2 to i1 + %x = sub i1 %a1 , %a2 + %ret = zext i1 %x to i32 + ret i32 %ret +} diff --git a/test/CodeGen/X86/GlobalISel/xor-scalar.ll b/test/CodeGen/X86/GlobalISel/xor-scalar.ll index 9941db8abd9..5c1fcaeeed8 100644 --- a/test/CodeGen/X86/GlobalISel/xor-scalar.ll +++ b/test/CodeGen/X86/GlobalISel/xor-scalar.ll @@ -1,6 +1,20 @@ ; 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=ALL +define i32 @test_xor_i1(i32 %arg1, i32 %arg2) { +; ALL-LABEL: test_xor_i1: +; ALL: # BB#0: +; ALL-NEXT: cmpl %esi, %edi +; ALL-NEXT: sete %al +; ALL-NEXT: xorb %al, %al +; ALL-NEXT: andl $1, %eax +; ALL-NEXT: retq + %c = icmp eq i32 %arg1, %arg2 + %x = xor i1 %c , %c + %ret = zext i1 %x to i32 + ret i32 %ret +} + define i8 @test_xor_i8(i8 %arg1, i8 %arg2) { ; ALL-LABEL: test_xor_i8: ; ALL: # BB#0: