[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