[llvm] r306328 - AArch64: legalize G_EXTRACT operations.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 26 13:34:13 PDT 2017
Author: tnorthover
Date: Mon Jun 26 13:34:13 2017
New Revision: 306328
URL: http://llvm.org/viewvc/llvm-project?rev=306328&view=rev
Log:
AArch64: legalize G_EXTRACT operations.
This is the dual problem to legalizing G_INSERTs so most of the code and
testing was cribbed from there.
Added:
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-extracts.mir
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp
llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll
Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp Mon Jun 26 13:34:13 2017
@@ -158,7 +158,7 @@ LegalizerHelper::LegalizeResult Legalize
unsigned TypeIdx,
LLT NarrowTy) {
// FIXME: Don't know how to handle secondary types yet.
- if (TypeIdx != 0)
+ if (TypeIdx != 0 && MI.getOpcode() != TargetOpcode::G_EXTRACT)
return UnableToLegalize;
MIRBuilder.setInstr(MI);
@@ -193,6 +193,58 @@ LegalizerHelper::LegalizeResult Legalize
MI.eraseFromParent();
return Legalized;
}
+ case TargetOpcode::G_EXTRACT: {
+ if (TypeIdx != 1)
+ return UnableToLegalize;
+
+ int64_t NarrowSize = NarrowTy.getSizeInBits();
+ int NumParts =
+ MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() / NarrowSize;
+
+ SmallVector<unsigned, 2> SrcRegs, DstRegs;
+ SmallVector<uint64_t, 2> Indexes;
+ extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
+
+ unsigned OpReg = MI.getOperand(0).getReg();
+ int64_t OpStart = MI.getOperand(2).getImm();
+ int64_t OpSize = MRI.getType(OpReg).getSizeInBits();
+ for (int i = 0; i < NumParts; ++i) {
+ unsigned SrcStart = i * NarrowSize;
+
+ if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) {
+ // No part of the extract uses this subregister, ignore it.
+ continue;
+ } else if (SrcStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
+ // The entire subregister is extracted, forward the value.
+ DstRegs.push_back(SrcRegs[i]);
+ continue;
+ }
+
+ // OpSegStart is where this destination segment would start in OpReg if it
+ // extended infinitely in both directions.
+ int64_t ExtractOffset, SegSize;
+ if (OpStart < SrcStart) {
+ ExtractOffset = 0;
+ SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
+ } else {
+ ExtractOffset = OpStart - SrcStart;
+ SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
+ }
+
+ unsigned SegReg = SrcRegs[i];
+ if (ExtractOffset != 0 || SegSize != NarrowSize) {
+ // A genuine extract is needed.
+ SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
+ MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset);
+ }
+
+ DstRegs.push_back(SegReg);
+ }
+
+ MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
+ MI.eraseFromParent();
+ return Legalized;
+ }
case TargetOpcode::G_INSERT: {
if (TypeIdx != 0)
return UnableToLegalize;
Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp Mon Jun 26 13:34:13 2017
@@ -42,6 +42,7 @@ LegalizerInfo::LegalizerInfo() : TablesI
DefaultActions[TargetOpcode::G_BRCOND] = WidenScalar;
DefaultActions[TargetOpcode::G_INSERT] = NarrowScalar;
+ DefaultActions[TargetOpcode::G_EXTRACT] = NarrowScalar;
DefaultActions[TargetOpcode::G_FNEG] = Lower;
}
@@ -75,8 +76,7 @@ LegalizerInfo::getAction(const InstrAspe
// FIXME: the long-term plan calls for expansion in terms of load/store (if
// they're not legal).
- if (Aspect.Opcode == TargetOpcode::G_EXTRACT ||
- Aspect.Opcode == TargetOpcode::G_MERGE_VALUES ||
+ if (Aspect.Opcode == TargetOpcode::G_MERGE_VALUES ||
Aspect.Opcode == TargetOpcode::G_UNMERGE_VALUES)
return std::make_pair(Legal, Aspect.Type);
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Mon Jun 26 13:34:13 2017
@@ -482,6 +482,9 @@ MachineInstrBuilder MachineIRBuilder::bu
"input operands do not cover output register");
#endif
+ if (Ops.size() == 1)
+ return buildCopy(Res, Ops[0]);
+
MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
MIB.addDef(Res);
for (unsigned i = 0; i < Ops.size(); ++i)
Modified: llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp Mon Jun 26 13:34:13 2017
@@ -99,6 +99,12 @@ AArch64LegalizerInfo::AArch64LegalizerIn
// G_INSERT (It seems entirely reasonable that inputs shouldn't overlap).
}
+ for (auto Ty : {s1, s8, s16, s32, s64, p0})
+ setAction({G_EXTRACT, Ty}, Legal);
+
+ for (auto Ty : {s32, s64})
+ setAction({G_EXTRACT, 1, Ty}, Legal);
+
for (unsigned MemOp : {G_LOAD, G_STORE}) {
for (auto Ty : {s8, s16, s32, s64, p0, v2s32})
setAction({MemOp, Ty}, Legal);
Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Mon Jun 26 13:34:13 2017
@@ -228,10 +228,14 @@ void X86LegalizerInfo::setLegalizerInfoA
for (auto Ty : {v8s32, v4s64})
setAction({MemOp, Ty}, Legal);
- for (auto Ty : {v32s8, v16s16, v8s32, v4s64})
+ for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) {
setAction({G_INSERT, Ty}, Legal);
- for (auto Ty : {v16s8, v8s16, v4s32, v2s64})
+ setAction({G_EXTRACT, 1, Ty}, Legal);
+ }
+ for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) {
setAction({G_INSERT, 1, Ty}, Legal);
+ setAction({G_EXTRACT, Ty}, Legal);
+ }
}
void X86LegalizerInfo::setLegalizerInfoAVX2() {
@@ -280,10 +284,14 @@ void X86LegalizerInfo::setLegalizerInfoA
for (auto Ty : {v16s32, v8s64})
setAction({MemOp, Ty}, Legal);
- for (auto Ty : {v64s8, v32s16, v16s32, v8s64})
+ for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) {
setAction({G_INSERT, Ty}, Legal);
- for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64})
+ setAction({G_EXTRACT, 1, Ty}, Legal);
+ }
+ for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) {
setAction({G_INSERT, 1, Ty}, Legal);
+ setAction({G_EXTRACT, Ty}, Legal);
+ }
/************ VLX *******************/
if (!Subtarget.hasVLX())
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir Mon Jun 26 13:34:13 2017
@@ -57,11 +57,11 @@ body: |
%0:_(s64) = COPY %x0
; CHECK-LABEL: name: test_combines_4
- ; CHECK: %2(<2 x s32>) = G_EXTRACT %1(s128), 0
- ; CHECK: %3(<2 x s32>) = G_ADD %2, %2
+ ; CHECK: %2(s64) = COPY %0(s64)
+ ; CHECK: %3(s64) = G_ADD %2, %2
%1:_(s128) = G_MERGE_VALUES %0, %0
- %2:_(<2 x s32>) = G_EXTRACT %1, 0
- %3:_(<2 x s32>) = G_ADD %2, %2
+ %2:_(s64) = G_EXTRACT %1, 0
+ %3:_(s64) = G_ADD %2, %2
...
---
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll?rev=306328&r1=306327&r2=306328&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll Mon Jun 26 13:34:13 2017
@@ -22,12 +22,11 @@ declare void @_Unwind_Resume(i8*)
; CHECK: [[SEL:%[0-9]+]](s32) = G_PTRTOINT [[SEL_PTR]]
; CHECK: [[STRUCT_SEL:%[0-9]+]](s64) = G_INSERT {{%[0-9]+}}, [[SEL]](s32), 0
-; CHECK: [[STRUCT:%[0-9]+]](s128) = G_MERGE_VALUES [[STRUCT_PTR]](s64), [[STRUCT_SEL]]
-
-; CHECK: [[PTR:%[0-9]+]](p0) = G_EXTRACT [[STRUCT]](s128), 0
+; CHECK: [[PTR:%[0-9]+]](p0) = COPY [[STRUCT_PTR]](s64)
; CHECK: G_STORE [[PTR]](p0), {{%[0-9]+}}(p0)
-; CHECK: [[SEL:%[0-9]+]](s32) = G_EXTRACT [[STRUCT]](s128), 64
+; CHECK: [[SEL_TMP:%[0-9]+]](s32) = G_EXTRACT [[STRUCT_SEL]](s64), 0
+; CHECK: [[SEL:%[0-9]+]](s32) = COPY [[SEL_TMP]]
; CHECK: G_STORE [[SEL]](s32), {{%[0-9]+}}(p0)
define void @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-extracts.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-extracts.mir?rev=306328&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-extracts.mir (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-extracts.mir Mon Jun 26 13:34:13 2017
@@ -0,0 +1,85 @@
+# RUN: llc -mtriple=aarch64-linux-gnu -O0 -run-pass=legalizer -global-isel %s -o - | FileCheck %s
+
+---
+name: test_extracts_1
+body: |
+ bb.0:
+ liveins: %w0
+
+ ; Low part of extraction takes entirity of the low register entirely, so
+ ; value stored is forwarded directly from first load.
+
+ ; CHECK-LABEL: name: test_extracts_1
+ ; CHECK: [[LO:%[0-9]+]](s64) = G_LOAD
+ ; CHECK: {{%[0-9]+}}(s64) = G_LOAD
+ ; CHECK: [[VAL:%[0-9]+]](s64) = COPY [[LO]]
+ ; CHECK: G_STORE [[VAL]]
+ %0:_(s64) = COPY %x0
+ %1:_(s32) = COPY %w1
+ %2:_(p0) = COPY %x2
+ %3:_(s128) = G_LOAD %2(p0) :: (load 16)
+ %4:_(s64) = G_EXTRACT %3(s128), 0
+ G_STORE %4(s64), %2(p0) :: (store 8)
+ RET_ReallyLR
+...
+
+---
+name: test_extracts_2
+body: |
+ bb.0:
+ liveins: %w0
+
+ ; Low extraction wipes takes whole low register. High extraction is real.
+ ; CHECK-LABEL: name: test_extracts_2
+ ; CHECK: [[LO_TMP:%[0-9]+]](s64) = G_LOAD
+ ; CHECK: [[HI:%[0-9]+]](s64) = G_LOAD
+ ; CHECK: [[LO:%[0-9]+]](s64) = COPY [[LO_TMP]]
+ ; CHECK: [[NEWHI_TMP:%[0-9]+]](s32) = G_EXTRACT [[HI]](s64), 0
+ ; CHECK: [[NEWHI:%[0-9]+]](s32) = COPY [[NEWHI_TMP]]
+ ; CHECK: G_STORE [[LO]]
+ ; CHECK: G_STORE [[NEWHI]]
+ %0:_(s64) = COPY %x0
+ %1:_(s32) = COPY %w1
+ %2:_(p0) = COPY %x2
+ %3:_(s128) = G_LOAD %2(p0) :: (load 16)
+ %4:_(s64) = G_EXTRACT %3(s128), 0
+ %5:_(s32) = G_EXTRACT %3(s128), 64
+ G_STORE %4(s64), %2(p0) :: (store 8)
+ G_STORE %5(s32), %2(p0) :: (store 4)
+ RET_ReallyLR
+...
+
+---
+name: test_extracts_3
+body: |
+ bb.0:
+ liveins: %x0, %x1, %x2
+
+
+ ; CHECK-LABEL: name: test_extracts_3
+ ; CHECK: [[LO:%[0-9]+]](s32) = G_EXTRACT %0(s64), 32
+ ; CHECK: [[HI:%[0-9]+]](s32) = G_EXTRACT %1(s64), 0
+ ; CHECK: %3(s64) = G_MERGE_VALUES [[LO]](s32), [[HI]](s32)
+ %0:_(s64) = COPY %x0
+ %1:_(s64) = COPY %x1
+ %2:_(s128) = G_MERGE_VALUES %0, %1
+ %3:_(s64) = G_EXTRACT %2, 32
+ RET_ReallyLR
+...
+
+---
+name: test_extracts_4
+body: |
+ bb.0:
+ liveins: %x0, %x1, %x2
+
+
+ ; CHECK-LABEL: name: test_extracts_4
+ ; CHECK: [[LO_TMP:%[0-9]+]](s32) = G_EXTRACT %0(s64), 32
+ ; CHECK: %3(s32) = COPY [[LO_TMP]]
+ %0:_(s64) = COPY %x0
+ %1:_(s64) = COPY %x1
+ %2:_(s128) = G_MERGE_VALUES %0, %1
+ %3:_(s32) = G_EXTRACT %2, 32
+ RET_ReallyLR
+...
More information about the llvm-commits
mailing list