diff options
author | Igor Breger <igor.breger@intel.com> | 2017-07-10 09:07:34 +0000 |
---|---|---|
committer | Igor Breger <igor.breger@intel.com> | 2017-07-10 09:07:34 +0000 |
commit | 77954ced1a8f4d4dda2b2c9b7a618c360fd5b1df (patch) | |
tree | f4e41c1d78f425161e975e8fe4cc58be0d8983ff | |
parent | d6a9e4a5f3b86b5e2f42855b3bc346e2b8f517ce (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307526 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86InstructionSelector.cpp | 45 | ||||
-rw-r--r-- | lib/Target/X86/X86LegalizerInfo.cpp | 8 | ||||
-rw-r--r-- | test/CodeGen/X86/GlobalISel/ext.ll | 36 | ||||
-rw-r--r-- | test/CodeGen/X86/GlobalISel/legalize-ext.mir | 171 | ||||
-rw-r--r-- | test/CodeGen/X86/GlobalISel/select-ext.mir | 64 |
5 files changed, 299 insertions, 25 deletions
diff --git a/lib/Target/X86/X86InstructionSelector.cpp b/lib/Target/X86/X86InstructionSelector.cpp index 9552d780d33..e912ebcfc12 100644 --- a/lib/Target/X86/X86InstructionSelector.cpp +++ b/lib/Target/X86/X86InstructionSelector.cpp @@ -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)) { - - unsigned AndOpc; - if (DstTy == LLT::scalar(32)) - AndOpc = X86::AND32ri8; - else if (DstTy == LLT::scalar(64)) - AndOpc = X86::AND64ri8; - else - return false; + if (SrcTy != LLT::scalar(1)) + 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); + MachineInstr &AndInst = + *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg) + .addReg(DefReg) + .addImm(1); - I.eraseFromParent(); - return true; - } + constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI); - return false; + I.eraseFromParent(); + return true; } bool X86InstructionSelector::selectCmp(MachineInstr &I, diff --git a/lib/Target/X86/X86LegalizerInfo.cpp b/lib/Target/X86/X86LegalizerInfo.cpp index 62dd088c2fd..ea3c3b99e06 100644 --- a/lib/Target/X86/X86LegalizerInfo.cpp +++ b/lib/Target/X86/X86LegalizerInfo.cpp @@ -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); } diff --git a/test/CodeGen/X86/GlobalISel/ext.ll b/test/CodeGen/X86/GlobalISel/ext.ll index 392c973c120..d9a09678cf4 100644 --- a/test/CodeGen/X86/GlobalISel/ext.ll +++ b/test/CodeGen/X86/GlobalISel/ext.ll @@ -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: diff --git a/test/CodeGen/X86/GlobalISel/legalize-ext.mir b/test/CodeGen/X86/GlobalISel/legalize-ext.mir index c9add0dc4e9..c86bfd9ee96 100644 --- a/test/CodeGen/X86/GlobalISel/legalize-ext.mir +++ b/test/CodeGen/X86/GlobalISel/legalize-ext.mir @@ -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 @@ -35,6 +66,52 @@ ... --- +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 # ALL-LABEL: name: test_zext_i1 alignment: 4 @@ -61,6 +138,29 @@ body: | ... --- +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 # ALL-LABEL: name: test_zext_i8 alignment: 4 @@ -107,6 +207,52 @@ body: | ... --- +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 # ALL-LABEL: name: test_sext_i1 alignment: 4 @@ -133,6 +279,29 @@ body: | ... --- +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 # ALL-LABEL: name: test_sext_i8 alignment: 4 diff --git a/test/CodeGen/X86/GlobalISel/select-ext.mir b/test/CodeGen/X86/GlobalISel/select-ext.mir index b52f1f6fa62..d8d48f627a7 100644 --- a/test/CodeGen/X86/GlobalISel/select-ext.mir +++ b/test/CodeGen/X86/GlobalISel/select-ext.mir @@ -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 @@ -29,6 +39,60 @@ ... --- +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 # ALL-LABEL: name: test_zext_i1 alignment: 4 |