[llvm] r349026 - [ARM GlobalISel] Support exts and truncs for Thumb2

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 13 04:06:54 PST 2018


Author: rovka
Date: Thu Dec 13 04:06:54 2018
New Revision: 349026

URL: http://llvm.org/viewvc/llvm-project?rev=349026&view=rev
Log:
[ARM GlobalISel] Support exts and truncs for Thumb2

Mark G_SEXT, G_ZEXT and G_ANYEXT to 32 bits as legal and add support for
them in the instruction selector. This uses handwritten code again
because the patterns that are generated with TableGen are tuned for what
the DAG combiner would produce and not for simple sext/zext nodes.
Luckily, we only need to update the opcodes to use the Thumb2 variants,
everything else can be reused from ARM.

Added:
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-exts.mir
    llvm/trunk/test/CodeGen/ARM/GlobalISel/thumb-select-exts.mir
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
    llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp?rev=349026&r1=349025&r2=349026&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp Thu Dec 13 04:06:54 2018
@@ -229,17 +229,19 @@ static bool selectUnmergeValues(MachineI
 /// instruction). Extension operations more complicated than that should not
 /// invoke this. Returns the original opcode if it doesn't know how to select a
 /// better one.
-static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
+static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size, bool isThumb) {
   using namespace TargetOpcode;
 
   if (Size != 8 && Size != 16)
     return Opc;
 
   if (Opc == G_SEXT)
-    return Size == 8 ? ARM::SXTB : ARM::SXTH;
+    return isThumb ? Size == 8 ? ARM::t2SXTB : ARM::t2SXTH
+                   : Size == 8 ? ARM::SXTB : ARM::SXTH;
 
   if (Opc == G_ZEXT)
-    return Size == 8 ? ARM::UXTB : ARM::UXTH;
+    return isThumb ? Size == 8 ? ARM::t2UXTB : ARM::t2UXTH
+                   : Size == 8 ? ARM::UXTB : ARM::UXTH;
 
   return Opc;
 }
