[llvm] r301164 - [ARM] GlobalISel: Support G_(S|U)DIV for s32

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 24 01:20:05 PDT 2017


Author: rovka
Date: Mon Apr 24 03:20:05 2017
New Revision: 301164

URL: http://llvm.org/viewvc/llvm-project?rev=301164&view=rev
Log:
[ARM] GlobalISel: Support G_(S|U)DIV for s32

Add support for both targets with hardware division and without. For
hardware division we have to add support throughout the pipeline
(legalizer, reg bank select, instruction select). For targets without
hardware division, we only need to mark it as a libcall.

Added:
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
    llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir

Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp?rev=301164&r1=301163&r2=301164&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp Mon Apr 24 03:20:05 2017
@@ -332,6 +332,16 @@ bool ARMInstructionSelector::select(Mach
     }
     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
     break;
+  case G_SDIV:
+    assert(TII.getSubtarget().hasDivideInARMMode() && "Unsupported operation");
+    I.setDesc(TII.get(ARM::SDIV));
+    MIB.add(predOps(ARMCC::AL));
+    break;
+  case G_UDIV:
+    assert(TII.getSubtarget().hasDivideInARMMode() && "Unsupported operation");
+    I.setDesc(TII.get(ARM::UDIV));
+    MIB.add(predOps(ARMCC::AL));
+    break;
   case G_FADD:
     if (!selectFAdd(MIB, TII, MRI))
       return false;

Modified: llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=301164&r1=301163&r2=301164&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp Mon Apr 24 03:20:05 2017
@@ -47,6 +47,13 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
     for (auto Ty : {s1, s8, s16, s32})
       setAction({Op, Ty}, Legal);
 
