1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[GlobalISel][X86] Support G_IMPLICIT_DEF.

Summary: Support G_IMPLICIT_DEF.

Reviewers: zvi, guyblank, t.p.northover

Reviewed By: guyblank

Subscribers: rovka, llvm-commits, kristof.beyls

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

llvm-svn: 311633
This commit is contained in:
Igor Breger 2017-08-24 07:06:27 +00:00
parent 16729fe8c1
commit 8dd4b724b5
7 changed files with 306 additions and 1 deletions

View File

@ -85,6 +85,7 @@ private:
MachineFunction &MF) const;
bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
bool selectImplicitDef(MachineInstr &I, MachineRegisterInfo &MRI) const;
// emit insert subreg instruction and insert it before MachineInstr &I
bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
@ -334,6 +335,8 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
return true;
if (selectCondBranch(I, MRI, MF))
return true;
if (selectImplicitDef(I, MRI))
return true;
return false;
}
@ -1128,6 +1131,29 @@ bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
return true;
}
bool X86InstructionSelector::selectImplicitDef(MachineInstr &I,
MachineRegisterInfo &MRI) const {
if (I.getOpcode() != TargetOpcode::G_IMPLICIT_DEF)
return false;
unsigned DstReg = I.getOperand(0).getReg();
if (!MRI.getRegClassOrNull(DstReg)) {
const LLT DstTy = MRI.getType(DstReg);
const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
<< " operand\n");
return false;
}
}
I.setDesc(TII.get(X86::IMPLICIT_DEF));
return true;
}
InstructionSelector *
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
X86Subtarget &Subtarget,

View File

@ -52,6 +52,9 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
for (auto Ty : {p0, s1, s8, s16, s32})
setAction({G_IMPLICIT_DEF, Ty}, Legal);
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);
@ -120,6 +123,9 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
for (auto Ty : {p0, s1, s8, s16, s32, s64})
setAction({G_IMPLICIT_DEF, Ty}, Legal);
for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
for (auto Ty : {s8, s16, s32, s64})
setAction({BinOp, Ty}, Legal);

View File

@ -211,7 +211,8 @@ X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case TargetOpcode::G_LOAD:
case TargetOpcode::G_STORE: {
case TargetOpcode::G_STORE:
case TargetOpcode::G_IMPLICIT_DEF: {
// we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
if (Size != 32 && Size != 64)

View File

@ -0,0 +1,29 @@
# 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
---
name: test_implicit_def
# ALL-LABEL: name: test_implicit_def
registers:
# X64: %0(s1) = G_IMPLICIT_DEF
# X64-NEXT: %1(s8) = G_IMPLICIT_DEF
# X64-NEXT: %2(s16) = G_IMPLICIT_DEF
# X64-NEXT: %3(s32) = G_IMPLICIT_DEF
# X64-NEXT: %4(s64) = G_IMPLICIT_DEF
#
# X32: %0(s1) = G_IMPLICIT_DEF
# X32-NEXT: %1(s8) = G_IMPLICIT_DEF
# X32-NEXT: %2(s16) = G_IMPLICIT_DEF
# X32-NEXT: %3(s32) = G_IMPLICIT_DEF
# X32-NEXT: %5(s32) = G_IMPLICIT_DEF
# X32-NEXT: %6(s32) = G_IMPLICIT_DEF
# X32-NEXT: %4(s64) = G_MERGE_VALUES %5(s32), %6(s32)
body: |
bb.0.entry:
liveins:
%0:_(s1) = G_IMPLICIT_DEF
%1:_(s8) = G_IMPLICIT_DEF
%2:_(s16) = G_IMPLICIT_DEF
%3:_(s32) = G_IMPLICIT_DEF
%4:_(s64) = G_IMPLICIT_DEF
...

View File

@ -181,6 +181,23 @@
ret i32* @g_int
}
define i8 @test_undef() {
ret i8 undef
}
define i8 @test_undef2(i8 %a) {
%r = add i8 %a, undef
ret i8 %r
}
define float @test_undef3() {
ret float undef
}
define float @test_undef4(float %a) {
%r = fadd float %a, undef
ret float %r
}
...
---
name: test_add_i8
@ -1111,4 +1128,122 @@ body: |
RET 0, implicit %rax
...
---
name: test_undef
# CHECK-LABEL: name: test_undef
alignment: 4
legalized: true
regBankSelected: false
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
registers:
- { id: 0, class: _, preferred-register: '' }
liveins:
fixedStack:
stack:
constants:
# CHECK: %0(s8) = G_IMPLICIT_DEF
# CHECK-NEXT: %al = COPY %0(s8)
# CHECK-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
%0(s8) = G_IMPLICIT_DEF
%al = COPY %0(s8)
RET 0, implicit %al
...
---
name: test_undef2
# CHECK-LABEL: name: test_undef2
alignment: 4
legalized: true
regBankSelected: false
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
# CHECK-NEXT: - { id: 2, class: gpr, preferred-register: '' }
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
liveins:
fixedStack:
stack:
constants:
# CHECK: %0(s8) = COPY %edi
# CHECK-NEXT: %1(s8) = G_IMPLICIT_DEF
# CHECK-NEXT: %2(s8) = G_ADD %0, %1
# CHECK-NEXT: %al = COPY %2(s8)
# CHECK-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s8) = COPY %edi
%1(s8) = G_IMPLICIT_DEF
%2(s8) = G_ADD %0, %1
%al = COPY %2(s8)
RET 0, implicit %al
...
---
name: test_undef3
# CHECK-LABEL: name: test_undef3
alignment: 4
legalized: true
regBankSelected: false
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
registers:
- { id: 0, class: _, preferred-register: '' }
liveins:
fixedStack:
stack:
constants:
# CHECK: %0(s32) = G_IMPLICIT_DEF
# CHECK-NEXT: %xmm0 = COPY %0(s32)
# CHECK-NEXT: RET 0, implicit %xmm0
body: |
bb.1 (%ir-block.0):
%0(s32) = G_IMPLICIT_DEF
%xmm0 = COPY %0(s32)
RET 0, implicit %xmm0
...
---
name: test_undef4
# CHECK-LABEL: name: test_undef4
alignment: 4
legalized: true
regBankSelected: false
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: vecr, preferred-register: '' }
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
# CHECK-NEXT: - { id: 2, class: vecr, preferred-register: '' }
# CHECK-NEXT: - { id: 3, class: vecr, preferred-register: '' }
registers:
- { id: 0, class: _, preferred-register: '' }
- { id: 1, class: _, preferred-register: '' }
- { id: 2, class: _, preferred-register: '' }
liveins:
fixedStack:
stack:
constants:
# CHECK: %0(s32) = COPY %xmm0
# CHECK-NEXT: %1(s32) = G_IMPLICIT_DEF
# CHECK-NEXT: %3(s32) = COPY %1(s32)
# CHECK-NEXT: %2(s32) = G_FADD %0, %3
# CHECK-NEXT: %xmm0 = COPY %2(s32)
# CHECK-NEXT: RET 0, implicit %xmm0
body: |
bb.1 (%ir-block.0):
liveins: %xmm0
%0(s32) = COPY %xmm0
%1(s32) = G_IMPLICIT_DEF
%2(s32) = G_FADD %0, %1
%xmm0 = COPY %2(s32)
RET 0, implicit %xmm0
...

