]> granicus.if.org Git - llvm/commitdiff
[GlobalISel][X86] Legalize i1 G_ADD/G_SUB/G_MUL/G_XOR/G_OR/G_AND instructions.
authorIgor Breger <igor.breger@intel.com>
Sun, 17 Sep 2017 11:34:17 +0000 (11:34 +0000)
committerIgor Breger <igor.breger@intel.com>
Sun, 17 Sep 2017 11:34:17 +0000 (11:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313483 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
lib/Target/X86/X86LegalizerInfo.cpp
test/CodeGen/X86/GlobalISel/add-scalar.ll
test/CodeGen/X86/GlobalISel/and-scalar.ll
test/CodeGen/X86/GlobalISel/legalize-add.mir
test/CodeGen/X86/GlobalISel/legalize-and-scalar.mir
test/CodeGen/X86/GlobalISel/legalize-mul-scalar.mir
test/CodeGen/X86/GlobalISel/legalize-or-scalar.mir
test/CodeGen/X86/GlobalISel/legalize-sub.mir
test/CodeGen/X86/GlobalISel/legalize-xor-scalar.mir
test/CodeGen/X86/GlobalISel/or-scalar.ll
test/CodeGen/X86/GlobalISel/sub-scalar.ll [new file with mode: 0644]
test/CodeGen/X86/GlobalISel/xor-scalar.ll

index 6bbb3f3c7e685dfaccee19407514d283793d20aa..98b4863134e5ae61446a7bd0e013676252355531 100644 (file)
@@ -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);
index a5dc7906363c9f765ab4bfa78f04c206b5f4bf4c..1718bf28bfae29cb3cae4d7ffe5c551a99ee4342 100644 (file)
@@ -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
+}
index b1932142108778b9405baca794323716f3baeff0..12d56a8a67ff62df44d792dc681cf321282988ab 100644 (file)
@@ -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:
index 6a03388da947198acf8efb883269a9f431b23397..4b4b1a8f31ac5e68457fe1bcd6f3c08dd8e70099 100644 (file)
@@ -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
index b57db15d4646e9f3c6b15db5b28a1613357a7f42..a34b4eacf11beda99cd97bc85003702510b47067 100644 (file)
@@ -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
 
 ...
 ---
+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
index 2216e0b3699bdf744c1263128a2527a31f07e6e6..49a317e4f76794b9b70dd58bae47ee5b10d11257 100644 (file)
@@ -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
 
 ...
 ---
+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
index a014f56a35888960dbf67efa22c5d2ae88f9da38..c233e8bcca75a20c021ff72230f54169706101da 100644 (file)
@@ -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
 
 ...
 ---
+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
index 26ef285929a689fdf2e795549cf7bdf6db27e8e4..66baa8752f012f0a36e6f0400a44485c1bf0c380 100644 (file)
@@ -1,10 +1,8 @@
 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
 
 --- |
-  ; ModuleID = '<stdin>'
-  source_filename = "<stdin>"
-  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
 
 ...
 ---
+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
index e2af91283026eee7c4c0398aca177a99620d765e..84388f8c264887a6b070f58e5054a9b312f80171 100644 (file)
@@ -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
 
 ...
 ---
+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
index b0371457f76e5c42b74ac52ea043eb08af7c3e3d..72566ffc49c637f1d757a4b5b4013e4979d62ca2 100644 (file)
@@ -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 (file)
index 0000000..8719e9d
--- /dev/null
@@ -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
+}
index 9941db8abd9cc67c799493a8f07d34268441f6df..5c1fcaeeed83afffc611e5e5190a843695d2b1f8 100644 (file)
@@ -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: