[llvm] r314760 - [Legalizer] Add support for G_OR NarrowScalar.
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 2 21:53:56 PDT 2017
Author: qcolombet
Date: Mon Oct 2 21:53:56 2017
New Revision: 314760
URL: http://llvm.org/viewvc/llvm-project?rev=314760&view=rev
Log:
[Legalizer] Add support for G_OR NarrowScalar.
Legalize bitwise OR:
A = BinOp<Ty> B, C
into:
B1, ..., BN = G_UNMERGE_VALUES B
C1, ..., CN = G_UNMERGE_VALUES C
A1 = BinOp<Ty/N> B1, C2
...
AN = BinOp<Ty/N> BN, CN
A = G_MERGE_VALUES A1, ..., AN
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-or.mir
Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=314760&r1=314759&r2=314760&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp Mon Oct 2 21:53:56 2017
@@ -396,6 +396,50 @@ LegalizerHelper::LegalizeResult Legalize
MI.eraseFromParent();
return Legalized;
}
+ case TargetOpcode::G_OR: {
+ // Legalize bitwise operation:
+ // A = BinOp<Ty> B, C
+ // into:
+ // B1, ..., BN = G_UNMERGE_VALUES B
+ // C1, ..., CN = G_UNMERGE_VALUES C
+ // A1 = BinOp<Ty/N> B1, C2
+ // ...
+ // AN = BinOp<Ty/N> BN, CN
+ // A = G_MERGE_VALUES A1, ..., AN
+ unsigned NarrowSize = NarrowTy.getSizeInBits();
+ int NumParts =
+ MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowSize;
+
+ // List the registers where the destination will be scattered.
+ SmallVector<unsigned, 2> DstRegs;
+ // List the registers where the first argument will be split.
+ SmallVector<unsigned, 2> SrcsReg1;
+ // List the registers where the second argument will be split.
+ SmallVector<unsigned, 2> SrcsReg2;
+ // Create all the temporary registers.
+ for (int i = 0; i < NumParts; ++i) {
+ unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
+ unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy);
+ unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy);
+
+ DstRegs.push_back(DstReg);
+ SrcsReg1.push_back(SrcReg1);
+ SrcsReg2.push_back(SrcReg2);
+ }
+ // Explode the big arguments into smaller chunks.
+ MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg());
+ MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg());
+
+ // Do the operation on each small part.
+ for (int i = 0; i < NumParts; ++i)
+ MIRBuilder.buildOr(DstRegs[i], SrcsReg1[i], SrcsReg2[i]);
+
+ // Gather the destination registers into the final destination.
+ unsigned DstReg = MI.getOperand(0).getReg();
+ MIRBuilder.buildMerge(DstReg, DstRegs);
+ MI.eraseFromParent();
+ return Legalized;
+ }
}
}
Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp?rev=314760&r1=314759&r2=314760&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp Mon Oct 2 21:53:56 2017
@@ -48,6 +48,7 @@ LegalizerInfo::LegalizerInfo() {
DefaultActions[TargetOpcode::G_ADD] = NarrowScalar;
DefaultActions[TargetOpcode::G_LOAD] = NarrowScalar;
DefaultActions[TargetOpcode::G_STORE] = NarrowScalar;
+ DefaultActions[TargetOpcode::G_OR] = NarrowScalar;
DefaultActions[TargetOpcode::G_BRCOND] = WidenScalar;
DefaultActions[TargetOpcode::G_INSERT] = NarrowScalar;
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-or.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-or.mir?rev=314760&r1=314759&r2=314760&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-or.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-or.mir Mon Oct 2 21:53:56 2017
@@ -1,13 +1,4 @@
-# RUN: llc -O0 -run-pass=legalizer -global-isel %s -o - | FileCheck %s
-
---- |
- target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
- target triple = "aarch64--"
- define void @test_scalar_or_small() {
- entry:
- ret void
- }
-...
+# RUN: llc -O0 -mtriple=aarch64-apple-ios -run-pass=legalizer -global-isel %s -o - | FileCheck %s
---
name: test_scalar_or_small
@@ -19,7 +10,7 @@ registers:
- { id: 4, class: _ }
- { id: 5, class: _ }
body: |
- bb.0.entry:
+ bb.0:
liveins: %x0, %x1, %x2, %x3
; CHECK-LABEL: name: test_scalar_or_small
; CHECK: [[OP0:%.*]](s32) = G_TRUNC %0
@@ -35,3 +26,49 @@ body: |
%5(s64) = G_ANYEXT %2
%x0 = COPY %5
...
+
+---
+name: test_big_scalar_power_of_2
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+ - { id: 4, class: _ }
+ - { id: 5, class: _ }
+ - { id: 6, class: _ }
+ - { id: 7, class: _ }
+ - { id: 8, class: _ }
+body: |
+ bb.0:
+ liveins: %x0, %x1, %x2, %x3
+ ; CHECK-LABEL: name: test_big_scalar_power_of_2
+ ; CHECK: [[OP0_0:%.*]](s64) = COPY %x0
+ ; CHECK-NEXT: [[OP0_1:%.*]](s64) = COPY %x1
+ ; CHECK-NEXT: [[OP1_0:%.*]](s64) = COPY %x2
+ ; CHECK-NEXT: [[OP1_1:%.*]](s64) = COPY %x3
+ ; CHECK-NEXT: [[RES_0:%.*]](s64) = G_OR [[OP0_0]], [[OP1_0]]
+ ; CHECK-NEXT: [[RES_1:%.*]](s64) = G_OR [[OP0_1]], [[OP1_1]]
+ ; We have a temporary G_MERGE_VALUES in the legalizer
+ ; that gets cleaned up with the G_UNMERGE_VALUES.
+ ; Thus,
+ ; tmp = G_MERGE_VALUES [[RES_0]], [[RES_1]]
+ ; %7, %8 = G_UNMERGE_VALUES tmp
+ ; %x0 = COPY %7
+ ; %x1 = COPY %8
+ ; translates into
+ ; CHECK-NEXT: %x0 = COPY [[RES_0]]
+ ; CHECK-NEXT: %x1 = COPY [[RES_1]]
+
+ %0(s64) = COPY %x0
+ %1(s64) = COPY %x1
+ %2(s64) = COPY %x2
+ %3(s64) = COPY %x3
+ %4(s128) = G_MERGE_VALUES %0, %1
+ %5(s128) = G_MERGE_VALUES %2, %3
+ %6(s128) = G_OR %4, %5
+ %7(s64), %8(s64) = G_UNMERGE_VALUES %6
+ %x0 = COPY %7
+ %x1 = COPY %8
+ RET_ReallyLR implicit %x0, implicit %x1
+...
More information about the llvm-commits
mailing list