View File

@ -0,0 +1,71 @@
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL
--- |
define i8 @test() {
ret i8 undef
}
define i8 @test2(i8 %a) {
%r = add i8 %a, undef
ret i8 %r
}
...
---
name: test
# ALL-LABEL: name: test
alignment: 4
legalized: true
regBankSelected: true
# ALL: registers:
# ALL-NEXT: - { id: 0, class: gr8, preferred-register: '' }
registers:
- { id: 0, class: gpr, preferred-register: '' }
liveins:
fixedStack:
stack:
constants:
# ALL: %0 = IMPLICIT_DEF
# ALL-NEXT: %al = COPY %0
# ALL-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
%0(s8) = G_IMPLICIT_DEF
%al = COPY %0(s8)
RET 0, implicit %al
...
---
name: test2
# ALL-LABEL: name: test2
alignment: 4
legalized: true
regBankSelected: true
# ALL: registers:
# ALL-NEXT: - { id: 0, class: gr8, preferred-register: '' }
# ALL-NEXT: - { id: 1, class: gr8, preferred-register: '' }
# ALL-NEXT: - { id: 2, class: gr8, preferred-register: '' }
registers:
- { id: 0, class: gpr, preferred-register: '' }
- { id: 1, class: gpr, preferred-register: '' }
- { id: 2, class: gpr, preferred-register: '' }
liveins:
fixedStack:
stack:
constants:
# ALL: %0 = COPY %dil
# ALL-NEXT: %1 = IMPLICIT_DEF
# ALL-NEXT: %2 = ADD8rr %0, %1, implicit-def %eflags
# ALL-NEXT: %al = COPY %2
# ALL-NEXT: RET 0, implicit %al
body: |
bb.1 (%ir-block.0):
liveins: %edi
%0(s8) = COPY %edi
%1(s8) = G_IMPLICIT_DEF
%2(s8) = G_ADD %0, %1
%al = COPY %2(s8)
RET 0, implicit %al
...

View File

@ -0,0 +1,37 @@
; 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 i8 @test() {
; ALL-LABEL: test:
; ALL: # BB#0:
; ALL-NEXT: retq
ret i8 undef
}
define i8 @test2(i8 %a) {
; ALL-LABEL: test2:
; ALL: # BB#0:
; ALL-NEXT: addb %al, %dil
; ALL-NEXT: movl %edi, %eax
; ALL-NEXT: retq
%r = add i8 %a, undef
ret i8 %r
}
define float @test3() {
; ALL-LABEL: test3:
; ALL: # BB#0:
; ALL-NEXT: retq
ret float undef
}
define float @test4(float %a) {
; ALL-LABEL: test4:
; ALL: # BB#0:
; ALL-NEXT: addss %xmm0, %xmm0
; ALL-NEXT: retq
%r = fadd float %a, undef
ret float %r
}