[llvm] r284526 - GlobalISel: select small binary operations on AArch64.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 18 13:03:48 PDT 2016


Author: tnorthover
Date: Tue Oct 18 15:03:48 2016
New Revision: 284526

URL: http://llvm.org/viewvc/llvm-project?rev=284526&view=rev
Log:
GlobalISel: select small binary operations on AArch64.

AArch64 actually supports many 8-bit operations under the definition used by
GlobalISel: the designated information-carrying bits of a GPR32 get the right
value if you just use the normal 32-bit instruction.

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=284526&r1=284525&r2=284526&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Tue Oct 18 15:03:48 2016
@@ -123,8 +123,13 @@ static unsigned selectBinaryOp(unsigned
                                unsigned OpSize) {
   switch (RegBankID) {
   case AArch64::GPRRegBankID:
-    switch (OpSize) {
-    case 32:
+    if (OpSize <= 32) {
+      assert((OpSize == 32 || (GenericOpc != TargetOpcode::G_SDIV &&
+                               GenericOpc != TargetOpcode::G_UDIV &&
+                               GenericOpc != TargetOpcode::G_LSHR &&
+                               GenericOpc != TargetOpcode::G_ASHR)) &&
+             "operation should have been legalized before now");
+
       switch (GenericOpc) {
       case TargetOpcode::G_OR:
         return AArch64::ORRWrr;
@@ -149,7 +154,7 @@ static unsigned selectBinaryOp(unsigned
       default:
         return GenericOpc;
       }
-    case 64:
+    } else if (OpSize == 64) {
       switch (GenericOpc) {
       case TargetOpcode::G_OR:
         return AArch64::ORRXrr;
@@ -676,7 +681,7 @@ bool AArch64InstructionSelector::select(
 
     unsigned ZeroReg;
     unsigned NewOpc;
-    if (Ty == LLT::scalar(32)) {
+    if (Ty.isScalar() && Ty.getSizeInBits() <= 32) {
       NewOpc = AArch64::MADDWrrr;
       ZeroReg = AArch64::WZR;
     } else if (Ty == LLT::scalar(64)) {

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir?rev=284526&r1=284525&r2=284526&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir Tue Oct 18 15:03:48 2016
@@ -8,22 +8,34 @@
 --- |
   target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
 
+  define void @add_s8_gpr() { ret void }
+  define void @add_s16_gpr() { ret void }
   define void @add_s32_gpr() { ret void }
   define void @add_s64_gpr() { ret void }
 
+  define void @sub_s8_gpr() { ret void }
+  define void @sub_s16_gpr() { ret void }
   define void @sub_s32_gpr() { ret void }
   define void @sub_s64_gpr() { ret void }
 
+  define void @or_s1_gpr() { ret void }
+  define void @or_s16_gpr() { ret void }
   define void @or_s32_gpr() { ret void }
   define void @or_s64_gpr() { ret void }
   define void @or_v2s32_fpr() { ret void }
 
+  define void @xor_s8_gpr() { ret void }
+  define void @xor_s16_gpr() { ret void }
   define void @xor_s32_gpr() { ret void }
   define void @xor_s64_gpr() { ret void }
 
+  define void @and_s8_gpr() { ret void }
+  define void @and_s16_gpr() { ret void }
   define void @and_s32_gpr() { ret void }
   define void @and_s64_gpr() { ret void }
 
+  define void @shl_s8_gpr() { ret void }
+  define void @shl_s16_gpr() { ret void }
   define void @shl_s32_gpr() { ret void }
   define void @shl_s64_gpr() { ret void }
 
@@ -33,6 +45,8 @@
   define void @ashr_s32_gpr() { ret void }
   define void @ashr_s64_gpr() { ret void }
 
+  define void @mul_s8_gpr() { ret void }
+  define void @mul_s16_gpr() { ret void }
   define void @mul_s32_gpr() { ret void }
   define void @mul_s64_gpr() { ret void }
 
@@ -136,6 +150,62 @@
 ...
 
 ---
+# CHECK-LABEL: name: add_s8_gpr
+name:            add_s8_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = ADDWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s8) = COPY %w0
+    %1(s8) = COPY %w1
+    %2(s8) = G_ADD %0, %1
+...
+
+---
+# CHECK-LABEL: name: add_s16_gpr
+name:            add_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = ADDWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_ADD %0, %1
+...
+
+---
 # Check that we select a 32-bit GPR G_ADD into ADDWrr on GPR32.
 # Also check that we constrain the register class of the COPY to GPR32.
 # CHECK-LABEL: name: add_s32_gpr
@@ -195,6 +265,62 @@ body:             |
 ...
 
 ---
+# CHECK-LABEL: name: sub_s8_gpr
+name:            sub_s8_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = SUBWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s8) = COPY %w0
+    %1(s8) = COPY %w1
+    %2(s8) = G_SUB %0, %1
+...
+
+---
+# CHECK-LABEL: name: sub_s16_gpr
+name:            sub_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = SUBWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_SUB %0, %1
+...
+
+---
 # Same as add_s32_gpr, for G_SUB operations.
 # CHECK-LABEL: name: sub_s32_gpr
 name:            sub_s32_gpr
@@ -253,6 +379,62 @@ body:             |
 ...
 
 ---
+# CHECK-LABEL: name: or_s1_gpr
+name:            or_s1_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = ORRWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s1) = COPY %w0
+    %1(s1) = COPY %w1
+    %2(s1) = G_OR %0, %1
+...
+
+---
+# CHECK-LABEL: name: or_s16_gpr
+name:            or_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = ORRWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_OR %0, %1
+...
+
+---
 # Same as add_s32_gpr, for G_OR operations.
 # CHECK-LABEL: name: or_s32_gpr
 name:            or_s32_gpr
@@ -342,6 +524,62 @@ body:             |
 ...
 
 ---
+# CHECK-LABEL: name: xor_s8_gpr
+name:            xor_s8_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = EORWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s8) = COPY %w0
+    %1(s8) = COPY %w1
+    %2(s8) = G_XOR %0, %1
+...
+
+---
+# CHECK-LABEL: name: xor_s16_gpr
+name:            xor_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = EORWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_XOR %0, %1
+...
+
+---
 # Same as add_s32_gpr, for G_XOR operations.
 # CHECK-LABEL: name: xor_s32_gpr
 name:            xor_s32_gpr
@@ -400,6 +638,62 @@ body:             |
 ...
 
 ---
+# CHECK-LABEL: name: and_s8_gpr
+name:            and_s8_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = ANDWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s8) = COPY %w0
+    %1(s8) = COPY %w1
+    %2(s8) = G_AND %0, %1
+...
+
+---
+# CHECK-LABEL: name: and_s16_gpr
+name:            and_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = ANDWrr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_AND %0, %1
+...
+
+---
 # Same as add_s32_gpr, for G_AND operations.
 # CHECK-LABEL: name: and_s32_gpr
 name:            and_s32_gpr
@@ -458,6 +752,62 @@ body:             |
 ...
 
 ---
+# CHECK-LABEL: name: shl_s8_gpr
+name:            shl_s8_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = LSLVWr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s8) = COPY %w0
+    %1(s8) = COPY %w1
+    %2(s8) = G_SHL %0, %1
+...
+
+---
+# CHECK-LABEL: name: shl_s16_gpr
+name:            shl_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = LSLVWr %0, %1
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_SHL %0, %1
+...
+
+---
 # Same as add_s32_gpr, for G_SHL operations.
 # CHECK-LABEL: name: shl_s32_gpr
 name:            shl_s32_gpr
@@ -631,6 +981,63 @@ body:             |
     %2(s64) = G_ASHR %0, %1
 ...
 
+---
+# CHECK-LABEL: name: mul_s8_gpr
+name:            mul_s8_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = MADDWrrr %0, %1, %wzr
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s8) = COPY %w0
+    %1(s8) = COPY %w1
+    %2(s8) = G_MUL %0, %1
+...
+
+---
+# CHECK-LABEL: name: mul_s16_gpr
+name:            mul_s16_gpr
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: gpr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = COPY %w1
+# CHECK:    %2 = MADDWrrr %0, %1, %wzr
+body:             |
+  bb.0:
+    liveins: %w0, %w1
+
+    %0(s16) = COPY %w0
+    %1(s16) = COPY %w1
+    %2(s16) = G_MUL %0, %1
+...
+
+---
 # Check that we select s32 GPR G_MUL. This is trickier than other binops because
 # there is only MADDWrrr, and we have to use the WZR physreg.
 # CHECK-LABEL: name: mul_s32_gpr




More information about the llvm-commits mailing list