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:
parent
69173e21c2
commit
1577d53536
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user