mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[GlobalISel][X86] G_ZEXT i1 to i32/i64 support.
Summary: Support G_ZEXT i1 to i32/i64 instruction selection. Reviewers: zvi, guyblank Reviewed By: guyblank Subscribers: rovka, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D32965 llvm-svn: 302623
This commit is contained in:
parent
41f55d04e2
commit
7350527066
@ -71,6 +71,8 @@ private:
|
||||
MachineFunction &MF) const;
|
||||
bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
|
||||
MachineFunction &MF) const;
|
||||
bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
|
||||
MachineFunction &MF) const;
|
||||
|
||||
const X86TargetMachine &TM;
|
||||
const X86Subtarget &STI;
|
||||
@ -226,7 +228,7 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
|
||||
"Generic instruction has unexpected implicit operands\n");
|
||||
|
||||
if (selectImpl(I))
|
||||
return true;
|
||||
return true;
|
||||
|
||||
DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
|
||||
|
||||
@ -241,6 +243,8 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
|
||||
return true;
|
||||
if (selectTrunc(I, MRI, MF))
|
||||
return true;
|
||||
if (selectZext(I, MRI, MF))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -562,6 +566,52 @@ bool X86InstructionSelector::selectTrunc(MachineInstr &I,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool X86InstructionSelector::selectZext(MachineInstr &I,
|
||||
MachineRegisterInfo &MRI,
|
||||
MachineFunction &MF) const {
|
||||
if (I.getOpcode() != TargetOpcode::G_ZEXT)
|
||||
return false;
|
||||
|
||||
const unsigned DstReg = I.getOperand(0).getReg();
|
||||
const unsigned SrcReg = I.getOperand(1).getReg();
|
||||
|
||||
const LLT DstTy = MRI.getType(DstReg);
|
||||
const LLT SrcTy = MRI.getType(SrcReg);
|
||||
|
||||
if (SrcTy == LLT::scalar(1)) {
|
||||
|
||||
unsigned AndOpc;
|
||||
if (DstTy == LLT::scalar(32))
|
||||
AndOpc = X86::AND32ri8;
|
||||
else if (DstTy == LLT::scalar(64))
|
||||
AndOpc = X86::AND64ri8;
|
||||
else
|
||||
return false;
|
||||
|
||||
const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
|
||||
unsigned DefReg =
|
||||
MRI.createVirtualRegister(getRegClassForTypeOnBank(DstTy, RegBank));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
InstructionSelector *
|
||||
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
|
||||
X86Subtarget &Subtarget,
|
||||
|
@ -87,7 +87,7 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
|
||||
setAction({G_ZEXT, s32}, Legal);
|
||||
setAction({G_SEXT, s32}, Legal);
|
||||
|
||||
for (auto Ty : {s8, s16}) {
|
||||
for (auto Ty : {s1, s8, s16}) {
|
||||
setAction({G_ZEXT, 1, Ty}, Legal);
|
||||
setAction({G_SEXT, 1, Ty}, Legal);
|
||||
}
|
||||
@ -139,7 +139,7 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
|
||||
setAction({G_SEXT, Ty}, Legal);
|
||||
}
|
||||
|
||||
for (auto Ty : {s8, s16, s32}) {
|
||||
for (auto Ty : {s1, s8, s16, s32}) {
|
||||
setAction({G_ZEXT, 1, Ty}, Legal);
|
||||
setAction({G_SEXT, 1, Ty}, Legal);
|
||||
}
|
||||
|
@ -1,7 +1,19 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X64
|
||||
|
||||
; TODO merge with ext.ll after i64 sext suported on 32bit platform
|
||||
; TODO merge with ext.ll after i64 sext suported on 32bit platform
|
||||
|
||||
define i64 @test_zext_i1(i8 %a) {
|
||||
; X64-LABEL: test_zext_i1:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: # kill: %DIL<def> %DIL<kill> %RDI<def>
|
||||
; X64-NEXT: andq $1, %rdi
|
||||
; X64-NEXT: movq %rdi, %rax
|
||||
; X64-NEXT: retq
|
||||
%val = trunc i8 %a to i1
|
||||
%r = zext i1 %val to i64
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
define i64 @test_sext_i8(i8 %val) {
|
||||
; X64-LABEL: test_sext_i8:
|
||||
|
@ -2,6 +2,24 @@
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X64
|
||||
; RUN: llc -mtriple=i386-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X32
|
||||
|
||||
define i32 @test_zext_i1(i32 %a) {
|
||||
; X64-LABEL: test_zext_i1:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: andl $1, %edi
|
||||
; X64-NEXT: movl %edi, %eax
|
||||
; X64-NEXT: retq
|
||||
;
|
||||
; X32-LABEL: test_zext_i1:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: leal 4(%esp), %eax
|
||||
; X32-NEXT: movl (%eax), %eax
|
||||
; X32-NEXT: andl $1, %eax
|
||||
; X32-NEXT: retl
|
||||
%val = trunc i32 %a to i1
|
||||
%r = zext i1 %val to i32
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define i32 @test_zext_i8(i8 %val) {
|
||||
; X64-LABEL: test_zext_i8:
|
||||
; X64: # BB#0:
|
||||
|
@ -1,6 +1,12 @@
|
||||
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
|
||||
|
||||
--- |
|
||||
define i64 @test_sext_i1(i8 %a) {
|
||||
%val = trunc i8 %a to i1
|
||||
%r = sext i1 %val to i64
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
define i64 @test_sext_i8(i8 %val) {
|
||||
%r = sext i8 %val to i64
|
||||
ret i64 %r
|
||||
@ -16,6 +22,12 @@
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
define i64 @test_zext_i1(i8 %a) {
|
||||
%val = trunc i8 %a to i1
|
||||
%r = zext i1 %val to i64
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
define i64 @test_zext_i8(i8 %val) {
|
||||
%r = zext i8 %val to i64
|
||||
ret i64 %r
|
||||
@ -31,6 +43,32 @@
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test_sext_i1
|
||||
# CHECK-LABEL: name: test_sext_i1
|
||||
alignment: 4
|
||||
legalized: false
|
||||
regBankSelected: false
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
# CHECK: %0(s8) = COPY %edi
|
||||
# CHECK-NEXT: %1(s1) = G_TRUNC %0(s8)
|
||||
# CHECK-NEXT: %2(s64) = G_SEXT %1(s1)
|
||||
# CHECK-NEXT: %rax = COPY %2(s64)
|
||||
# CHECK-NEXT: RET 0, implicit %rax
|
||||
body: |
|
||||
bb.1 (%ir-block.0):
|
||||
liveins: %edi
|
||||
|
||||
%0(s8) = COPY %edi
|
||||
%1(s1) = G_TRUNC %0(s8)
|
||||
%2(s64) = G_SEXT %1(s1)
|
||||
%rax = COPY %2(s64)
|
||||
RET 0, implicit %rax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_sext_i8
|
||||
@ -100,6 +138,32 @@ body: |
|
||||
%rax = COPY %1(s64)
|
||||
RET 0, implicit %rax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i1
|
||||
# CHECK-LABEL: name: test_zext_i1
|
||||
alignment: 4
|
||||
legalized: false
|
||||
regBankSelected: false
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
# CHECK: %0(s8) = COPY %edi
|
||||
# CHECK-NEXT: %1(s1) = G_TRUNC %0(s8)
|
||||
# CHECK-NEXT: %2(s64) = G_ZEXT %1(s1)
|
||||
# CHECK-NEXT: %rax = COPY %2(s64)
|
||||
# CHECK-NEXT: RET 0, implicit %rax
|
||||
body: |
|
||||
bb.1 (%ir-block.0):
|
||||
liveins: %edi
|
||||
|
||||
%0(s8) = COPY %edi
|
||||
%1(s1) = G_TRUNC %0(s8)
|
||||
%2(s64) = G_ZEXT %1(s1)
|
||||
%rax = COPY %2(s64)
|
||||
RET 0, implicit %rax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i8
|
||||
|
@ -1,6 +1,12 @@
|
||||
# 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) {
|
||||
%val = trunc i8 %a to i1
|
||||
%r = zext i1 %val to i32
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define i32 @test_zext_i8(i8 %val) {
|
||||
%r = zext i8 %val to i32
|
||||
ret i32 %r
|
||||
@ -11,6 +17,12 @@
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define i32 @test_sext_i1(i8 %a) {
|
||||
%val = trunc i8 %a to i1
|
||||
%r = sext i1 %val to i32
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define i32 @test_sext_i8(i8 %val) {
|
||||
%r = sext i8 %val to i32
|
||||
ret i32 %r
|
||||
@ -21,6 +33,32 @@
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i1
|
||||
# ALL-LABEL: name: test_zext_i1
|
||||
alignment: 4
|
||||
legalized: false
|
||||
regBankSelected: false
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
# ALL: %0(s8) = COPY %edi
|
||||
# ALL-NEXT: %1(s1) = G_TRUNC %0(s8)
|
||||
# ALL-NEXT: %2(s32) = G_ZEXT %1(s1)
|
||||
# ALL-NEXT: %eax = COPY %2(s32)
|
||||
# ALL-NEXT: RET 0, implicit %eax
|
||||
body: |
|
||||
bb.1 (%ir-block.0):
|
||||
liveins: %edi
|
||||
|
||||
%0(s8) = COPY %edi
|
||||
%1(s1) = G_TRUNC %0(s8)
|
||||
%2(s32) = G_ZEXT %1(s1)
|
||||
%eax = COPY %2(s32)
|
||||
RET 0, implicit %eax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i8
|
||||
@ -67,6 +105,32 @@ body: |
|
||||
%eax = COPY %1(s32)
|
||||
RET 0, implicit %eax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_sext_i1
|
||||
# ALL-LABEL: name: test_sext_i1
|
||||
alignment: 4
|
||||
legalized: false
|
||||
regBankSelected: false
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
# ALL: %0(s8) = COPY %edi
|
||||
# ALL-NEXT: %1(s1) = G_TRUNC %0(s8)
|
||||
# ALL-NEXT: %2(s32) = G_SEXT %1(s1)
|
||||
# ALL-NEXT: %eax = COPY %2(s32)
|
||||
# ALL-NEXT: RET 0, implicit %eax
|
||||
body: |
|
||||
bb.1 (%ir-block.0):
|
||||
liveins: %edi
|
||||
|
||||
%0(s8) = COPY %edi
|
||||
%1(s1) = G_TRUNC %0(s8)
|
||||
%2(s32) = G_SEXT %1(s1)
|
||||
%eax = COPY %2(s32)
|
||||
RET 0, implicit %eax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_sext_i8
|
||||
|
@ -1,6 +1,12 @@
|
||||
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
|
||||
|
||||
--- |
|
||||
define i64 @test_zext_i1(i8 %a) {
|
||||
%val = trunc i8 %a to i1
|
||||
%r = zext i1 %val to i64
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
define i64 @test_sext_i8(i8 %val) {
|
||||
%r = sext i8 %val to i64
|
||||
ret i64 %r
|
||||
@ -11,6 +17,38 @@
|
||||
ret i64 %r
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i1
|
||||
# ALL-LABEL: name: test_zext_i1
|
||||
alignment: 4
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
# ALL: registers:
|
||||
# ALL-NEXT: - { id: 0, class: gr8 }
|
||||
# ALL-NEXT: - { id: 1, class: gr8 }
|
||||
# ALL-NEXT: - { id: 2, class: gr64 }
|
||||
# ALL-NEXT: - { id: 3, class: gr64 }
|
||||
registers:
|
||||
- { id: 0, class: gpr }
|
||||
- { id: 1, class: gpr }
|
||||
- { id: 2, class: gpr }
|
||||
# ALL: %0 = COPY %dil
|
||||
# ALL-NEXT: %1 = COPY %0
|
||||
# ALL-NEXT: %3 = SUBREG_TO_REG 0, %1, 1
|
||||
# ALL-NEXT: %2 = AND64ri8 %3, 1, implicit-def %eflags
|
||||
# ALL-NEXT: %rax = COPY %2
|
||||
# ALL-NEXT: RET 0, implicit %rax
|
||||
body: |
|
||||
bb.1 (%ir-block.0):
|
||||
liveins: %edi
|
||||
|
||||
%0(s8) = COPY %edi
|
||||
%1(s1) = G_TRUNC %0(s8)
|
||||
%2(s64) = G_ZEXT %1(s1)
|
||||
%rax = COPY %2(s64)
|
||||
RET 0, implicit %rax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_sext_i8
|
||||
|
@ -2,6 +2,11 @@
|
||||
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
|
||||
|
||||
--- |
|
||||
define i32 @test_zext_i1(i1 %a) {
|
||||
%r = zext i1 %a to i32
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define i32 @test_zext_i8(i8 %val) {
|
||||
%r = zext i8 %val to i32
|
||||
ret i32 %r
|
||||
@ -22,6 +27,34 @@
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i1
|
||||
# ALL-LABEL: name: test_zext_i1
|
||||
alignment: 4
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
# ALL: registers:
|
||||
# ALL-NEXT: - { id: 0, class: gr8 }
|
||||
# ALL-NEXT: - { id: 1, class: gr32 }
|
||||
# ALL-NEXT: - { id: 2, class: gr32 }
|
||||
registers:
|
||||
- { id: 0, class: gpr }
|
||||
- { id: 1, class: gpr }
|
||||
# ALL: %0 = COPY %dil
|
||||
# ALL-NEXT: %2 = SUBREG_TO_REG 0, %0, 1
|
||||
# ALL-NEXT: %1 = AND32ri8 %2, 1, implicit-def %eflags
|
||||
# ALL-NEXT: %eax = COPY %1
|
||||
# ALL-NEXT: RET 0, implicit %eax
|
||||
body: |
|
||||
bb.1 (%ir-block.0):
|
||||
liveins: %edi
|
||||
|
||||
%0(s1) = COPY %edi
|
||||
%1(s32) = G_ZEXT %0(s1)
|
||||
%eax = COPY %1(s32)
|
||||
RET 0, implicit %eax
|
||||
|
||||
...
|
||||
---
|
||||
name: test_zext_i8
|
||||
|
Loading…
Reference in New Issue
Block a user