1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

[GlobalISel][X86] extend G_ZEXT support.

Summary:
Mark G_ZEXT/G_SEXT i1 to i8/i16,  i8 to i16 as legal.
Support G_ZEXT i1 to i8/i16 instruction selection ( C++ code).
This patch requred to support G_LOAD/G_STORE i1.

Reviewers: zvi, guyblank

Reviewed By: guyblank

Subscribers: rovka, llvm-commits, kristof.beyls

Differential Revision: https://reviews.llvm.org/D35177

llvm-svn: 307526
This commit is contained in:
Igor Breger 2017-07-10 09:07:34 +00:00
parent 69173e21c2
commit 1577d53536
5 changed files with 300 additions and 26 deletions

View File

@ -637,37 +637,40 @@ bool X86InstructionSelector::selectZext(MachineInstr &I,
const LLT DstTy = MRI.getType(DstReg);
const LLT SrcTy = MRI.getType(SrcReg);
if (SrcTy == LLT::scalar(1)) {
if (SrcTy != LLT::scalar(1))
return false;
unsigned AndOpc;
if (DstTy == LLT::scalar(32))
AndOpc = X86::AND32ri8;
else if (DstTy == LLT::scalar(64))
AndOpc = X86::AND64ri8;
else
return false;
unsigned DefReg =
MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
unsigned AndOpc;
if (DstTy == LLT::scalar(8))
AndOpc = X86::AND8ri8;
else if (DstTy == LLT::scalar(16))
AndOpc = X86::AND16ri8;
else if (DstTy == LLT::scalar(32))
AndOpc = X86::AND32ri8;
else if (DstTy == LLT::scalar(64))
AndOpc = X86::AND64ri8;
else
return false;
unsigned DefReg = SrcReg;
if (DstTy != LLT::scalar(8)) {
DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
.addImm(0)
.addReg(SrcReg)
.addImm(X86::sub_8bit);
MachineInstr &AndInst =
*BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
.addReg(DefReg)
.addImm(1);
constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
I.eraseFromParent();
return true;
}
return false;
MachineInstr &AndInst =
*BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
.addReg(DefReg)
.addImm(1);
constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
I.eraseFromParent();
return true;
}
bool X86InstructionSelector::selectCmp(MachineInstr &I,

View File

@ -91,8 +91,10 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar);
// Extensions
setAction({G_ZEXT, s32}, Legal);
setAction({G_SEXT, s32}, Legal);
for (auto Ty : {s8, s16, s32}) {
setAction({G_ZEXT, Ty}, Legal);
setAction({G_SEXT, Ty}, Legal);
}
for (auto Ty : {s1, s8, s16}) {
setAction({G_ZEXT, 1, Ty}, Legal);
@ -148,7 +150,7 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
// Extensions
for (auto Ty : {s32, s64}) {
for (auto Ty : {s8, s16, s32, s64}) {
setAction({G_ZEXT, Ty}, Legal);
setAction({G_SEXT, Ty}, Legal);
}

View File

@ -2,6 +2,42 @@
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
; RUN: llc -mtriple=i386-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X32
define i8 @test_zext_i1toi8(i32 %a) {
; X64-LABEL: test_zext_i1toi8:
; X64: # BB#0:
; X64-NEXT: andb $1, %dil
; X64-NEXT: movl %edi, %eax
; X64-NEXT: retq
;
; X32-LABEL: test_zext_i1toi8:
; X32: # BB#0:
; X32-NEXT: movl 4(%esp), %eax
; X32-NEXT: andb $1, %al
; X32-NEXT: # kill: %AL<def> %AL<kill> %EAX<kill>
; X32-NEXT: retl
%val = trunc i32 %a to i1
%r = zext i1 %val to i8
ret i8 %r
}
define i16 @test_zext_i1toi16(i32 %a) {
; X64-LABEL: test_zext_i1toi16:
; X64: # BB#0:
; X64-NEXT: andw $1, %di
; X64-NEXT: movl %edi, %eax
; X64-NEXT: retq
;
; X32-LABEL: test_zext_i1toi16:
; X32: # BB#0:
; X32-NEXT: movl 4(%esp), %eax
; X32-NEXT: andw $1, %ax
; X32-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
; X32-NEXT: retl
%val = trunc i32 %a to i1
%r = zext i1 %val to i16
ret i16 %r
}
define i32 @test_zext_i1(i32 %a) {
; X64-LABEL: test_zext_i1:
; X64: # BB#0:

View File

@ -1,12 +1,28 @@
# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
--- |
define i32 @test_zext_i1(i8 %a) {
define i8 @test_zext_i1toi8(i1 %a) {
%r = zext i1 %a to i8
ret i8 %r
}
define i16 @test_zext_i1toi16(i1 %a) {
%r = zext i1 %a to i16
ret i16 %r
}
define i32 @test_zext_i1(i8 %a) {
%val = trunc i8 %a to i1
%r = zext i1 %val to i32
ret i32 %r
}
define i16 @test_zext_i8toi16(i8 %val) {
%r = zext i8 %val to i16
ret i16 %r
}
define i32 @test_zext_i8(i8 %val) {
%r = zext i8 %val to i32
ret i32 %r
@ -17,12 +33,27 @@
ret i32 %r
}
define i8 @test_sext_i1toi8(i1 %a) {
%r = sext i1 %a to i8
ret i8 %r
}
define i16 @test_sext_i1toi16(i1 %a) {
%r = sext i1 %a to i16
ret i16 %r
}
define i32 @test_sext_i1(i8 %a) {
%val = trunc i8 %a to i1
%r = sext i1 %val to i32
ret i32 %r
}
define i16 @test_sext_i8toi16(i8 %val) {
%r = sext i8 %val to i16
ret i16 %r
}
define i32 @test_sext_i8(i8 %val) {
%r = sext i8 %val to i32
ret i32 %r
@ -33,6 +64,52 @@
ret i32 %r
}
...
---
name: test_zext_i1toi8
# ALL-LABEL: name: test_zext_i1toi8
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
# ALL: %0(s1) = COPY %edi
# ALL-NEXT: %1(s8) = G_ZEXT %0(s1)
# ALL-NEXT: %al = COPY %1(s8)
# ALL-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s1) = COPY %edi
%1(s8) = G_ZEXT %0(s1)
%al = COPY %1(s8)
RET 0, implicit %al
...
---
name: test_zext_i1toi16
# ALL-LABEL: name: test_zext_i1toi16
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
# ALL: %0(s1) = COPY %edi
# ALL-NEXT: %1(s16) = G_ZEXT %0(s1)
# ALL-NEXT: %ax = COPY %1(s16)
# ALL-NEXT: RET 0, implicit %ax
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s1) = COPY %edi
%1(s16) = G_ZEXT %0(s1)
%ax = COPY %1(s16)
RET 0, implicit %ax
...
---
name: test_zext_i1
@ -59,6 +136,29 @@ body: |
%eax = COPY %2(s32)
RET 0, implicit %eax
...
---
name: test_zext_i8toi16
# ALL-LABEL: name: test_zext_i8toi16
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
# ALL: %0(s8) = COPY %edi
# ALL-NEXT: %1(s16) = G_ZEXT %0(s8)
# ALL-NEXT: %ax = COPY %1(s16)
# ALL-NEXT: RET 0, implicit %ax
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s8) = COPY %edi
%1(s16) = G_ZEXT %0(s8)
%ax = COPY %1(s16)
RET 0, implicit %ax
...
---
name: test_zext_i8
@ -105,6 +205,52 @@ body: |
%eax = COPY %1(s32)
RET 0, implicit %eax
...
---
name: test_sext_i1toi8
# ALL-LABEL: name: test_sext_i1toi8
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
# ALL: %0(s1) = COPY %edi
# ALL-NEXT: %1(s8) = G_SEXT %0(s1)
# ALL-NEXT: %al = COPY %1(s8)
# ALL-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s1) = COPY %edi
%1(s8) = G_SEXT %0(s1)
%al = COPY %1(s8)
RET 0, implicit %al
...
---
name: test_sext_i1toi16
# ALL-LABEL: name: test_sext_i1toi16
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
# ALL: %0(s1) = COPY %edi
# ALL-NEXT: %1(s16) = G_SEXT %0(s1)
# ALL-NEXT: %ax = COPY %1(s16)
# ALL-NEXT: RET 0, implicit %ax
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s1) = COPY %edi
%1(s16) = G_SEXT %0(s1)
%ax = COPY %1(s16)
RET 0, implicit %ax
...
---
name: test_sext_i1
@ -131,6 +277,29 @@ body: |
%eax = COPY %2(s32)
RET 0, implicit %eax
...
---
name: test_sext_i8toi16
# ALL-LABEL: name: test_sext_i8toi16
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
# ALL: %0(s8) = COPY %edi
# ALL-NEXT: %1(s16) = G_SEXT %0(s8)
# ALL-NEXT: %ax = COPY %1(s16)
# ALL-NEXT: RET 0, implicit %ax
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s8) = COPY %edi
%1(s16) = G_SEXT %0(s8)
%ax = COPY %1(s16)
RET 0, implicit %ax
...
---
name: test_sext_i8

View File

@ -2,6 +2,16 @@
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
--- |
define i8 @test_zext_i1toi8(i1 %a) {
%r = zext i1 %a to i8
ret i8 %r
}
define i16 @test_zext_i1toi16(i1 %a) {
%r = zext i1 %a to i16
ret i16 %r
}
define i32 @test_zext_i1(i1 %a) {
%r = zext i1 %a to i32
ret i32 %r
@ -27,6 +37,60 @@
ret i32 %r
}
...
---
name: test_zext_i1toi8
# ALL-LABEL: name: test_zext_i1toi8
alignment: 4
legalized: true
regBankSelected: true
# ALL: registers:
# ALL-NEXT: - { id: 0, class: gr8, preferred-register: '' }
# ALL-NEXT: - { id: 1, class: gr8, preferred-register: '' }
registers:
- { id: 0, class: gpr, preferred-register: '' }
- { id: 1, class: gpr, preferred-register: '' }
# ALL: %0 = COPY %dil
# ALL-NEXT: %1 = AND8ri8 %0, 1, implicit-def %eflags
# ALL-NEXT: %al = COPY %1
# ALL-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s1) = COPY %edi
%1(s8) = G_ZEXT %0(s1)
%al = COPY %1(s8)
RET 0, implicit %al
...
---
name: test_zext_i1toi16
# ALL-LABEL: name: test_zext_i1toi16
alignment: 4
legalized: true
regBankSelected: true
# ALL: registers:
# ALL-NEXT: - { id: 0, class: gr8, preferred-register: '' }
# ALL-NEXT: - { id: 1, class: gr16, preferred-register: '' }
# ALL-NEXT: - { id: 2, class: gr16, preferred-register: '' }
registers:
- { id: 0, class: gpr, preferred-register: '' }
- { id: 1, class: gpr, preferred-register: '' }
# ALL: %0 = COPY %dil
# ALL-NEXT: %2 = SUBREG_TO_REG 0, %0, 1
# ALL-NEXT: %1 = AND16ri8 %2, 1, implicit-def %eflags
# ALL-NEXT: %ax = COPY %1
# ALL-NEXT: RET 0, implicit %ax
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s1) = COPY %edi
%1(s16) = G_ZEXT %0(s1)
%ax = COPY %1(s16)
RET 0, implicit %ax
...
---
name: test_zext_i1