@@ -715,7 +717,7 @@ bool ARMInstructionSelector::select(Mach
     switch (SrcSize) {
     case 1: {
       // ZExt boils down to & 0x1; for SExt we also subtract that from 0
-      I.setDesc(TII.get(ARM::ANDri));
+      I.setDesc(TII.get(STI.isThumb() ? ARM::t2ANDri : ARM::ANDri));
       MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
 
       if (isSExt) {
@@ -726,13 +728,13 @@ bool ARMInstructionSelector::select(Mach
         I.getOperand(0).setReg(AndResult);
 
         auto InsertBefore = std::next(I.getIterator());
-        auto SubI =
-            BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
-                .addDef(SExtResult)
-                .addUse(AndResult)
-                .addImm(0)
-                .add(predOps(ARMCC::AL))
-                .add(condCodeOp());
+        auto SubI = BuildMI(MBB, InsertBefore, I.getDebugLoc(),
+                            TII.get(STI.isThumb() ? ARM::t2RSBri : ARM::RSBri))
+                        .addDef(SExtResult)
+                        .addUse(AndResult)
+                        .addImm(0)
+                        .add(predOps(ARMCC::AL))
+                        .add(condCodeOp());
         if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
           return false;
       }
@@ -740,7 +742,8 @@ bool ARMInstructionSelector::select(Mach
     }
     case 8:
     case 16: {
-      unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
+      unsigned NewOpc =
+          selectSimpleExtOpc(I.getOpcode(), SrcSize, STI.isThumb());
       if (NewOpc == I.getOpcode())
         return false;
       I.setDesc(TII.get(NewOpc));

Modified: llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=349026&r1=349025&r2=349026&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp Thu Dec 13 04:06:54 2018
@@ -82,6 +82,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
     return;
   }
 
+  getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT})
+      .legalForCartesianProduct({s32}, {s1, s8, s16});
+
   // We're keeping these builders around because we'll want to add support for
   // floating point to them.
   auto &LoadStoreBuilder =
@@ -126,9 +129,6 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
       setAction({Op, s32}, Libcall);
   }
 
-  getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT})
-      .legalForCartesianProduct({s32}, {s1, s8, s16});
-
   getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s32}});
   getActionDefinitionsBuilder(G_PTRTOINT).legalFor({{s32, p0}});
 

Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-exts.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-exts.mir?rev=349026&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-exts.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-exts.mir Thu Dec 13 04:06:54 2018
@@ -0,0 +1,79 @@
+# RUN: llc -mtriple arm-- -run-pass=legalizer %s -o - | FileCheck %s
+# RUN: llc -mtriple thumb-- -mattr=+v6t2 -run-pass=legalizer %s -o - | FileCheck %s
+--- |
+  define void @test_zext_s16() { ret void }
+  define void @test_sext_s8() { ret void }
+  define void @test_anyext_s1() { ret void }
+...
+---
+name:            test_zext_s16
+# CHECK-LABEL: name: test_zext_s16
+legalized:       false
+# CHECK: legalized: true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    %1(s16) = G_LOAD %0 :: (load 2)
+    %2(s32) = G_ZEXT %1
+    ; G_ZEXT with s16 is legal, so we should find it unchanged in the output
+    ; CHECK: {{%[0-9]+}}:_(s32) = G_ZEXT {{%[0-9]+}}
+    $r0 = COPY %2(s32)
+    BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_sext_s8
+# CHECK-LABEL: name: test_sext_s8
+legalized:       false
+# CHECK: legalized: true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    %1(s8) = G_LOAD %0(p0) :: (load 1)
+    %2(s32) = G_SEXT %1
+    ; G_SEXT with s8 is legal, so we should find it unchanged in the output
+    ; CHECK: {{%[0-9]+}}:_(s32) = G_SEXT {{%[0-9]+}}
+    $r0 = COPY %2(s32)
+    BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_anyext_s1
+# CHECK-LABEL: name: test_anyext_s1
+legalized:       false
+# CHECK: legalized: true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(p0) = COPY $r0
+    %1(s1) = G_LOAD %0(p0) :: (load 1)
+    %2(s32) = G_ANYEXT %1
+    ; G_ANYEXT with s1 is legal, so we should find it unchanged in the output
+    ; CHECK: {{%[0-9]+}}:_(s32) = G_ANYEXT {{%[0-9]+}}
+    $r0 = COPY %2(s32)
+    BX_RET 14, $noreg, implicit $r0
+...

Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/thumb-select-exts.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/thumb-select-exts.mir?rev=349026&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/thumb-select-exts.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/thumb-select-exts.mir Thu Dec 13 04:06:54 2018
@@ -0,0 +1,288 @@
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+--- |
+  define void @test_trunc_and_zext_s1() { ret void }
+  define void @test_trunc_and_sext_s1() { ret void }
+  define void @test_trunc_and_anyext_s1() { ret void }
+
+  define void @test_trunc_and_zext_s8() { ret void }
+  define void @test_trunc_and_sext_s8() { ret void }
+  define void @test_trunc_and_anyext_s8() { ret void }
+
+  define void @test_trunc_and_zext_s16() { ret void }
+  define void @test_trunc_and_sext_s16() { ret void }
+  define void @test_trunc_and_anyext_s16() { ret void }
+...
+---
+name:            test_trunc_and_zext_s1
+# CHECK-LABEL: name: test_trunc_and_zext_s1
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s1) = G_TRUNC %0(s32)
+
+    %2(s32) = G_ZEXT %1(s1)
+    ; CHECK: [[RVREG:%[0-9]+]]:rgpr = COPY [[VREG]]
+    ; CHECK: [[VREGEXT:%[0-9]+]]:rgpr = t2ANDri [[RVREG]], 1, 14, $noreg, $noreg
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREGEXT]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_sext_s1
+# CHECK-LABEL: name: test_trunc_and_sext_s1
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s1) = G_TRUNC %0(s32)
+
+    %2(s32) = G_SEXT %1(s1)
+    ; CHECK: [[RVREG:%[0-9]+]]:rgpr = COPY [[VREG]]
+    ; CHECK: [[VREGAND:%[0-9]+]]:rgpr = t2ANDri [[RVREG]], 1, 14, $noreg, $noreg
+    ; CHECK: [[VREGEXT:%[0-9]+]]:rgpr = t2RSBri [[VREGAND]], 0, 14, $noreg, $noreg
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREGEXT]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_anyext_s1
+# CHECK-LABEL: name: test_trunc_and_anyext_s1
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s1) = G_TRUNC %0(s32)
+
+    %2(s32) = G_ANYEXT %1(s1)
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREG]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_zext_s8
+# CHECK-LABEL: name: test_trunc_and_zext_s8
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s8) = G_TRUNC %0(s32)
+    ; CHECK: [[VREGTRUNC:%[0-9]+]]:rgpr = COPY [[VREG]]
+
+    %2(s32) = G_ZEXT %1(s8)
+    ; CHECK: [[VREGEXT:%[0-9]+]]:rgpr = t2UXTB [[VREGTRUNC]], 0, 14, $noreg
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREGEXT]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_sext_s8
+# CHECK-LABEL: name: test_trunc_and_sext_s8
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s8) = G_TRUNC %0(s32)
+    ; CHECK: [[VREGTRUNC:%[0-9]+]]:rgpr = COPY [[VREG]]
+
+    %2(s32) = G_SEXT %1(s8)
+    ; CHECK: [[VREGEXT:%[0-9]+]]:rgpr = t2SXTB [[VREGTRUNC]], 0, 14, $noreg
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREGEXT]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_anyext_s8
+# CHECK-LABEL: name: test_trunc_and_anyext_s8
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s8) = G_TRUNC %0(s32)
+
+    %2(s32) = G_ANYEXT %1(s8)
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREG]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_zext_s16
+# CHECK-LABEL: name: test_trunc_and_zext_s16
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s16) = G_TRUNC %0(s32)
+    ; CHECK: [[VREGTRUNC:%[0-9]+]]:rgpr = COPY [[VREG]]
+
+    %2(s32) = G_ZEXT %1(s16)
+    ; CHECK: [[VREGEXT:%[0-9]+]]:rgpr = t2UXTH [[VREGTRUNC]], 0, 14, $noreg
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREGEXT]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_sext_s16
+# CHECK-LABEL: name: test_trunc_and_sext_s16
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s16) = G_TRUNC %0(s32)
+    ; CHECK: [[VREGTRUNC:%[0-9]+]]:rgpr = COPY [[VREG]]
+
+    %2(s32) = G_SEXT %1(s16)
+    ; CHECK: [[VREGEXT:%[0-9]+]]:rgpr = t2SXTH [[VREGTRUNC]], 0, 14, $noreg
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREGEXT]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name:            test_trunc_and_anyext_s16
+# CHECK-LABEL: name: test_trunc_and_anyext_s16
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+
+    %0(s32) = COPY $r0
+    ; CHECK: [[VREG:%[0-9]+]]:gpr = COPY $r0
+
+    %1(s16) = G_TRUNC %0(s32)
+
+    %2(s32) = G_ANYEXT %1(s16)
+
+    $r0 = COPY %2(s32)
+    ; CHECK: $r0 = COPY [[VREG]]
+
+    BX_RET 14, $noreg, implicit $r0
+    ; CHECK: BX_RET 14, $noreg, implicit $r0
+...




More information about the llvm-commits mailing list