+  for (unsigned Op : {G_SDIV, G_UDIV}) {
+    if (ST.hasDivideInARMMode())
+      setAction({Op, s32}, Legal);
+    else
+      setAction({Op, s32}, Libcall);
+  }
+
   for (unsigned Op : {G_SEXT, G_ZEXT}) {
     setAction({Op, s32}, Legal);
     for (auto Ty : {s1, s8, s16})

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp?rev=301164&r1=301163&r2=301164&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp Mon Apr 24 03:20:05 2017
@@ -221,6 +221,8 @@ ARMRegisterBankInfo::getInstrMapping(con
   case G_ADD:
   case G_SUB:
   case G_MUL:
+  case G_SDIV:
+  case G_UDIV:
   case G_SEXT:
   case G_ZEXT:
   case G_TRUNC:

Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir?rev=301164&r1=301163&r2=301164&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir Mon Apr 24 03:20:05 2017
@@ -23,6 +23,9 @@
   define void @test_mul_s32() #1 { ret void }
   define void @test_mulv5_s32() { ret void }
 
+  define void @test_sdiv_s32() #2 { ret void }
+  define void @test_udiv_s32() #2 { ret void }
+
   define void @test_load_from_stack() { ret void }
   define void @test_load_f32() #0 { ret void }
   define void @test_load_f64() #0 { ret void }
@@ -37,6 +40,7 @@
 
   attributes #0 = { "target-features"="+vfp2,-neonfp" }
   attributes #1 = { "target-features"="+v6" }
+  attributes #2 = { "target-features"="+hwdiv-arm" }
 ...
 ---
 name:            test_zext_s1
@@ -564,6 +568,72 @@ body:             |
 
     %r0 = COPY %2(s32)
     ; CHECK: %r0 = COPY [[VREGRES]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...
+---
+name:            test_sdiv_s32
+# CHECK-LABEL: name: test_sdiv_s32
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+# CHECK: id: 0, class: gpr
+# CHECK: id: 1, class: gpr
+# CHECK: id: 2, class: gpr
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s32) = COPY %r0
+    ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
+
+    %1(s32) = COPY %r1
+    ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
+
+    %2(s32) = G_SDIV %0, %1
+    ; CHECK: [[VREGRES:%[0-9]+]] = SDIV [[VREGX]], [[VREGY]], 14, _
+
+    %r0 = COPY %2(s32)
+    ; CHECK: %r0 = COPY [[VREGRES]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...
+---
+name:            test_udiv_s32
+# CHECK-LABEL: name: test_udiv_s32
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+# CHECK: id: 0, class: gpr
+# CHECK: id: 1, class: gpr
+# CHECK: id: 2, class: gpr
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s32) = COPY %r0
+    ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
+
+    %1(s32) = COPY %r1
+    ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
+
+    %2(s32) = G_UDIV %0, %1
+    ; CHECK: [[VREGRES:%[0-9]+]] = UDIV [[VREGX]], [[VREGY]], 14, _
+
+    %r0 = COPY %2(s32)
+    ; CHECK: %r0 = COPY [[VREGRES]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0

Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll?rev=301164&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll Mon Apr 24 03:20:05 2017
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple arm-gnueabi -mattr=+hwdiv-arm -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,HWDIV
+; RUN: llc -mtriple arm-gnueabi -mattr=-hwdiv-arm -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,SOFT-AEABI
+; RUN: llc -mtriple arm-gnu -mattr=+hwdiv-arm -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,HWDIV
+; RUN: llc -mtriple arm-gnu -mattr=-hwdiv-arm -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,SOFT-DEFAULT
+
+define arm_aapcscc i32 @test_sdiv_i32(i32 %a, i32 %b) {
+; CHECK-LABEL: test_sdiv_i32:
+; HWDIV: sdiv r0, r0, r1
+; SOFT-AEABI: blx __aeabi_idiv
+; SOFT-DEFAULT: blx __divsi3
+  %r = sdiv i32 %a, %b
+  ret i32 %r
+}
+
+define arm_aapcscc i32 @test_udiv_i32(i32 %a, i32 %b) {
+; CHECK-LABEL: test_udiv_i32:
+; HWDIV: udiv r0, r0, r1
+; SOFT-AEABI: blx __aeabi_uidiv
+; SOFT-DEFAULT: blx __udivsi3
+  %r = udiv i32 %a, %b
+  ret i32 %r
+}
+

Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir?rev=301164&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir Mon Apr 24 03:20:05 2017
@@ -0,0 +1,76 @@
+# RUN: llc -mtriple arm-linux-gnueabi -mattr=+hwdiv-arm -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefixes=CHECK,HWDIV
+# RUN: llc -mtriple arm-linux-gnueabi -mattr=-hwdiv-arm -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefixes=CHECK,SOFT,SOFT-AEABI
+# RUN: llc -mtriple arm-linux-gnu -mattr=+hwdiv-arm -global-isel -run-pass=legalizer %s -o - | FileCheck %s  -check-prefixes=CHECK,HWDIV
+# RUN: llc -mtriple arm-linux-gnu -mattr=-hwdiv-arm -global-isel -run-pass=legalizer %s -o - | FileCheck %s  -check-prefixes=CHECK,SOFT,SOFT-DEFAULT
+--- |
+  define void @test_sdiv_i32() { ret void }
+  define void @test_udiv_i32() { ret void }
+...
+---
+name:            test_sdiv_i32
+# CHECK-LABEL: name: test_sdiv_i32
+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, %r1
+
+    ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
+    ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    ; HWDIV: [[R:%[0-9]+]](s32) = G_SDIV [[X]], [[Y]]
+    ; SOFT: ADJCALLSTACKDOWN
+    ; SOFT-DAG: %r0 = COPY [[X]]
+    ; SOFT-DAG: %r1 = COPY [[Y]]
+    ; SOFT-AEABI: BLX $__aeabi_idiv, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+    ; SOFT-AEABI: [[R:%[0-9]+]](s32) = COPY %r0
+    ; SOFT-DEFAULT: BLX $__divsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+    ; SOFT-DEFAULT: [[R:%[0-9]+]](s32) = COPY %r0
+    ; SOFT: ADJCALLSTACKUP
+    %2(s32) = G_SDIV %0, %1
+    ; CHECK: %r0 = COPY [[R]]
+    %r0 = COPY %2(s32)
+    BX_RET 14, _, implicit %r0
+...
+---
+name:            test_udiv_i32
+# CHECK-LABEL: name: test_udiv_i32
+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, %r1
+
+    ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
+    ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    ; HWDIV: [[R:%[0-9]+]](s32) = G_UDIV [[X]], [[Y]]
+    ; SOFT: ADJCALLSTACKDOWN
+    ; SOFT-DAG: %r0 = COPY [[X]]
+    ; SOFT-DAG: %r1 = COPY [[Y]]
+    ; SOFT-AEABI: BLX $__aeabi_uidiv, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+    ; SOFT-AEABI: [[R:%[0-9]+]](s32) = COPY %r0
+    ; SOFT-DEFAULT: BLX $__udivsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+    ; SOFT-DEFAULT: [[R:%[0-9]+]](s32) = COPY %r0
+    ; SOFT: ADJCALLSTACKUP
+    %2(s32) = G_UDIV %0, %1
+    ; CHECK: %r0 = COPY [[R]]
+    %r0 = COPY %2(s32)
+    BX_RET 14, _, implicit %r0
+...

Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir?rev=301164&r1=301163&r2=301164&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir Mon Apr 24 03:20:05 2017
@@ -13,6 +13,9 @@
   define void @test_mul_s16() { ret void }
   define void @test_mul_s8() { ret void }
 
+  define void @test_sdiv_s32() #1 { ret void }
+  define void @test_udiv_s32() #1 { ret void }
+
   define void @test_loads() #0 { ret void }
   define void @test_stores() #0 { ret void }
 
@@ -30,6 +33,7 @@
   define void @test_soft_fp_s64() #0 { ret void }
 
   attributes #0 = { "target-features"="+vfp2"}
+  attributes #1 = { "target-features"="+hwdiv-arm" }
 ...
 ---
 name:            test_add_s32
@@ -291,6 +295,58 @@ body:             |
     BX_RET 14, _, implicit %r0
 
 ...
+---
+name:            test_sdiv_s32
+# CHECK-LABEL: name: test_sdiv_s32
+legalized:       true
+regBankSelected: false
+selected:        false
+# CHECK: registers:
+# CHECK: - { id: 0, class: gprb }
+# CHECK: - { id: 1, class: gprb }
+# CHECK: - { id: 2, class: gprb }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    %2(s32) = G_SDIV %0, %1
+    %r0 = COPY %2(s32)
+    BX_RET 14, _, implicit %r0
+
+...
+---
+name:            test_udiv_s32
+# CHECK-LABEL: name: test_udiv_s32
+legalized:       true
+regBankSelected: false
+selected:        false
+# CHECK: registers:
+# CHECK: - { id: 0, class: gprb }
+# CHECK: - { id: 1, class: gprb }
+# CHECK: - { id: 2, class: gprb }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    %2(s32) = G_UDIV %0, %1
+    %r0 = COPY %2(s32)
+    BX_RET 14, _, implicit %r0
+
+...
 ---
 name:            test_loads
 # CHECK-LABEL: name: test_loads




More information about the llvm-commits mailing list